diff --git a/grouperBot/.env.example b/grouperBot/.env.example deleted file mode 100644 index 708a07f..0000000 --- a/grouperBot/.env.example +++ /dev/null @@ -1 +0,0 @@ -ETH_MAINNET_RPC= \ No newline at end of file diff --git a/grouperBot/.github/workflows/test.yml b/grouperBot/.github/workflows/test.yml deleted file mode 100644 index 57bdb22..0000000 --- a/grouperBot/.github/workflows/test.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: CI - -on: - push: - pull_request: - workflow_dispatch: - -env: - FOUNDRY_PROFILE: ci - -jobs: - check: - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Show Forge version - run: forge --version - - - name: Run Forge fmt - run: forge fmt --check - - - name: Run Forge build - run: forge build --sizes - - - name: Run Forge tests - run: forge test -vvv diff --git a/grouperBot/.gitignore b/grouperBot/.gitignore deleted file mode 100644 index a3c19dd..0000000 --- a/grouperBot/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# Compiler files -cache/ -out/ - -# Ignores development broadcast logs -/broadcast - -# Docs -docs/ - -# Dotenv file -.env diff --git a/grouperBot/.gitmodules b/grouperBot/.gitmodules deleted file mode 100644 index 0f07815..0000000 --- a/grouperBot/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "lib/solady"] - path = lib/solady - url = https://github.com/vectorized/solady diff --git a/grouperBot/Makefile b/grouperBot/Makefile deleted file mode 100644 index 014278e..0000000 --- a/grouperBot/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# Usage: -# 1. Launch a node: `anvil --fork-url https://ethereum-rpc.publicnode.com` or `anvil --fork-url https://eth.llamarpc.com` -# 2. Execute the following commands - -# useful Info -usdc_addr = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 -WHALE_ADDR = 0x37305B1cD40574E4C5Ce33f8e8306Be057fD7341 -ANVIL_ACCOUNT0_ADDR = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -ANVIL_ACCOUNT0_PRIVATE_KEY = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -ANVIL_RPC_URL = http://127.0.0.1:8545 -usdc_10000_amount = 10000000000 - -# 0. Launch a node: `anvil --fork-url https://ethereum-rpc.publicnode.com` or `anvil --fork-url https://eth.llamarpc.com` - -# 1. create a new uniswap-v2 pool in ethereum: [mockERC20, usdc] -deploy_mockERC20_usdc_pool: - forge script script/deploy_pool.s.sol:DeployPool --rpc-url ${ANVIL_RPC_URL} --broadcast - -# 2. replace the mock erc20 and pool address in constant.s.sol - -# 3. get some usdc -get_usdc: - cast rpc anvil_impersonateAccount ${WHALE_ADDR} --rpc-url ${ANVIL_RPC_URL} - cast send ${usdc_addr} "transfer(address,uint256)" ${ANVIL_ACCOUNT0_ADDR} ${usdc_10000_amount} --from ${WHALE_ADDR} --rpc-url ${ANVIL_RPC_URL} --unlocked - cast call ${usdc_addr} "balanceOf(address)(uint256)" ${ANVIL_ACCOUNT0_ADDR} --private-key ${ANVIL_ACCOUNT0_PRIVATE_KEY} --rpc-url ${ANVIL_RPC_URL} - -# 4. add liquidity to the pool: [mockERC20, usdc] -# before that, plz update the mock_erc20_addr in constant.s.sol -add_liquidity: - forge script script/add_liquidity.s.sol:AddLiquidity --rpc-url ${ANVIL_RPC_URL} --broadcast - -# 5. deploy the bot contract -deploy_bot: - forge script script/deploy_bot.s.sol:DeployGrouperBot --rpc-url ${ANVIL_RPC_URL} --broadcast - -# 6. replace the bot address in constant.s.sol - -# 7. swap usdc to mock erc20 -swap_usdc_to_mockERC20: - forge script script/swap.s.sol:Swap --rpc-url ${ANVIL_RPC_URL} --broadcast \ No newline at end of file diff --git a/grouperBot/README.md b/grouperBot/README.md deleted file mode 100644 index 8817d6a..0000000 --- a/grouperBot/README.md +++ /dev/null @@ -1,66 +0,0 @@ -## Foundry - -**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** - -Foundry consists of: - -- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). -- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. -- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. -- **Chisel**: Fast, utilitarian, and verbose solidity REPL. - -## Documentation - -https://book.getfoundry.sh/ - -## Usage - -### Build - -```shell -$ forge build -``` - -### Test - -```shell -$ forge test -``` - -### Format - -```shell -$ forge fmt -``` - -### Gas Snapshots - -```shell -$ forge snapshot -``` - -### Anvil - -```shell -$ anvil -``` - -### Deploy - -```shell -$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key -``` - -### Cast - -```shell -$ cast -``` - -### Help - -```shell -$ forge --help -$ anvil --help -$ cast --help -``` diff --git a/grouperBot/foundry.lock b/grouperBot/foundry.lock deleted file mode 100644 index afa6112..0000000 --- a/grouperBot/foundry.lock +++ /dev/null @@ -1,14 +0,0 @@ -{ - "lib/forge-std": { - "tag": { - "name": "v1.11.0", - "rev": "8e40513d678f392f398620b3ef2b418648b33e89" - } - }, - "lib/solady": { - "tag": { - "name": "v0.1.26", - "rev": "acd959aa4bd04720d640bf4e6a5c71037510cc4b" - } - } -} \ No newline at end of file diff --git a/grouperBot/foundry.toml b/grouperBot/foundry.toml deleted file mode 100644 index 25b918f..0000000 --- a/grouperBot/foundry.toml +++ /dev/null @@ -1,6 +0,0 @@ -[profile.default] -src = "src" -out = "out" -libs = ["lib"] - -# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/grouperBot/lib/forge-std/.gitattributes b/grouperBot/lib/forge-std/.gitattributes deleted file mode 100644 index 27042d4..0000000 --- a/grouperBot/lib/forge-std/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -src/Vm.sol linguist-generated diff --git a/grouperBot/lib/forge-std/.github/CODEOWNERS b/grouperBot/lib/forge-std/.github/CODEOWNERS deleted file mode 100644 index beae7aa..0000000 --- a/grouperBot/lib/forge-std/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @danipopes @klkvr @mattsse @grandizzy @yash-atreya @zerosnacks @onbjerg @0xrusowsky \ No newline at end of file diff --git a/grouperBot/lib/forge-std/.github/dependabot.yml b/grouperBot/lib/forge-std/.github/dependabot.yml deleted file mode 100644 index 5ace460..0000000 --- a/grouperBot/lib/forge-std/.github/dependabot.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" diff --git a/grouperBot/lib/forge-std/.github/workflows/ci.yml b/grouperBot/lib/forge-std/.github/workflows/ci.yml deleted file mode 100644 index cede018..0000000 --- a/grouperBot/lib/forge-std/.github/workflows/ci.yml +++ /dev/null @@ -1,142 +0,0 @@ -name: CI - -permissions: {} - -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - -jobs: - build: - name: build +${{ matrix.toolchain }} ${{ matrix.flags }} - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read - strategy: - fail-fast: false - matrix: - toolchain: [stable, nightly] - flags: - - "" - - --via-ir - - --use solc:0.8.17 --via-ir - - --use solc:0.8.17 - - --use solc:0.8.0 - - --use solc:0.7.6 - - --use solc:0.7.0 - - --use solc:0.6.2 - - --use solc:0.6.12 - steps: - - uses: actions/checkout@v5 - with: - persist-credentials: false - - uses: foundry-rs/foundry-toolchain@v1 - - run: forge --version - - run: | - case "${{ matrix.flags }}" in - *"solc:0.8.0"* | *"solc:0.7"* | *"solc:0.6"*) - forge build --skip test --skip Config --skip StdConfig --skip LibVariable --deny-warnings ${{ matrix.flags }} - ;; - *) - forge build --skip test --deny-warnings ${{ matrix.flags }} - ;; - esac - # via-ir compilation time checks. - - if: contains(matrix.flags, '--via-ir') - run: forge build --skip test --deny-warnings ${{ matrix.flags }} --contracts 'test/compilation/*' - - test: - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read - strategy: - fail-fast: false - matrix: - toolchain: [stable, nightly] - steps: - - uses: actions/checkout@v5 - with: - persist-credentials: false - - uses: foundry-rs/foundry-toolchain@v1 - with: - version: ${{ matrix.toolchain }} - - run: forge --version - - run: | - if [ "${{ matrix.toolchain }}" = "stable" ]; then - forge test -vvv --no-match-path "test/Config.t.sol" - else - forge test -vvv - fi - - fmt: - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read - steps: - - uses: actions/checkout@v5 - with: - persist-credentials: false - - uses: foundry-rs/foundry-toolchain@v1 - - run: forge --version - - run: forge fmt --check - - typos: - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read - steps: - - uses: actions/checkout@v5 - with: - persist-credentials: false - - uses: crate-ci/typos@7436548694def3314aacd93ed06c721b1f91ea04 # v1 - - codeql: - name: Analyze (${{ matrix.language }}) - runs-on: ubuntu-latest - permissions: - security-events: write - actions: read - contents: read - strategy: - fail-fast: false - matrix: - include: - - language: actions - build-mode: none - steps: - - name: Checkout repository - uses: actions/checkout@v5 - with: - persist-credentials: false - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" - - ci-success: - runs-on: ubuntu-latest - if: always() - needs: - - build - - test - - fmt - - typos - - codeql - timeout-minutes: 10 - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/grouperBot/lib/forge-std/.github/workflows/sync.yml b/grouperBot/lib/forge-std/.github/workflows/sync.yml deleted file mode 100644 index 15731cb..0000000 --- a/grouperBot/lib/forge-std/.github/workflows/sync.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Sync Release Branch - -permissions: {} - -on: - release: - types: - - created - -jobs: - sync-release-branch: - runs-on: ubuntu-latest - permissions: - contents: write - if: startsWith(github.event.release.tag_name, 'v1') - steps: - - name: Check out the repo - uses: actions/checkout@v5 - with: - persist-credentials: true - fetch-depth: 0 - ref: v1 - - # The email is derived from the bots user id, - # found here: https://api.github.com/users/github-actions%5Bbot%5D - - name: Configure Git - run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - - - name: Sync Release Branch - run: | - git fetch --tags - git checkout v1 - git reset --hard ${GITHUB_REF} - git push --force diff --git a/grouperBot/lib/forge-std/.gitignore b/grouperBot/lib/forge-std/.gitignore deleted file mode 100644 index 756106d..0000000 --- a/grouperBot/lib/forge-std/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -cache/ -out/ -.vscode -.idea diff --git a/grouperBot/lib/forge-std/CONTRIBUTING.md b/grouperBot/lib/forge-std/CONTRIBUTING.md deleted file mode 100644 index 89b75f3..0000000 --- a/grouperBot/lib/forge-std/CONTRIBUTING.md +++ /dev/null @@ -1,193 +0,0 @@ -## Contributing to Foundry - -Thanks for your interest in improving Foundry! - -There are multiple opportunities to contribute at any level. It doesn't matter if you are just getting started with Rust or are the most weathered expert, we can use your help. - -This document will help you get started. **Do not let the document intimidate you**. -It should be considered as a guide to help you navigate the process. - -The [dev Telegram][dev-tg] is available for any concerns you may have that are not covered in this guide. - -### Code of Conduct - -The Foundry project adheres to the [Rust Code of Conduct][rust-coc]. This code of conduct describes the _minimum_ behavior expected from all contributors. - -Instances of violations of the Code of Conduct can be reported by contacting the team at [me@gakonst.com](mailto:me@gakonst.com). - -### Ways to contribute - -There are fundamentally four ways an individual can contribute: - -1. **By opening an issue:** For example, if you believe that you have uncovered a bug - in Foundry, creating a new issue in the issue tracker is the way to report it. -2. **By adding context:** Providing additional context to existing issues, - such as screenshots and code snippets, which help resolve issues. -3. **By resolving issues:** Typically this is done in the form of either - demonstrating that the issue reported is not a problem after all, or more often, - by opening a pull request that fixes the underlying problem, in a concrete and - reviewable manner. - -**Anybody can participate in any stage of contribution**. We urge you to participate in the discussion -around bugs and participate in reviewing PRs. - -### Contributions Related to Spelling and Grammar - -At this time, we will not be accepting contributions that only fix spelling or grammatical errors in documentation, code or -elsewhere. - -### Asking for help - -If you have reviewed existing documentation and still have questions, or you are having problems, you can get help in the following ways: - -- **Asking in the support Telegram:** The [Foundry Support Telegram][support-tg] is a fast and easy way to ask questions. -- **Opening a discussion:** This repository comes with a discussions board where you can also ask for help. Click the "Discussions" tab at the top. - -As Foundry is still in heavy development, the documentation can be a bit scattered. -The [Foundry Book][foundry-book] is our current best-effort attempt at keeping up-to-date information. - -### Submitting a bug report - -When filing a new bug report in the issue tracker, you will be presented with a basic form to fill out. - -If you believe that you have uncovered a bug, please fill out the form to the best of your ability. Do not worry if you cannot answer every detail; just fill in what you can. Contributors will ask follow-up questions if something is unclear. - -The most important pieces of information we need in a bug report are: - -- The Foundry version you are on (and that it is up to date) -- The platform you are on (Windows, macOS, an M1 Mac or Linux) -- Code snippets if this is happening in relation to testing or building code -- Concrete steps to reproduce the bug - -In order to rule out the possibility of the bug being in your project, the code snippets should be as minimal -as possible. It is better if you can reproduce the bug with a small snippet as opposed to an entire project! - -See [this guide][mcve] on how to create a minimal, complete, and verifiable example. - -### Submitting a feature request - -When adding a feature request in the issue tracker, you will be presented with a basic form to fill out. - -Please include as detailed of an explanation as possible of the feature you would like, adding additional context if necessary. - -If you have examples of other tools that have the feature you are requesting, please include them as well. - -### Resolving an issue - -Pull requests are the way concrete changes are made to the code, documentation, and dependencies of Foundry. - -Even minor pull requests, such as those fixing wording, are greatly appreciated. Before making a large change, it is usually -a good idea to first open an issue describing the change to solicit feedback and guidance. This will increase -the likelihood of the PR getting merged. - -Please make sure that the following commands pass if you have changed the code: - -```sh -forge fmt --check -forge test -vvv -``` - -To make sure your changes are compatible with all compiler version targets, run the following commands: - -```sh -forge build --skip test --use solc:0.6.2 -forge build --skip test --use solc:0.6.12 -forge build --skip test --use solc:0.7.0 -forge build --skip test --use solc:0.7.6 -forge build --skip test --use solc:0.8.0 -``` - -The CI will also ensure that the code is formatted correctly and that the tests are passing across all compiler version targets. - -#### Adding cheatcodes - -Please follow the guide outlined in the [cheatcodes](https://github.com/foundry-rs/foundry/blob/master/docs/dev/cheatcodes.md#adding-a-new-cheatcode) documentation of Foundry. - -When making modifications to the native cheatcodes or adding new ones, please make sure to run [`./scripts/vm.py`](./scripts/vm.py) to update the cheatcodes in the [`src/Vm.sol`](./src/Vm.sol) file. - -By default the script will automatically generate the cheatcodes from the [`cheatcodes.json`](https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json) file but alternatively you can provide a path to a JSON file containing the Vm interface, as generated by Foundry, with the `--from` flag. - -```sh -./scripts/vm.py --from path/to/cheatcodes.json -``` - -It is possible that the resulting [`src/Vm.sol`](./src/Vm.sol) file will have some changes that are not directly related to your changes, this is not a problem. - -#### Commits - -It is a recommended best practice to keep your changes as logically grouped as possible within individual commits. There is no limit to the number of commits any single pull request may have, and many contributors find it easier to review changes that are split across multiple commits. - -That said, if you have a number of commits that are "checkpoints" and don't represent a single logical change, please squash those together. - -#### Opening the pull request - -From within GitHub, opening a new pull request will present you with a template that should be filled out. Please try your best at filling out the details, but feel free to skip parts if you're not sure what to put. - -#### Discuss and update - -You will probably get feedback or requests for changes to your pull request. -This is a big part of the submission process, so don't be discouraged! Some contributors may sign off on the pull request right away, others may have more detailed comments or feedback. -This is a necessary part of the process in order to evaluate whether the changes are correct and necessary. - -**Any community member can review a PR, so you might get conflicting feedback**. -Keep an eye out for comments from code owners to provide guidance on conflicting feedback. - -#### Reviewing pull requests - -**Any Foundry community member is welcome to review any pull request**. - -All contributors who choose to review and provide feedback on pull requests have a responsibility to both the project and individual making the contribution. Reviews and feedback must be helpful, insightful, and geared towards improving the contribution as opposed to simply blocking it. If there are reasons why you feel the PR should not be merged, explain what those are. Do not expect to be able to block a PR from advancing simply because you say "no" without giving an explanation. Be open to having your mind changed. Be open to working _with_ the contributor to make the pull request better. - -Reviews that are dismissive or disrespectful of the contributor or any other reviewers are strictly counter to the Code of Conduct. - -When reviewing a pull request, the primary goals are for the codebase to improve and for the person submitting the request to succeed. **Even if a pull request is not merged, the submitter should come away from the experience feeling like their effort was not unappreciated**. Every PR from a new contributor is an opportunity to grow the community. - -##### Review a bit at a time - -Do not overwhelm new contributors. - -It is tempting to micro-optimize and make everything about relative performance, perfect grammar, or exact style matches. Do not succumb to that temptation.. - -Focus first on the most significant aspects of the change: - -1. Does this change make sense for Foundry? -2. Does this change make Foundry better, even if only incrementally? -3. Are there clear bugs or larger scale issues that need attending? -4. Are the commit messages readable and correct? If it contains a breaking change, is it clear enough? - -Note that only **incremental** improvement is needed to land a PR. This means that the PR does not need to be perfect, only better than the status quo. Follow-up PRs may be opened to continue iterating. - -When changes are necessary, _request_ them, do not _demand_ them, and **do not assume that the submitter already knows how to add a test or run a benchmark**. - -Specific performance optimization techniques, coding styles and conventions change over time. The first impression you give to a new contributor never does. - -Nits (requests for small changes that are not essential) are fine, but try to avoid stalling the pull request. Most nits can typically be fixed by the Foundry maintainers merging the pull request, but they can also be an opportunity for the contributor to learn a bit more about the project. - -It is always good to clearly indicate nits when you comment, e.g.: `Nit: change foo() to bar(). But this is not blocking`. - -If your comments were addressed but were not folded after new commits, or if they proved to be mistaken, please, [hide them][hiding-a-comment] with the appropriate reason to keep the conversation flow concise and relevant. - -##### Be aware of the person behind the code - -Be aware that _how_ you communicate requests and reviews in your feedback can have a significant impact on the success of the pull request. Yes, we may merge a particular change that makes Foundry better, but the individual might just not want to have anything to do with Foundry ever again. The goal is not just having good code. - -##### Abandoned or stale pull requests - -If a pull request appears to be abandoned or stalled, it is polite to first check with the contributor to see if they intend to continue the work before checking if they would mind if you took it over (especially if it just has nits left). When doing so, it is courteous to give the original contributor credit for the work they started, either by preserving their name and e-mail address in the commit log, or by using the `Author: ` or `Co-authored-by: ` metadata tag in the commits. - -_Adapted from the [ethers-rs contributing guide](https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md)_. - -### Releasing - -Releases are automatically done by the release workflow when a tag is pushed, however, these steps still need to be taken: - -1. Ensure that the versions in the relevant `Cargo.toml` files are up-to-date. -2. Update documentation links -3. Perform a final audit for breaking changes. - -[rust-coc]: https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md -[dev-tg]: https://t.me/foundry_rs -[foundry-book]: https://github.com/foundry-rs/foundry-book -[support-tg]: https://t.me/foundry_support -[mcve]: https://stackoverflow.com/help/mcve -[hiding-a-comment]: https://help.github.com/articles/managing-disruptive-comments/#hiding-a-comment \ No newline at end of file diff --git a/grouperBot/lib/forge-std/LICENSE-APACHE b/grouperBot/lib/forge-std/LICENSE-APACHE deleted file mode 100644 index cf01a49..0000000 --- a/grouperBot/lib/forge-std/LICENSE-APACHE +++ /dev/null @@ -1,203 +0,0 @@ -Copyright Contributors to Forge Standard Library - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/grouperBot/lib/forge-std/LICENSE-MIT b/grouperBot/lib/forge-std/LICENSE-MIT deleted file mode 100644 index 28f9830..0000000 --- a/grouperBot/lib/forge-std/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright Contributors to Forge Standard Library - -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 O THE USE OR OTHER -DEALINGS IN THE SOFTWARE.R diff --git a/grouperBot/lib/forge-std/README.md b/grouperBot/lib/forge-std/README.md deleted file mode 100644 index 51673e5..0000000 --- a/grouperBot/lib/forge-std/README.md +++ /dev/null @@ -1,266 +0,0 @@ -# Forge Standard Library • [![CI status](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml/badge.svg)](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml) - -Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. - -**Learn how to use Forge-Std with the [📖 Foundry Book (Forge-Std Guide)](https://getfoundry.sh/reference/forge-std/overview/).** - -## Install - -```bash -forge install foundry-rs/forge-std -``` - -## Contracts -### stdError - -This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler built-in errors. - -See the contract itself for all error codes. - -#### Example usage - -```solidity - -import "forge-std/Test.sol"; - -contract TestContract is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } -} - -contract ErrorsTest { - function arithmeticError(uint256 a) public { - a = a - 100; - } -} -``` - -### stdStorage - -This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). - -This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. - -I.e.: -```solidity -struct T { - // depth 0 - uint256 a; - // depth 1 - uint256 b; -} -``` - -#### Example usage - -```solidity -import "forge-std/Test.sol"; - -contract TestContract is Test { - using stdStorage for StdStorage; - - Storage test; - - function setUp() public { - test = new Storage(); - } - - function testFindExists() public { - // Lets say we want to find the slot for the public - // variable `exists`. We just pass in the function selector - // to the `find` command - uint256 slot = stdstore.target(address(test)).sig("exists()").find(); - assertEq(slot, 0); - } - - function testWriteExists() public { - // Lets say we want to write to the slot for the public - // variable `exists`. We just pass in the function selector - // to the `checked_write` command - stdstore.target(address(test)).sig("exists()").checked_write(100); - assertEq(test.exists(), 100); - } - - // It supports arbitrary storage layouts, like assembly based storage locations - function testFindHidden() public { - // `hidden` is a random hash of a bytes, iteration through slots would - // not find it. Our mechanism does - // Also, you can use the selector instead of a string - uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); - assertEq(slot, uint256(keccak256("my.random.var"))); - } - - // If targeting a mapping, you have to pass in the keys necessary to perform the find - // i.e.: - function testFindMapping() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.map_addr.selector) - .with_key(address(this)) - .find(); - // in the `Storage` constructor, we wrote that this address' value was 1 in the map - // so when we load the slot, we expect it to be 1 - assertEq(uint(vm.load(address(test), bytes32(slot))), 1); - } - - // If the target is a struct, you can specify the field depth: - function testFindStruct() public { - // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. - uint256 slot_for_a_field = stdstore - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(0) - .find(); - - uint256 slot_for_b_field = stdstore - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(1) - .find(); - - assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); - assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); - } -} - -// A complex storage contract -contract Storage { - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - constructor() { - map_addr[msg.sender] = 1; - } - - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - // mapping(address => Packed) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basicStruct = UnpackedStruct({ - a: 1, - b: 2 - }); - - function hidden() public view returns (bytes32 t) { - // an extremely hidden storage slot - bytes32 slot = keccak256("my.random.var"); - assembly { - t := sload(slot) - } - } -} -``` - -### stdCheats - -This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for addresses that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. - - -#### Example usage: -```solidity - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; - -// Inherit the stdCheats -contract StdCheatsTest is Test { - Bar test; - function setUp() public { - test = new Bar(); - } - - function testHoax() public { - // we call `hoax`, which gives the target address - // eth and then calls `prank` - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - - // overloaded to allow you to specify how much eth to - // initialize the address with - hoax(address(1337), 1); - test.bar{value: 1}(address(1337)); - } - - function testStartHoax() public { - // we call `startHoax`, which gives the target address - // eth and then calls `startPrank` - // - // it is also overloaded so that you can specify an eth amount - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } -} - -contract Bar { - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } -} -``` - -### Std Assertions - -Contains various assertions. - -### `console.log` - -Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). -It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console2.sol"; -... -console2.log(someValue); -``` - -If you need compatibility with Hardhat, you must use the standard `console.sol` instead. -Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console.sol"; -... -console.log(someValue); -``` - -## Contributing - -See our [contributing guidelines](./CONTRIBUTING.md). - -## Getting Help - -First, see if the answer to your question can be found in [book](https://book.getfoundry.sh). - -If the answer is not there: - -- Join the [support Telegram](https://t.me/foundry_support) to get help, or -- Open a [discussion](https://github.com/foundry-rs/foundry/discussions/new/choose) with your question, or -- Open an issue with [the bug](https://github.com/foundry-rs/foundry/issues/new/choose) - -If you want to contribute, or follow along with contributor discussion, you can use our [main telegram](https://t.me/foundry_rs) to chat with us about the development of Foundry! - -## License - -Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/grouperBot/lib/forge-std/RELEASE_CHECKLIST.md b/grouperBot/lib/forge-std/RELEASE_CHECKLIST.md deleted file mode 100644 index 4611de4..0000000 --- a/grouperBot/lib/forge-std/RELEASE_CHECKLIST.md +++ /dev/null @@ -1,12 +0,0 @@ -# Release checklist - -This checklist is meant to be used as a guide for the `forge-std` release process. - -## Steps - -- [ ] Update the version number in `package.json` -- [ ] Open and merge a PR with the version bump -- [ ] Tag the merged commit with the version number: `git tag v` -- [ ] Push the tag to the repository: `git push --tags` -- [ ] Create a new GitHub release with the automatically generated changelog and with the name set to `v` -- [ ] Add `## Featured Changes` section to the top of the release notes diff --git a/grouperBot/lib/forge-std/foundry.toml b/grouperBot/lib/forge-std/foundry.toml deleted file mode 100644 index b68bd54..0000000 --- a/grouperBot/lib/forge-std/foundry.toml +++ /dev/null @@ -1,27 +0,0 @@ -[profile.default] -fs_permissions = [{ access = "read-write", path = "./" }] -optimizer = true -optimizer_runs = 200 - -# A list of solidity error codes to ignore. -# 3860 = init-code-size -ignored_error_codes = [3860] - -[rpc_endpoints] -# The RPC URLs are modified versions of the default for testing initialization. -mainnet = "https://eth.merkle.io" # Different API key. -optimism_sepolia = "https://sepolia.optimism.io/" # Adds a trailing slash. -arbitrum_one_sepolia = "https://sepolia-rollup.arbitrum.io/rpc/" # Adds a trailing slash. -needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" - -[fmt] -# These are all the `forge fmt` defaults. -line_length = 120 -tab_width = 4 -bracket_spacing = false -int_types = 'long' -multiline_func_header = 'attributes_first' -quote_style = 'double' -number_underscore = 'preserve' -single_line_statement_blocks = 'preserve' -ignore = ["src/console.sol", "src/console2.sol"] diff --git a/grouperBot/lib/forge-std/package.json b/grouperBot/lib/forge-std/package.json deleted file mode 100644 index 09f5717..0000000 --- a/grouperBot/lib/forge-std/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge-std", - "version": "1.11.0", - "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", - "homepage": "https://book.getfoundry.sh/forge/forge-std", - "bugs": "https://github.com/foundry-rs/forge-std/issues", - "license": "(Apache-2.0 OR MIT)", - "author": "Contributors to Forge Standard Library", - "files": [ - "src/**/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/foundry-rs/forge-std.git" - } -} diff --git a/grouperBot/lib/forge-std/scripts/vm.py b/grouperBot/lib/forge-std/scripts/vm.py deleted file mode 100755 index 3cd047d..0000000 --- a/grouperBot/lib/forge-std/scripts/vm.py +++ /dev/null @@ -1,646 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import copy -import json -import re -import subprocess -from enum import Enum as PyEnum -from pathlib import Path -from typing import Callable -from urllib import request - -VoidFn = Callable[[], None] - -CHEATCODES_JSON_URL = "https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json" -OUT_PATH = "src/Vm.sol" - -VM_SAFE_DOC = """\ -/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may -/// result in Script simulations differing from on-chain execution. It is recommended to only use -/// these cheats in scripts. -""" - -VM_DOC = """\ -/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used -/// in tests, but it is not recommended to use these cheats in scripts. -""" - - -def main(): - parser = argparse.ArgumentParser( - description="Generate Vm.sol based on the cheatcodes json created by Foundry") - parser.add_argument( - "--from", - metavar="PATH", - dest="path", - required=False, - help="path to a json file containing the Vm interface, as generated by Foundry") - args = parser.parse_args() - json_str = request.urlopen(CHEATCODES_JSON_URL).read().decode("utf-8") if args.path is None else Path(args.path).read_text() - contract = Cheatcodes.from_json(json_str) - - ccs = contract.cheatcodes - ccs = list(filter(lambda cc: cc.status not in ["experimental", "internal"], ccs)) - ccs.sort(key=lambda cc: cc.func.id) - - safe = list(filter(lambda cc: cc.safety == "safe", ccs)) - safe.sort(key=CmpCheatcode) - unsafe = list(filter(lambda cc: cc.safety == "unsafe", ccs)) - unsafe.sort(key=CmpCheatcode) - assert len(safe) + len(unsafe) == len(ccs) - - prefix_with_group_headers(safe) - prefix_with_group_headers(unsafe) - - out = "" - - out += "// Automatically @generated by scripts/vm.py. Do not modify manually.\n\n" - - pp = CheatcodesPrinter( - spdx_identifier="MIT OR Apache-2.0", - solidity_requirement=">=0.6.2 <0.9.0", - abicoder_pragma=True, - ) - pp.p_prelude() - pp.prelude = False - out += pp.finish() - - out += "\n\n" - out += VM_SAFE_DOC - vm_safe = Cheatcodes( - # TODO: Custom errors were introduced in 0.8.4 - errors=[], # contract.errors - events=contract.events, - enums=contract.enums, - structs=contract.structs, - cheatcodes=safe, - ) - pp.p_contract(vm_safe, "VmSafe") - out += pp.finish() - - out += "\n\n" - out += VM_DOC - vm_unsafe = Cheatcodes( - errors=[], - events=[], - enums=[], - structs=[], - cheatcodes=unsafe, - ) - pp.p_contract(vm_unsafe, "Vm", "VmSafe") - out += pp.finish() - - # Compatibility with <0.8.0 - def memory_to_calldata(m: re.Match) -> str: - return " calldata " + m.group(1) - - out = re.sub(r" memory (.*returns)", memory_to_calldata, out) - - with open(OUT_PATH, "w") as f: - f.write(out) - - forge_fmt = ["forge", "fmt", OUT_PATH] - res = subprocess.run(forge_fmt) - assert res.returncode == 0, f"command failed: {forge_fmt}" - - print(f"Wrote to {OUT_PATH}") - - -class CmpCheatcode: - cheatcode: "Cheatcode" - - def __init__(self, cheatcode: "Cheatcode"): - self.cheatcode = cheatcode - - def __lt__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) < 0 - - def __eq__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) == 0 - - def __gt__(self, other: "CmpCheatcode") -> bool: - return cmp_cheatcode(self.cheatcode, other.cheatcode) > 0 - - -def cmp_cheatcode(a: "Cheatcode", b: "Cheatcode") -> int: - if a.group != b.group: - return -1 if a.group < b.group else 1 - if a.status != b.status: - return -1 if a.status < b.status else 1 - if a.safety != b.safety: - return -1 if a.safety < b.safety else 1 - if a.func.id != b.func.id: - return -1 if a.func.id < b.func.id else 1 - return 0 - - -# HACK: A way to add group header comments without having to modify printer code -def prefix_with_group_headers(cheats: list["Cheatcode"]): - s = set() - for i, cheat in enumerate(cheats): - if cheat.group in s: - continue - - s.add(cheat.group) - - c = copy.deepcopy(cheat) - c.func.description = "" - c.func.declaration = f"// ======== {group(c.group)} ========" - cheats.insert(i, c) - return cheats - - -def group(s: str) -> str: - if s == "evm": - return "EVM" - if s == "json": - return "JSON" - return s[0].upper() + s[1:] - - -class Visibility(PyEnum): - EXTERNAL: str = "external" - PUBLIC: str = "public" - INTERNAL: str = "internal" - PRIVATE: str = "private" - - def __str__(self): - return self.value - - -class Mutability(PyEnum): - PURE: str = "pure" - VIEW: str = "view" - NONE: str = "" - - def __str__(self): - return self.value - - -class Function: - id: str - description: str - declaration: str - visibility: Visibility - mutability: Mutability - signature: str - selector: str - selector_bytes: bytes - - def __init__( - self, - id: str, - description: str, - declaration: str, - visibility: Visibility, - mutability: Mutability, - signature: str, - selector: str, - selector_bytes: bytes, - ): - self.id = id - self.description = description - self.declaration = declaration - self.visibility = visibility - self.mutability = mutability - self.signature = signature - self.selector = selector - self.selector_bytes = selector_bytes - - @staticmethod - def from_dict(d: dict) -> "Function": - return Function( - d["id"], - d["description"], - d["declaration"], - Visibility(d["visibility"]), - Mutability(d["mutability"]), - d["signature"], - d["selector"], - bytes(d["selectorBytes"]), - ) - - -class Cheatcode: - func: Function - group: str - status: str - safety: str - - def __init__(self, func: Function, group: str, status: str, safety: str): - self.func = func - self.group = group - self.status = status - self.safety = safety - - @staticmethod - def from_dict(d: dict) -> "Cheatcode": - return Cheatcode( - Function.from_dict(d["func"]), - str(d["group"]), - str(d["status"]), - str(d["safety"]), - ) - - -class Error: - name: str - description: str - declaration: str - - def __init__(self, name: str, description: str, declaration: str): - self.name = name - self.description = description - self.declaration = declaration - - @staticmethod - def from_dict(d: dict) -> "Error": - return Error(**d) - - -class Event: - name: str - description: str - declaration: str - - def __init__(self, name: str, description: str, declaration: str): - self.name = name - self.description = description - self.declaration = declaration - - @staticmethod - def from_dict(d: dict) -> "Event": - return Event(**d) - - -class EnumVariant: - name: str - description: str - - def __init__(self, name: str, description: str): - self.name = name - self.description = description - - -class Enum: - name: str - description: str - variants: list[EnumVariant] - - def __init__(self, name: str, description: str, variants: list[EnumVariant]): - self.name = name - self.description = description - self.variants = variants - - @staticmethod - def from_dict(d: dict) -> "Enum": - return Enum( - d["name"], - d["description"], - list(map(lambda v: EnumVariant(**v), d["variants"])), - ) - - -class StructField: - name: str - ty: str - description: str - - def __init__(self, name: str, ty: str, description: str): - self.name = name - self.ty = ty - self.description = description - - -class Struct: - name: str - description: str - fields: list[StructField] - - def __init__(self, name: str, description: str, fields: list[StructField]): - self.name = name - self.description = description - self.fields = fields - - @staticmethod - def from_dict(d: dict) -> "Struct": - return Struct( - d["name"], - d["description"], - list(map(lambda f: StructField(**f), d["fields"])), - ) - - -class Cheatcodes: - errors: list[Error] - events: list[Event] - enums: list[Enum] - structs: list[Struct] - cheatcodes: list[Cheatcode] - - def __init__( - self, - errors: list[Error], - events: list[Event], - enums: list[Enum], - structs: list[Struct], - cheatcodes: list[Cheatcode], - ): - self.errors = errors - self.events = events - self.enums = enums - self.structs = structs - self.cheatcodes = cheatcodes - - @staticmethod - def from_dict(d: dict) -> "Cheatcodes": - return Cheatcodes( - errors=[Error.from_dict(e) for e in d["errors"]], - events=[Event.from_dict(e) for e in d["events"]], - enums=[Enum.from_dict(e) for e in d["enums"]], - structs=[Struct.from_dict(e) for e in d["structs"]], - cheatcodes=[Cheatcode.from_dict(e) for e in d["cheatcodes"]], - ) - - @staticmethod - def from_json(s) -> "Cheatcodes": - return Cheatcodes.from_dict(json.loads(s)) - - @staticmethod - def from_json_file(file_path: str) -> "Cheatcodes": - with open(file_path, "r") as f: - return Cheatcodes.from_dict(json.load(f)) - - -class Item(PyEnum): - ERROR: str = "error" - EVENT: str = "event" - ENUM: str = "enum" - STRUCT: str = "struct" - FUNCTION: str = "function" - - -class ItemOrder: - _list: list[Item] - - def __init__(self, list: list[Item]) -> None: - assert len(list) <= len(Item), "list must not contain more items than Item" - assert len(list) == len(set(list)), "list must not contain duplicates" - self._list = list - pass - - def get_list(self) -> list[Item]: - return self._list - - @staticmethod - def default() -> "ItemOrder": - return ItemOrder( - [ - Item.ERROR, - Item.EVENT, - Item.ENUM, - Item.STRUCT, - Item.FUNCTION, - ] - ) - - -class CheatcodesPrinter: - buffer: str - - prelude: bool - spdx_identifier: str - solidity_requirement: str - abicoder_v2: bool - - block_doc_style: bool - - indent_level: int - _indent_str: str - - nl_str: str - - items_order: ItemOrder - - def __init__( - self, - buffer: str = "", - prelude: bool = True, - spdx_identifier: str = "UNLICENSED", - solidity_requirement: str = "", - abicoder_pragma: bool = False, - block_doc_style: bool = False, - indent_level: int = 0, - indent_with: int | str = 4, - nl_str: str = "\n", - items_order: ItemOrder = ItemOrder.default(), - ): - self.prelude = prelude - self.spdx_identifier = spdx_identifier - self.solidity_requirement = solidity_requirement - self.abicoder_v2 = abicoder_pragma - self.block_doc_style = block_doc_style - self.buffer = buffer - self.indent_level = indent_level - self.nl_str = nl_str - - if isinstance(indent_with, int): - assert indent_with >= 0 - self._indent_str = " " * indent_with - elif isinstance(indent_with, str): - self._indent_str = indent_with - else: - assert False, "indent_with must be int or str" - - self.items_order = items_order - - def finish(self) -> str: - ret = self.buffer.rstrip() - self.buffer = "" - return ret - - def p_contract(self, contract: Cheatcodes, name: str, inherits: str = ""): - if self.prelude: - self.p_prelude(contract) - - self._p_str("interface ") - name = name.strip() - if name != "": - self._p_str(name) - self._p_str(" ") - if inherits != "": - self._p_str("is ") - self._p_str(inherits) - self._p_str(" ") - self._p_str("{") - self._p_nl() - self._with_indent(lambda: self._p_items(contract)) - self._p_str("}") - self._p_nl() - - def _p_items(self, contract: Cheatcodes): - for item in self.items_order.get_list(): - if item == Item.ERROR: - self.p_errors(contract.errors) - elif item == Item.EVENT: - self.p_events(contract.events) - elif item == Item.ENUM: - self.p_enums(contract.enums) - elif item == Item.STRUCT: - self.p_structs(contract.structs) - elif item == Item.FUNCTION: - self.p_functions(contract.cheatcodes) - else: - assert False, f"unknown item {item}" - - def p_prelude(self, contract: Cheatcodes | None = None): - self._p_str(f"// SPDX-License-Identifier: {self.spdx_identifier}") - self._p_nl() - - if self.solidity_requirement != "": - req = self.solidity_requirement - elif contract and len(contract.errors) > 0: - req = ">=0.8.4 <0.9.0" - else: - req = ">=0.6.0 <0.9.0" - self._p_str(f"pragma solidity {req};") - self._p_nl() - - if self.abicoder_v2: - self._p_str("pragma experimental ABIEncoderV2;") - self._p_nl() - - self._p_nl() - - def p_errors(self, errors: list[Error]): - for error in errors: - self._p_line(lambda: self.p_error(error)) - - def p_error(self, error: Error): - self._p_comment(error.description, doc=True) - self._p_line(lambda: self._p_str(error.declaration)) - - def p_events(self, events: list[Event]): - for event in events: - self._p_line(lambda: self.p_event(event)) - - def p_event(self, event: Event): - self._p_comment(event.description, doc=True) - self._p_line(lambda: self._p_str(event.declaration)) - - def p_enums(self, enums: list[Enum]): - for enum in enums: - self._p_line(lambda: self.p_enum(enum)) - - def p_enum(self, enum: Enum): - self._p_comment(enum.description, doc=True) - self._p_line(lambda: self._p_str(f"enum {enum.name} {{")) - self._with_indent(lambda: self.p_enum_variants(enum.variants)) - self._p_line(lambda: self._p_str("}")) - - def p_enum_variants(self, variants: list[EnumVariant]): - for i, variant in enumerate(variants): - self._p_indent() - self._p_comment(variant.description) - - self._p_indent() - self._p_str(variant.name) - if i < len(variants) - 1: - self._p_str(",") - self._p_nl() - - def p_structs(self, structs: list[Struct]): - for struct in structs: - self._p_line(lambda: self.p_struct(struct)) - - def p_struct(self, struct: Struct): - self._p_comment(struct.description, doc=True) - self._p_line(lambda: self._p_str(f"struct {struct.name} {{")) - self._with_indent(lambda: self.p_struct_fields(struct.fields)) - self._p_line(lambda: self._p_str("}")) - - def p_struct_fields(self, fields: list[StructField]): - for field in fields: - self._p_line(lambda: self.p_struct_field(field)) - - def p_struct_field(self, field: StructField): - self._p_comment(field.description) - self._p_indented(lambda: self._p_str(f"{field.ty} {field.name};")) - - def p_functions(self, cheatcodes: list[Cheatcode]): - for cheatcode in cheatcodes: - self._p_line(lambda: self.p_function(cheatcode.func)) - - def p_function(self, func: Function): - self._p_comment(func.description, doc=True) - self._p_line(lambda: self._p_str(func.declaration)) - - def _p_comment(self, s: str, doc: bool = False): - s = s.strip() - if s == "": - return - - s = map(lambda line: line.lstrip(), s.split("\n")) - if self.block_doc_style: - self._p_str("/*") - if doc: - self._p_str("*") - self._p_nl() - for line in s: - self._p_indent() - self._p_str(" ") - if doc: - self._p_str("* ") - self._p_str(line) - self._p_nl() - self._p_indent() - self._p_str(" */") - self._p_nl() - else: - first_line = True - for line in s: - if not first_line: - self._p_indent() - first_line = False - - if doc: - self._p_str("/// ") - else: - self._p_str("// ") - self._p_str(line) - self._p_nl() - - def _with_indent(self, f: VoidFn): - self._inc_indent() - f() - self._dec_indent() - - def _p_line(self, f: VoidFn): - self._p_indent() - f() - self._p_nl() - - def _p_indented(self, f: VoidFn): - self._p_indent() - f() - - def _p_indent(self): - for _ in range(self.indent_level): - self._p_str(self._indent_str) - - def _p_nl(self): - self._p_str(self.nl_str) - - def _p_str(self, txt: str): - self.buffer += txt - - def _inc_indent(self): - self.indent_level += 1 - - def _dec_indent(self): - self.indent_level -= 1 - - -if __name__ == "__main__": - main() diff --git a/grouperBot/lib/forge-std/src/Base.sol b/grouperBot/lib/forge-std/src/Base.sol deleted file mode 100644 index 52a5082..0000000 --- a/grouperBot/lib/forge-std/src/Base.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {StdStorage} from "./StdStorage.sol"; -import {Vm, VmSafe} from "./Vm.sol"; - -abstract contract CommonBase { - /// @dev Cheat code address. - /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`. - address internal constant VM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; - - /// @dev console.sol and console2.sol work by executing a staticcall to this address. - /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`. - address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; - - /// @dev Used when deploying with create2. - /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy. - address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - - /// @dev The default address for tx.origin and msg.sender. - /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`. - address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; - - /// @dev The address of the first contract `CREATE`d by a running test contract. - /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. - /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`. - address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; - - /// @dev Deterministic deployment address of the Multicall3 contract. - /// Taken from https://www.multicall3.com. - address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; - - /// @dev The order of the secp256k1 curve. - uint256 internal constant SECP256K1_ORDER = - 115792089237316195423570985008687907852837564279074904382605163141518161494337; - - uint256 internal constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - Vm internal constant vm = Vm(VM_ADDRESS); - StdStorage internal stdstore; -} - -abstract contract TestBase is CommonBase {} - -abstract contract ScriptBase is CommonBase { - VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); -} diff --git a/grouperBot/lib/forge-std/src/Config.sol b/grouperBot/lib/forge-std/src/Config.sol deleted file mode 100644 index 1c63c87..0000000 --- a/grouperBot/lib/forge-std/src/Config.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {console} from "./console.sol"; -import {StdConfig} from "./StdConfig.sol"; -import {CommonBase} from "./Base.sol"; - -/// @notice Boilerplate to streamline the setup of multi-chain environments. -abstract contract Config is CommonBase { - // -- STORAGE (CONFIG + CHAINS + FORKS) ------------------------------------ - - /// @dev Contract instance holding the data from the TOML config file. - StdConfig internal config; - - /// @dev Array of chain IDs for which forks have been created. - uint256[] internal chainIds; - - /// @dev A mapping from a chain ID to its initialized fork ID. - mapping(uint256 => uint256) internal forkOf; - - // -- HELPER FUNCTIONS ----------------------------------------------------- - - /// @notice Loads configuration from a file. - /// - /// @dev This function instantiates a `Config` contract, caching all its config variables. - /// - /// @param filePath: the path to the TOML configuration file. - /// @param writeToFile: whether updates are written back to the TOML file. - function _loadConfig(string memory filePath, bool writeToFile) internal { - console.log("----------"); - console.log(string.concat("Loading config from '", filePath, "'")); - config = new StdConfig(filePath, writeToFile); - vm.makePersistent(address(config)); - console.log("Config successfully loaded"); - console.log("----------"); - } - - /// @notice Loads configuration from a file and creates forks for each specified chain. - /// - /// @dev This function instantiates a `Config` contract, caching all its config variables, - /// reads the configured chain ids, and iterates through them to create a fork for each one. - /// It also creates a map `forkOf[chainId] -> forkId` to easily switch between forks. - /// - /// @param filePath: the path to the TOML configuration file. - /// @param writeToFile: whether updates are written back to the TOML file. - function _loadConfigAndForks(string memory filePath, bool writeToFile) internal { - _loadConfig(filePath, writeToFile); - - console.log("Setting up forks for the configured chains..."); - uint256[] memory chains = config.getChainIds(); - for (uint256 i = 0; i < chains.length; i++) { - uint256 chainId = chains[i]; - uint256 forkId = vm.createFork(config.getRpcUrl(chainId)); - forkOf[chainId] = forkId; - chainIds.push(chainId); - } - console.log("Forks successfully created"); - console.log("----------"); - } -} diff --git a/grouperBot/lib/forge-std/src/LibVariable.sol b/grouperBot/lib/forge-std/src/LibVariable.sol deleted file mode 100644 index c46b153..0000000 --- a/grouperBot/lib/forge-std/src/LibVariable.sol +++ /dev/null @@ -1,477 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// Enable globally. -using LibVariable for Variable global; - -struct Variable { - Type ty; - bytes data; -} - -struct Type { - TypeKind kind; - bool isArray; -} - -enum TypeKind { - None, - Bool, - Address, - Bytes32, - Uint256, - Int256, - String, - Bytes -} - -/// @notice Library for type-safe coercion of the `Variable` struct to concrete types. -/// -/// @dev Ensures that when a `Variable` is cast to a concrete Solidity type, the operation is safe and the -/// underlying type matches what is expected. -/// Provides functions to check types, convert them to strings, and coerce `Variable` instances into -/// both single values and arrays of various types. -/// -/// Usage example: -/// ```solidity -/// import {LibVariable} from "./LibVariable.sol"; -/// -/// contract MyContract { -/// using LibVariable for Variable; -/// StdConfig config; // Assume 'config' is an instance of `StdConfig` and has already been loaded. -/// -/// function readValues() public { -/// // Retrieve a 'uint256' value from the config. -/// uint256 myNumber = config.get("important_number").toUint256(); -/// -/// // Would revert with `TypeMismatch` as 'important_number' isn't a `uint256` in the config file. -/// // string memory notANumber = config.get("important_number").toString(); -/// -/// // Retrieve a address array from the config. -/// string[] memory admins = config.get("whitelisted_admins").toAddressArray(); -/// } -/// } -/// ``` -library LibVariable { - error NotInitialized(); - error TypeMismatch(string expected, string actual); - error UnsafeCast(string message); - - // -- TYPE HELPERS ---------------------------------------------------- - - /// @notice Compares two Type instances for equality. - function isEqual(Type memory self, Type memory other) internal pure returns (bool) { - return self.kind == other.kind && self.isArray == other.isArray; - } - - /// @notice Compares two Type instances for equality. Reverts if they are not equal. - function assertEq(Type memory self, Type memory other) internal pure { - if (!isEqual(self, other)) { - revert TypeMismatch(toString(other), toString(self)); - } - } - - /// @notice Converts a Type struct to its full string representation (i.e. "uint256[]"). - function toString(Type memory self) internal pure returns (string memory) { - string memory tyStr = toString(self.kind); - if (!self.isArray || self.kind == TypeKind.None) { - return tyStr; - } else { - return string.concat(tyStr, "[]"); - } - } - - /// @dev Converts a `TypeKind` enum to its base string representation. - function toString(TypeKind self) internal pure returns (string memory) { - if (self == TypeKind.Bool) return "bool"; - if (self == TypeKind.Address) return "address"; - if (self == TypeKind.Bytes32) return "bytes32"; - if (self == TypeKind.Uint256) return "uint256"; - if (self == TypeKind.Int256) return "int256"; - if (self == TypeKind.String) return "string"; - if (self == TypeKind.Bytes) return "bytes"; - return "none"; - } - - /// @dev Converts a `TypeKind` enum to its base string representation. - function toTomlKey(TypeKind self) internal pure returns (string memory) { - if (self == TypeKind.Bool) return "bool"; - if (self == TypeKind.Address) return "address"; - if (self == TypeKind.Bytes32) return "bytes32"; - if (self == TypeKind.Uint256) return "uint"; - if (self == TypeKind.Int256) return "int"; - if (self == TypeKind.String) return "string"; - if (self == TypeKind.Bytes) return "bytes"; - return "none"; - } - - // -- VARIABLE HELPERS ---------------------------------------------------- - - /// @dev Checks if a `Variable` has been initialized and matches the expected type reverting if not. - modifier check(Variable memory self, Type memory expected) { - assertExists(self); - assertEq(self.ty, expected); - _; - } - - /// @dev Checks if a `Variable` has been initialized, reverting if not. - function assertExists(Variable memory self) public pure { - if (self.ty.kind == TypeKind.None) { - revert NotInitialized(); - } - } - - // -- VARIABLE COERCION FUNCTIONS (SINGLE VALUES) -------------------------- - - /// @notice Coerces a `Variable` to a `bool` value. - function toBool(Variable memory self) internal pure check(self, Type(TypeKind.Bool, false)) returns (bool) { - return abi.decode(self.data, (bool)); - } - - /// @notice Coerces a `Variable` to an `address` value. - function toAddress(Variable memory self) - internal - pure - check(self, Type(TypeKind.Address, false)) - returns (address) - { - return abi.decode(self.data, (address)); - } - - /// @notice Coerces a `Variable` to a `bytes32` value. - function toBytes32(Variable memory self) - internal - pure - check(self, Type(TypeKind.Bytes32, false)) - returns (bytes32) - { - return abi.decode(self.data, (bytes32)); - } - - /// @notice Coerces a `Variable` to a `uint256` value. - function toUint256(Variable memory self) - internal - pure - check(self, Type(TypeKind.Uint256, false)) - returns (uint256) - { - return abi.decode(self.data, (uint256)); - } - - /// @notice Coerces a `Variable` to a `uint128` value, checking for overflow. - function toUint128(Variable memory self) internal pure returns (uint128) { - uint256 value = self.toUint256(); - if (value > type(uint128).max) { - revert UnsafeCast("value does not fit in 'uint128'"); - } - return uint128(value); - } - - /// @notice Coerces a `Variable` to a `uint64` value, checking for overflow. - function toUint64(Variable memory self) internal pure returns (uint64) { - uint256 value = self.toUint256(); - if (value > type(uint64).max) { - revert UnsafeCast("value does not fit in 'uint64'"); - } - return uint64(value); - } - - /// @notice Coerces a `Variable` to a `uint32` value, checking for overflow. - function toUint32(Variable memory self) internal pure returns (uint32) { - uint256 value = self.toUint256(); - if (value > type(uint32).max) { - revert UnsafeCast("value does not fit in 'uint32'"); - } - return uint32(value); - } - - /// @notice Coerces a `Variable` to a `uint16` value, checking for overflow. - function toUint16(Variable memory self) internal pure returns (uint16) { - uint256 value = self.toUint256(); - if (value > type(uint16).max) { - revert UnsafeCast("value does not fit in 'uint16'"); - } - return uint16(value); - } - - /// @notice Coerces a `Variable` to a `uint8` value, checking for overflow. - function toUint8(Variable memory self) internal pure returns (uint8) { - uint256 value = self.toUint256(); - if (value > type(uint8).max) { - revert UnsafeCast("value does not fit in 'uint8'"); - } - return uint8(value); - } - - /// @notice Coerces a `Variable` to an `int256` value. - function toInt256(Variable memory self) internal pure check(self, Type(TypeKind.Int256, false)) returns (int256) { - return abi.decode(self.data, (int256)); - } - - /// @notice Coerces a `Variable` to an `int128` value, checking for overflow/underflow. - function toInt128(Variable memory self) internal pure returns (int128) { - int256 value = self.toInt256(); - if (value > type(int128).max || value < type(int128).min) { - revert UnsafeCast("value does not fit in 'int128'"); - } - return int128(value); - } - - /// @notice Coerces a `Variable` to an `int64` value, checking for overflow/underflow. - function toInt64(Variable memory self) internal pure returns (int64) { - int256 value = self.toInt256(); - if (value > type(int64).max || value < type(int64).min) { - revert UnsafeCast("value does not fit in 'int64'"); - } - return int64(value); - } - - /// @notice Coerces a `Variable` to an `int32` value, checking for overflow/underflow. - function toInt32(Variable memory self) internal pure returns (int32) { - int256 value = self.toInt256(); - if (value > type(int32).max || value < type(int32).min) { - revert UnsafeCast("value does not fit in 'int32'"); - } - return int32(value); - } - - /// @notice Coerces a `Variable` to an `int16` value, checking for overflow/underflow. - function toInt16(Variable memory self) internal pure returns (int16) { - int256 value = self.toInt256(); - if (value > type(int16).max || value < type(int16).min) { - revert UnsafeCast("value does not fit in 'int16'"); - } - return int16(value); - } - - /// @notice Coerces a `Variable` to an `int8` value, checking for overflow/underflow. - function toInt8(Variable memory self) internal pure returns (int8) { - int256 value = self.toInt256(); - if (value > type(int8).max || value < type(int8).min) { - revert UnsafeCast("value does not fit in 'int8'"); - } - return int8(value); - } - - /// @notice Coerces a `Variable` to a `string` value. - function toString(Variable memory self) - internal - pure - check(self, Type(TypeKind.String, false)) - returns (string memory) - { - return abi.decode(self.data, (string)); - } - - /// @notice Coerces a `Variable` to a `bytes` value. - function toBytes(Variable memory self) - internal - pure - check(self, Type(TypeKind.Bytes, false)) - returns (bytes memory) - { - return abi.decode(self.data, (bytes)); - } - - // -- VARIABLE COERCION FUNCTIONS (ARRAYS) --------------------------------- - - /// @notice Coerces a `Variable` to a `bool` array. - function toBoolArray(Variable memory self) - internal - pure - check(self, Type(TypeKind.Bool, true)) - returns (bool[] memory) - { - return abi.decode(self.data, (bool[])); - } - - /// @notice Coerces a `Variable` to an `address` array. - function toAddressArray(Variable memory self) - internal - pure - check(self, Type(TypeKind.Address, true)) - returns (address[] memory) - { - return abi.decode(self.data, (address[])); - } - - /// @notice Coerces a `Variable` to a `bytes32` array. - function toBytes32Array(Variable memory self) - internal - pure - check(self, Type(TypeKind.Bytes32, true)) - returns (bytes32[] memory) - { - return abi.decode(self.data, (bytes32[])); - } - - /// @notice Coerces a `Variable` to a `uint256` array. - function toUint256Array(Variable memory self) - internal - pure - check(self, Type(TypeKind.Uint256, true)) - returns (uint256[] memory) - { - return abi.decode(self.data, (uint256[])); - } - - /// @notice Coerces a `Variable` to a `uint128` array, checking for overflow. - function toUint128Array(Variable memory self) internal pure returns (uint128[] memory) { - uint256[] memory values = self.toUint256Array(); - uint128[] memory result = new uint128[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(uint128).max) { - revert UnsafeCast("value in array does not fit in 'uint128'"); - } - result[i] = uint128(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `uint64` array, checking for overflow. - function toUint64Array(Variable memory self) internal pure returns (uint64[] memory) { - uint256[] memory values = self.toUint256Array(); - uint64[] memory result = new uint64[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(uint64).max) { - revert UnsafeCast("value in array does not fit in 'uint64'"); - } - result[i] = uint64(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `uint32` array, checking for overflow. - function toUint32Array(Variable memory self) internal pure returns (uint32[] memory) { - uint256[] memory values = self.toUint256Array(); - uint32[] memory result = new uint32[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(uint32).max) { - revert UnsafeCast("value in array does not fit in 'uint32'"); - } - result[i] = uint32(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `uint16` array, checking for overflow. - function toUint16Array(Variable memory self) internal pure returns (uint16[] memory) { - uint256[] memory values = self.toUint256Array(); - uint16[] memory result = new uint16[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(uint16).max) { - revert UnsafeCast("value in array does not fit in 'uint16'"); - } - result[i] = uint16(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `uint8` array, checking for overflow. - function toUint8Array(Variable memory self) internal pure returns (uint8[] memory) { - uint256[] memory values = self.toUint256Array(); - uint8[] memory result = new uint8[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(uint8).max) { - revert UnsafeCast("value in array does not fit in 'uint8'"); - } - result[i] = uint8(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to an `int256` array. - function toInt256Array(Variable memory self) - internal - pure - check(self, Type(TypeKind.Int256, true)) - returns (int256[] memory) - { - return abi.decode(self.data, (int256[])); - } - - /// @notice Coerces a `Variable` to a `int128` array, checking for overflow/underflow. - function toInt128Array(Variable memory self) internal pure returns (int128[] memory) { - int256[] memory values = self.toInt256Array(); - int128[] memory result = new int128[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(int128).max || values[i] < type(int128).min) { - revert UnsafeCast("value in array does not fit in 'int128'"); - } - result[i] = int128(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `int64` array, checking for overflow/underflow. - function toInt64Array(Variable memory self) internal pure returns (int64[] memory) { - int256[] memory values = self.toInt256Array(); - int64[] memory result = new int64[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(int64).max || values[i] < type(int64).min) { - revert UnsafeCast("value in array does not fit in 'int64'"); - } - result[i] = int64(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `int32` array, checking for overflow/underflow. - function toInt32Array(Variable memory self) internal pure returns (int32[] memory) { - int256[] memory values = self.toInt256Array(); - int32[] memory result = new int32[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(int32).max || values[i] < type(int32).min) { - revert UnsafeCast("value in array does not fit in 'int32'"); - } - result[i] = int32(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `int16` array, checking for overflow/underflow. - function toInt16Array(Variable memory self) internal pure returns (int16[] memory) { - int256[] memory values = self.toInt256Array(); - int16[] memory result = new int16[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(int16).max || values[i] < type(int16).min) { - revert UnsafeCast("value in array does not fit in 'int16'"); - } - result[i] = int16(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `int8` array, checking for overflow/underflow. - function toInt8Array(Variable memory self) internal pure returns (int8[] memory) { - int256[] memory values = self.toInt256Array(); - int8[] memory result = new int8[](values.length); - for (uint256 i = 0; i < values.length; i++) { - if (values[i] > type(int8).max || values[i] < type(int8).min) { - revert UnsafeCast("value in array does not fit in 'int8'"); - } - result[i] = int8(values[i]); - } - return result; - } - - /// @notice Coerces a `Variable` to a `string` array. - function toStringArray(Variable memory self) - internal - pure - check(self, Type(TypeKind.String, true)) - returns (string[] memory) - { - return abi.decode(self.data, (string[])); - } - - /// @notice Coerces a `Variable` to a `bytes` array. - function toBytesArray(Variable memory self) - internal - pure - check(self, Type(TypeKind.Bytes, true)) - returns (bytes[] memory) - { - return abi.decode(self.data, (bytes[])); - } -} diff --git a/grouperBot/lib/forge-std/src/Script.sol b/grouperBot/lib/forge-std/src/Script.sol deleted file mode 100644 index a2e2aa1..0000000 --- a/grouperBot/lib/forge-std/src/Script.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -// 💬 ABOUT -// Forge Std's default Script. - -// 🧩 MODULES -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {safeconsole} from "./safeconsole.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheatsSafe} from "./StdCheats.sol"; -import {StdConstants} from "./StdConstants.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; -import {StdStyle} from "./StdStyle.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {VmSafe} from "./Vm.sol"; - -// 📦 BOILERPLATE -import {ScriptBase} from "./Base.sol"; - -// ⭐️ SCRIPT -abstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils { - // Note: IS_SCRIPT() must return true. - bool public IS_SCRIPT = true; -} diff --git a/grouperBot/lib/forge-std/src/StdAssertions.sol b/grouperBot/lib/forge-std/src/StdAssertions.sol deleted file mode 100644 index 4248170..0000000 --- a/grouperBot/lib/forge-std/src/StdAssertions.sol +++ /dev/null @@ -1,764 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; -pragma experimental ABIEncoderV2; - -import {Vm} from "./Vm.sol"; - -abstract contract StdAssertions { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - event log(string); - event logs(bytes); - - event log_address(address); - event log_bytes32(bytes32); - event log_int(int256); - event log_uint(uint256); - event log_bytes(bytes); - event log_string(string); - - event log_named_address(string key, address val); - event log_named_bytes32(string key, bytes32 val); - event log_named_decimal_int(string key, int256 val, uint256 decimals); - event log_named_decimal_uint(string key, uint256 val, uint256 decimals); - event log_named_int(string key, int256 val); - event log_named_uint(string key, uint256 val); - event log_named_bytes(string key, bytes val); - event log_named_string(string key, string val); - - event log_array(uint256[] val); - event log_array(int256[] val); - event log_array(address[] val); - event log_named_array(string key, uint256[] val); - event log_named_array(string key, int256[] val); - event log_named_array(string key, address[] val); - - bytes32 private constant FAILED_SLOT = bytes32("failed"); - - bool private _failed; - - function failed() public view returns (bool) { - if (_failed) { - return true; - } else { - return vm.load(address(vm), FAILED_SLOT) != bytes32(0); - } - } - - function fail() internal virtual { - vm.store(address(vm), FAILED_SLOT, bytes32(uint256(1))); - _failed = true; - } - - function fail(string memory message) internal virtual { - fail(); - vm.assertTrue(false, message); - } - - function assertTrue(bool data) internal pure virtual { - if (!data) { - vm.assertTrue(data); - } - } - - function assertTrue(bool data, string memory err) internal pure virtual { - if (!data) { - vm.assertTrue(data, err); - } - } - - function assertFalse(bool data) internal pure virtual { - if (data) { - vm.assertFalse(data); - } - } - - function assertFalse(bool data, string memory err) internal pure virtual { - if (data) { - vm.assertFalse(data, err); - } - } - - function assertEq(bool left, bool right) internal pure virtual { - if (left != right) { - vm.assertEq(left, right); - } - } - - function assertEq(bool left, bool right, string memory err) internal pure virtual { - if (left != right) { - vm.assertEq(left, right, err); - } - } - - function assertEq(uint256 left, uint256 right) internal pure virtual { - if (left != right) { - vm.assertEq(left, right); - } - } - - function assertEq(uint256 left, uint256 right, string memory err) internal pure virtual { - if (left != right) { - vm.assertEq(left, right, err); - } - } - - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertEqDecimal(left, right, decimals); - } - - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertEqDecimal(left, right, decimals, err); - } - - function assertEq(int256 left, int256 right) internal pure virtual { - if (left != right) { - vm.assertEq(left, right); - } - } - - function assertEq(int256 left, int256 right, string memory err) internal pure virtual { - if (left != right) { - vm.assertEq(left, right, err); - } - } - - function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertEqDecimal(left, right, decimals); - } - - function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertEqDecimal(left, right, decimals, err); - } - - function assertEq(address left, address right) internal pure virtual { - if (left != right) { - vm.assertEq(left, right); - } - } - - function assertEq(address left, address right, string memory err) internal pure virtual { - if (left != right) { - vm.assertEq(left, right, err); - } - } - - function assertEq(bytes32 left, bytes32 right) internal pure virtual { - if (left != right) { - vm.assertEq(left, right); - } - } - - function assertEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { - if (left != right) { - vm.assertEq(left, right, err); - } - } - - function assertEq32(bytes32 left, bytes32 right) internal pure virtual { - if (left != right) { - vm.assertEq(left, right); - } - } - - function assertEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { - if (left != right) { - vm.assertEq(left, right, err); - } - } - - function assertEq(string memory left, string memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(string memory left, string memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bytes memory left, bytes memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bool[] memory left, bool[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(uint256[] memory left, uint256[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(int256[] memory left, int256[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(address[] memory left, address[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(string[] memory left, string[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - function assertEq(bytes[] memory left, bytes[] memory right) internal pure virtual { - vm.assertEq(left, right); - } - - function assertEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { - vm.assertEq(left, right, err); - } - - // Legacy helper - function assertEqUint(uint256 left, uint256 right) internal pure virtual { - assertEq(left, right); - } - - function assertNotEq(bool left, bool right) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right); - } - } - - function assertNotEq(bool left, bool right, string memory err) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right, err); - } - } - - function assertNotEq(uint256 left, uint256 right) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right); - } - } - - function assertNotEq(uint256 left, uint256 right, string memory err) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right, err); - } - } - - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertNotEqDecimal(left, right, decimals); - } - - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - pure - virtual - { - vm.assertNotEqDecimal(left, right, decimals, err); - } - - function assertNotEq(int256 left, int256 right) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right); - } - } - - function assertNotEq(int256 left, int256 right, string memory err) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right, err); - } - } - - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertNotEqDecimal(left, right, decimals); - } - - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertNotEqDecimal(left, right, decimals, err); - } - - function assertNotEq(address left, address right) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right); - } - } - - function assertNotEq(address left, address right, string memory err) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right, err); - } - } - - function assertNotEq(bytes32 left, bytes32 right) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right); - } - } - - function assertNotEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right, err); - } - } - - function assertNotEq32(bytes32 left, bytes32 right) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right); - } - } - - function assertNotEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { - if (left == right) { - vm.assertNotEq(left, right, err); - } - } - - function assertNotEq(string memory left, string memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(string memory left, string memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes memory left, bytes memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bool[] memory left, bool[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(uint256[] memory left, uint256[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(int256[] memory left, int256[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(address[] memory left, address[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(string[] memory left, string[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes[] memory left, bytes[] memory right) internal pure virtual { - vm.assertNotEq(left, right); - } - - function assertNotEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { - vm.assertNotEq(left, right, err); - } - - function assertLt(uint256 left, uint256 right) internal pure virtual { - if (left >= right) { - vm.assertLt(left, right); - } - } - - function assertLt(uint256 left, uint256 right, string memory err) internal pure virtual { - if (left >= right) { - vm.assertLt(left, right, err); - } - } - - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertLtDecimal(left, right, decimals); - } - - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLtDecimal(left, right, decimals, err); - } - - function assertLt(int256 left, int256 right) internal pure virtual { - if (left >= right) { - vm.assertLt(left, right); - } - } - - function assertLt(int256 left, int256 right, string memory err) internal pure virtual { - if (left >= right) { - vm.assertLt(left, right, err); - } - } - - function assertLtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertLtDecimal(left, right, decimals); - } - - function assertLtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLtDecimal(left, right, decimals, err); - } - - function assertGt(uint256 left, uint256 right) internal pure virtual { - if (left <= right) { - vm.assertGt(left, right); - } - } - - function assertGt(uint256 left, uint256 right, string memory err) internal pure virtual { - if (left <= right) { - vm.assertGt(left, right, err); - } - } - - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertGtDecimal(left, right, decimals); - } - - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGtDecimal(left, right, decimals, err); - } - - function assertGt(int256 left, int256 right) internal pure virtual { - if (left <= right) { - vm.assertGt(left, right); - } - } - - function assertGt(int256 left, int256 right, string memory err) internal pure virtual { - if (left <= right) { - vm.assertGt(left, right, err); - } - } - - function assertGtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertGtDecimal(left, right, decimals); - } - - function assertGtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGtDecimal(left, right, decimals, err); - } - - function assertLe(uint256 left, uint256 right) internal pure virtual { - if (left > right) { - vm.assertLe(left, right); - } - } - - function assertLe(uint256 left, uint256 right, string memory err) internal pure virtual { - if (left > right) { - vm.assertLe(left, right, err); - } - } - - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertLeDecimal(left, right, decimals); - } - - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLeDecimal(left, right, decimals, err); - } - - function assertLe(int256 left, int256 right) internal pure virtual { - if (left > right) { - vm.assertLe(left, right); - } - } - - function assertLe(int256 left, int256 right, string memory err) internal pure virtual { - if (left > right) { - vm.assertLe(left, right, err); - } - } - - function assertLeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertLeDecimal(left, right, decimals); - } - - function assertLeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertLeDecimal(left, right, decimals, err); - } - - function assertGe(uint256 left, uint256 right) internal pure virtual { - if (left < right) { - vm.assertGe(left, right); - } - } - - function assertGe(uint256 left, uint256 right, string memory err) internal pure virtual { - if (left < right) { - vm.assertGe(left, right, err); - } - } - - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { - vm.assertGeDecimal(left, right, decimals); - } - - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGeDecimal(left, right, decimals, err); - } - - function assertGe(int256 left, int256 right) internal pure virtual { - if (left < right) { - vm.assertGe(left, right); - } - } - - function assertGe(int256 left, int256 right, string memory err) internal pure virtual { - if (left < right) { - vm.assertGe(left, right, err); - } - } - - function assertGeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { - vm.assertGeDecimal(left, right, decimals); - } - - function assertGeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { - vm.assertGeDecimal(left, right, decimals, err); - } - - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) internal pure virtual { - vm.assertApproxEqAbs(left, right, maxDelta); - } - - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string memory err) - internal - pure - virtual - { - vm.assertApproxEqAbs(left, right, maxDelta, err); - } - - function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) - internal - pure - virtual - { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); - } - - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals, - string memory err - ) internal pure virtual { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); - } - - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) internal pure virtual { - vm.assertApproxEqAbs(left, right, maxDelta); - } - - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string memory err) internal pure virtual { - vm.assertApproxEqAbs(left, right, maxDelta, err); - } - - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) - internal - pure - virtual - { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); - } - - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals, string memory err) - internal - pure - virtual - { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); - } - - function assertApproxEqRel( - uint256 left, - uint256 right, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta); - } - - function assertApproxEqRel( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta, err); - } - - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); - } - - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); - } - - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta); - } - - function assertApproxEqRel( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal pure virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta, err); - } - - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); - } - - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal pure virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); - } - - // Inherited from DSTest, not used but kept for backwards-compatibility - function checkEq0(bytes memory left, bytes memory right) internal pure returns (bool) { - return keccak256(left) == keccak256(right); - } - - function assertEq0(bytes memory left, bytes memory right) internal pure virtual { - assertEq(left, right); - } - - function assertEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { - assertEq(left, right, err); - } - - function assertNotEq0(bytes memory left, bytes memory right) internal pure virtual { - assertNotEq(left, right); - } - - function assertNotEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { - assertNotEq(left, right, err); - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { - assertEqCall(target, callDataA, target, callDataB, true); - } - - function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) - internal - virtual - { - assertEqCall(targetA, callDataA, targetB, callDataB, true); - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) - internal - virtual - { - assertEqCall(target, callDataA, target, callDataB, strictRevertData); - } - - function assertEqCall( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData - ) internal virtual { - (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); - (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); - - if (successA && successB) { - assertEq(returnDataA, returnDataB, "Call return data does not match"); - } - - if (!successA && !successB && strictRevertData) { - assertEq(returnDataA, returnDataB, "Call revert data does not match"); - } - - if (!successA && successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call revert data", returnDataA); - emit log_named_bytes(" Right call return data", returnDataB); - revert("assertion failed"); - } - - if (successA && !successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call return data", returnDataA); - emit log_named_bytes(" Right call revert data", returnDataB); - revert("assertion failed"); - } - } -} diff --git a/grouperBot/lib/forge-std/src/StdChains.sol b/grouperBot/lib/forge-std/src/StdChains.sol deleted file mode 100644 index 3bc5f43..0000000 --- a/grouperBot/lib/forge-std/src/StdChains.sol +++ /dev/null @@ -1,287 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -/** - * StdChains provides information about EVM compatible chains that can be used in scripts/tests. - * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are - * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of - * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the - * alias used in this contract, which can be found as the first argument to the - * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. - * - * There are two main ways to use this contract: - * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or - * `setChain(string memory chainAlias, Chain memory chain)` - * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. - * - * The first time either of those are used, chains are initialized with the default set of RPC URLs. - * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in - * `defaultRpcUrls`. - * - * The `setChain` function is straightforward, and it simply saves off the given chain data. - * - * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say - * we want to retrieve the RPC URL for `mainnet`: - * - If you have specified data with `setChain`, it will return that. - * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it - * is valid (e.g. a URL is specified, or an environment variable is given and exists). - * - If neither of the above conditions is met, the default data is returned. - * - * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. - */ -abstract contract StdChains { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - bool private stdChainsInitialized; - - struct ChainData { - string name; - uint256 chainId; - string rpcUrl; - } - - struct Chain { - // The chain name. - string name; - // The chain's Chain ID. - uint256 chainId; - // The chain's alias. (i.e. what gets specified in `foundry.toml`). - string chainAlias; - // A default RPC endpoint for this chain. - // NOTE: This default RPC URL is included for convenience to facilitate quick tests and - // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy - // usage as you will be throttled and this is a disservice to others who need this endpoint. - string rpcUrl; - } - - // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. - mapping(string => Chain) private chains; - // Maps from the chain's alias to it's default RPC URL. - mapping(string => string) private defaultRpcUrls; - // Maps from a chain ID to it's alias. - mapping(uint256 => string) private idToAlias; - - bool private fallbackToDefaultRpcUrls = true; - - // The RPC URL will be fetched from config or defaultRpcUrls if possible. - function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { - require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); - - initializeStdChains(); - chain = chains[chainAlias]; - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { - require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); - initializeStdChains(); - string memory chainAlias = idToAlias[chainId]; - - chain = chains[chainAlias]; - - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, ChainData memory chain) internal virtual { - require( - bytes(chainAlias).length != 0, - "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." - ); - - require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); - - initializeStdChains(); - string memory foundAlias = idToAlias[chain.chainId]; - - require( - bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), - string( - abi.encodePacked( - "StdChains setChain(string,ChainData): Chain ID ", - vm.toString(chain.chainId), - " already used by \"", - foundAlias, - "\"." - ) - ) - ); - - uint256 oldChainId = chains[chainAlias].chainId; - delete idToAlias[oldChainId]; - - chains[chainAlias] = - Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); - idToAlias[chain.chainId] = chainAlias; - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, Chain memory chain) internal virtual { - setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); - } - - function _toUpper(string memory str) private pure returns (string memory) { - bytes memory strb = bytes(str); - bytes memory copy = new bytes(strb.length); - for (uint256 i = 0; i < strb.length; i++) { - bytes1 b = strb[i]; - if (b >= 0x61 && b <= 0x7A) { - copy[i] = bytes1(uint8(b) - 32); - } else { - copy[i] = b; - } - } - return string(copy); - } - - // lookup rpcUrl, in descending order of priority: - // current -> config (foundry.toml) -> environment variable -> default - function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) - private - view - returns (Chain memory) - { - if (bytes(chain.rpcUrl).length == 0) { - try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { - chain.rpcUrl = configRpcUrl; - } catch (bytes memory err) { - string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); - if (fallbackToDefaultRpcUrls) { - chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); - } else { - chain.rpcUrl = vm.envString(envName); - } - // Distinguish 'not found' from 'cannot read' - // The upstream error thrown by forge for failing cheats changed so we check both the old and new versions - bytes memory oldNotFoundError = - abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); - bytes memory newNotFoundError = abi.encodeWithSignature( - "CheatcodeError(string)", string(abi.encodePacked("invalid rpc url: ", chainAlias)) - ); - bytes32 errHash = keccak256(err); - if ( - (errHash != keccak256(oldNotFoundError) && errHash != keccak256(newNotFoundError)) - || bytes(chain.rpcUrl).length == 0 - ) { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, err), mload(err)) - } - } - } - } - return chain; - } - - function setFallbackToDefaultRpcUrls(bool useDefault) internal { - fallbackToDefaultRpcUrls = useDefault; - } - - function initializeStdChains() private { - if (stdChainsInitialized) return; - - stdChainsInitialized = true; - - // If adding an RPC here, make sure to test the default RPC URL in `test_Rpcs` in `StdChains.t.sol` - setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); - setChainWithDefaultRpcUrl("mainnet", ChainData("Mainnet", 1, "https://eth.llamarpc.com")); - setChainWithDefaultRpcUrl( - "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl("holesky", ChainData("Holesky", 17000, "https://rpc.holesky.ethpandaops.io")); - setChainWithDefaultRpcUrl("hoodi", ChainData("Hoodi", 560048, "https://rpc.hoodi.ethpandaops.io")); - setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); - setChainWithDefaultRpcUrl( - "optimism_sepolia", ChainData("Optimism Sepolia", 11155420, "https://sepolia.optimism.io") - ); - setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl( - "arbitrum_one_sepolia", ChainData("Arbitrum One Sepolia", 421614, "https://sepolia-rollup.arbitrum.io/rpc") - ); - setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); - setChainWithDefaultRpcUrl( - "polygon_amoy", ChainData("Polygon Amoy", 80002, "https://rpc-amoy.polygon.technology") - ); - setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); - setChainWithDefaultRpcUrl( - "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain_testnet", - ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") - ); - setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); - setChainWithDefaultRpcUrl("moonbeam", ChainData("Moonbeam", 1284, "https://rpc.api.moonbeam.network")); - setChainWithDefaultRpcUrl( - "moonriver", ChainData("Moonriver", 1285, "https://rpc.api.moonriver.moonbeam.network") - ); - setChainWithDefaultRpcUrl("moonbase", ChainData("Moonbase", 1287, "https://rpc.testnet.moonbeam.network")); - setChainWithDefaultRpcUrl("base_sepolia", ChainData("Base Sepolia", 84532, "https://sepolia.base.org")); - setChainWithDefaultRpcUrl("base", ChainData("Base", 8453, "https://mainnet.base.org")); - setChainWithDefaultRpcUrl("blast_sepolia", ChainData("Blast Sepolia", 168587773, "https://sepolia.blast.io")); - setChainWithDefaultRpcUrl("blast", ChainData("Blast", 81457, "https://rpc.blast.io")); - setChainWithDefaultRpcUrl("fantom_opera", ChainData("Fantom Opera", 250, "https://rpc.ankr.com/fantom/")); - setChainWithDefaultRpcUrl( - "fantom_opera_testnet", ChainData("Fantom Opera Testnet", 4002, "https://rpc.ankr.com/fantom_testnet/") - ); - setChainWithDefaultRpcUrl("fraxtal", ChainData("Fraxtal", 252, "https://rpc.frax.com")); - setChainWithDefaultRpcUrl("fraxtal_testnet", ChainData("Fraxtal Testnet", 2522, "https://rpc.testnet.frax.com")); - setChainWithDefaultRpcUrl( - "berachain_bartio_testnet", ChainData("Berachain bArtio Testnet", 80084, "https://bartio.rpc.berachain.com") - ); - setChainWithDefaultRpcUrl("flare", ChainData("Flare", 14, "https://flare-api.flare.network/ext/C/rpc")); - setChainWithDefaultRpcUrl( - "flare_coston2", ChainData("Flare Coston2", 114, "https://coston2-api.flare.network/ext/C/rpc") - ); - - setChainWithDefaultRpcUrl("mode", ChainData("Mode", 34443, "https://mode.drpc.org")); - setChainWithDefaultRpcUrl("mode_sepolia", ChainData("Mode Sepolia", 919, "https://sepolia.mode.network")); - - setChainWithDefaultRpcUrl("zora", ChainData("Zora", 7777777, "https://zora.drpc.org")); - setChainWithDefaultRpcUrl( - "zora_sepolia", ChainData("Zora Sepolia", 999999999, "https://sepolia.rpc.zora.energy") - ); - - setChainWithDefaultRpcUrl("race", ChainData("Race", 6805, "https://racemainnet.io")); - setChainWithDefaultRpcUrl("race_sepolia", ChainData("Race Sepolia", 6806, "https://racemainnet.io")); - - setChainWithDefaultRpcUrl("metal", ChainData("Metal", 1750, "https://metall2.drpc.org")); - setChainWithDefaultRpcUrl("metal_sepolia", ChainData("Metal Sepolia", 1740, "https://testnet.rpc.metall2.com")); - - setChainWithDefaultRpcUrl("binary", ChainData("Binary", 624, "https://rpc.zero.thebinaryholdings.com")); - setChainWithDefaultRpcUrl( - "binary_sepolia", ChainData("Binary Sepolia", 625, "https://rpc.zero.thebinaryholdings.com") - ); - - setChainWithDefaultRpcUrl("orderly", ChainData("Orderly", 291, "https://rpc.orderly.network")); - setChainWithDefaultRpcUrl( - "orderly_sepolia", ChainData("Orderly Sepolia", 4460, "https://testnet-rpc.orderly.org") - ); - } - - // set chain info, with priority to chainAlias' rpc url in foundry.toml - function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { - string memory rpcUrl = chain.rpcUrl; - defaultRpcUrls[chainAlias] = rpcUrl; - chain.rpcUrl = ""; - setChain(chainAlias, chain); - chain.rpcUrl = rpcUrl; // restore argument - } -} diff --git a/grouperBot/lib/forge-std/src/StdCheats.sol b/grouperBot/lib/forge-std/src/StdCheats.sol deleted file mode 100644 index 9f360de..0000000 --- a/grouperBot/lib/forge-std/src/StdCheats.sol +++ /dev/null @@ -1,829 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {console2} from "./console2.sol"; -import {Vm} from "./Vm.sol"; - -abstract contract StdCheatsSafe { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - uint256 private constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - bool private gasMeteringOff; - - // Data structures to parse Transaction objects from the broadcast artifact - // that conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawTx1559 { - string[] arguments; - address contractAddress; - string contractName; - // json value name = function - string functionSig; - bytes32 hash; - // json value name = tx - RawTx1559Detail txDetail; - // json value name = type - string opcode; - } - - struct RawTx1559Detail { - AccessList[] accessList; - bytes data; - address from; - bytes gas; - bytes nonce; - address to; - bytes txType; - bytes value; - } - - struct Tx1559 { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - bytes32 hash; - Tx1559Detail txDetail; - string opcode; - } - - struct Tx1559Detail { - AccessList[] accessList; - bytes data; - address from; - uint256 gas; - uint256 nonce; - address to; - uint256 txType; - uint256 value; - } - - // Data structures to parse Transaction objects from the broadcast artifact - // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct TxLegacy { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - string hash; - string opcode; - TxDetailLegacy transaction; - } - - struct TxDetailLegacy { - AccessList[] accessList; - uint256 chainId; - bytes data; - address from; - uint256 gas; - uint256 gasPrice; - bytes32 hash; - uint256 nonce; - bytes1 opcode; - bytes32 r; - bytes32 s; - uint256 txType; - address to; - uint8 v; - uint256 value; - } - - struct AccessList { - address accessAddress; - bytes32[] storageKeys; - } - - // Data structures to parse Receipt objects from the broadcast artifact. - // The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawReceipt { - bytes32 blockHash; - bytes blockNumber; - address contractAddress; - bytes cumulativeGasUsed; - bytes effectiveGasPrice; - address from; - bytes gasUsed; - RawReceiptLog[] logs; - bytes logsBloom; - bytes status; - address to; - bytes32 transactionHash; - bytes transactionIndex; - } - - struct Receipt { - bytes32 blockHash; - uint256 blockNumber; - address contractAddress; - uint256 cumulativeGasUsed; - uint256 effectiveGasPrice; - address from; - uint256 gasUsed; - ReceiptLog[] logs; - bytes logsBloom; - uint256 status; - address to; - bytes32 transactionHash; - uint256 transactionIndex; - } - - // Data structures to parse the entire broadcast artifact, assuming the - // transactions conform to EIP1559. - - struct EIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - Receipt[] receipts; - uint256 timestamp; - Tx1559[] transactions; - TxReturn[] txReturns; - } - - struct RawEIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - RawReceipt[] receipts; - TxReturn[] txReturns; - uint256 timestamp; - RawTx1559[] transactions; - } - - struct RawReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - bytes blockNumber; - bytes data; - bytes logIndex; - bool removed; - bytes32[] topics; - bytes32 transactionHash; - bytes transactionIndex; - bytes transactionLogIndex; - } - - struct ReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - uint256 blockNumber; - bytes data; - uint256 logIndex; - bytes32[] topics; - uint256 transactionIndex; - uint256 transactionLogIndex; - bool removed; - } - - struct TxReturn { - string internalType; - string value; - } - - struct Account { - address addr; - uint256 key; - } - - enum AddressType { - Payable, - NonPayable, - ZeroAddress, - Precompile, - ForgeAddress - } - - // Checks that `addr` is not blacklisted by token contracts that have a blacklist. - function assumeNotBlacklisted(address token, address addr) internal view virtual { - // Nothing to check if `token` is not a contract. - uint256 tokenCodeSize; - assembly { - tokenCodeSize := extcodesize(token) - } - require(tokenCodeSize > 0, "StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); - - bool success; - bytes memory returnData; - - // 4-byte selector for `isBlacklisted(address)`, used by USDC. - (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr)); - vm.assume(!success || abi.decode(returnData, (bool)) == false); - - // 4-byte selector for `isBlackListed(address)`, used by USDT. - (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr)); - vm.assume(!success || abi.decode(returnData, (bool)) == false); - } - - // Checks that `addr` is not blacklisted by token contracts that have a blacklist. - // This is identical to `assumeNotBlacklisted(address,address)` but with a different name, for - // backwards compatibility, since this name was used in the original PR which already has - // a release. This function can be removed in a future release once we want a breaking change. - function assumeNoBlacklisted(address token, address addr) internal view virtual { - assumeNotBlacklisted(token, addr); - } - - function assumeAddressIsNot(address addr, AddressType addressType) internal virtual { - if (addressType == AddressType.Payable) { - assumeNotPayable(addr); - } else if (addressType == AddressType.NonPayable) { - assumePayable(addr); - } else if (addressType == AddressType.ZeroAddress) { - assumeNotZeroAddress(addr); - } else if (addressType == AddressType.Precompile) { - assumeNotPrecompile(addr); - } else if (addressType == AddressType.ForgeAddress) { - assumeNotForgeAddress(addr); - } - } - - function assumeAddressIsNot(address addr, AddressType addressType1, AddressType addressType2) internal virtual { - assumeAddressIsNot(addr, addressType1); - assumeAddressIsNot(addr, addressType2); - } - - function assumeAddressIsNot( - address addr, - AddressType addressType1, - AddressType addressType2, - AddressType addressType3 - ) internal virtual { - assumeAddressIsNot(addr, addressType1); - assumeAddressIsNot(addr, addressType2); - assumeAddressIsNot(addr, addressType3); - } - - function assumeAddressIsNot( - address addr, - AddressType addressType1, - AddressType addressType2, - AddressType addressType3, - AddressType addressType4 - ) internal virtual { - assumeAddressIsNot(addr, addressType1); - assumeAddressIsNot(addr, addressType2); - assumeAddressIsNot(addr, addressType3); - assumeAddressIsNot(addr, addressType4); - } - - // This function checks whether an address, `addr`, is payable. It works by sending 1 wei to - // `addr` and checking the `success` return value. - // NOTE: This function may result in state changes depending on the fallback/receive logic - // implemented by `addr`, which should be taken into account when this function is used. - function _isPayable(address addr) private returns (bool) { - require( - addr.balance < UINT256_MAX, - "StdCheats _isPayable(address): Balance equals max uint256, so it cannot receive any more funds" - ); - uint256 origBalanceTest = address(this).balance; - uint256 origBalanceAddr = address(addr).balance; - - vm.deal(address(this), 1); - (bool success,) = payable(addr).call{value: 1}(""); - - // reset balances - vm.deal(address(this), origBalanceTest); - vm.deal(addr, origBalanceAddr); - - return success; - } - - // NOTE: This function may result in state changes depending on the fallback/receive logic - // implemented by `addr`, which should be taken into account when this function is used. See the - // `_isPayable` method for more information. - function assumePayable(address addr) internal virtual { - vm.assume(_isPayable(addr)); - } - - function assumeNotPayable(address addr) internal virtual { - vm.assume(!_isPayable(addr)); - } - - function assumeNotZeroAddress(address addr) internal pure virtual { - vm.assume(addr != address(0)); - } - - function assumeNotPrecompile(address addr) internal pure virtual { - assumeNotPrecompile(addr, _pureChainId()); - } - - function assumeNotPrecompile(address addr, uint256 chainId) internal pure virtual { - // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific - // address), but the same rationale for excluding them applies so we include those too. - - // These are reserved by Ethereum and may be on all EVM-compatible chains. - vm.assume(addr < address(0x1) || addr > address(0xff)); - - // forgefmt: disable-start - if (chainId == 10 || chainId == 420) { - // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 - vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); - } else if (chainId == 42161 || chainId == 421613) { - // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains - vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); - } else if (chainId == 43114 || chainId == 43113) { - // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 - vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); - vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); - vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); - } - // forgefmt: disable-end - } - - function assumeNotForgeAddress(address addr) internal pure virtual { - // vm, console, and Create2Deployer addresses - vm.assume( - addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } - - function assumeUnusedAddress(address addr) internal view virtual { - uint256 size; - assembly { - size := extcodesize(addr) - } - vm.assume(size == 0); - - assumeNotPrecompile(addr); - assumeNotZeroAddress(addr); - assumeNotForgeAddress(addr); - } - - function readEIP1559ScriptArtifact(string memory path) - internal - view - virtual - returns (EIP1559ScriptArtifact memory) - { - string memory data = vm.readFile(path); - bytes memory parsedData = vm.parseJson(data); - RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); - EIP1559ScriptArtifact memory artifact; - artifact.libraries = rawArtifact.libraries; - artifact.path = rawArtifact.path; - artifact.timestamp = rawArtifact.timestamp; - artifact.pending = rawArtifact.pending; - artifact.txReturns = rawArtifact.txReturns; - artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); - artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); - return artifact; - } - - function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { - Tx1559[] memory txs = new Tx1559[](rawTxs.length); - for (uint256 i; i < rawTxs.length; i++) { - txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); - } - return txs; - } - - function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { - Tx1559 memory transaction; - transaction.arguments = rawTx.arguments; - transaction.contractName = rawTx.contractName; - transaction.functionSig = rawTx.functionSig; - transaction.hash = rawTx.hash; - transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); - transaction.opcode = rawTx.opcode; - return transaction; - } - - function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) - internal - pure - virtual - returns (Tx1559Detail memory) - { - Tx1559Detail memory txDetail; - txDetail.data = rawDetail.data; - txDetail.from = rawDetail.from; - txDetail.to = rawDetail.to; - txDetail.nonce = _bytesToUint(rawDetail.nonce); - txDetail.txType = _bytesToUint(rawDetail.txType); - txDetail.value = _bytesToUint(rawDetail.value); - txDetail.gas = _bytesToUint(rawDetail.gas); - txDetail.accessList = rawDetail.accessList; - return txDetail; - } - - function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); - RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); - return rawToConvertedEIPTx1559s(rawTxs); - } - - function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); - return rawToConvertedEIPTx1559(rawTx); - } - - // Analogous to readTransactions, but for receipts. - function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); - RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); - return rawToConvertedReceipts(rawReceipts); - } - - function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); - return rawToConvertedReceipt(rawReceipt); - } - - function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { - Receipt[] memory receipts = new Receipt[](rawReceipts.length); - for (uint256 i; i < rawReceipts.length; i++) { - receipts[i] = rawToConvertedReceipt(rawReceipts[i]); - } - return receipts; - } - - function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { - Receipt memory receipt; - receipt.blockHash = rawReceipt.blockHash; - receipt.to = rawReceipt.to; - receipt.from = rawReceipt.from; - receipt.contractAddress = rawReceipt.contractAddress; - receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); - receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); - receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); - receipt.status = _bytesToUint(rawReceipt.status); - receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); - receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); - receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); - receipt.logsBloom = rawReceipt.logsBloom; - receipt.transactionHash = rawReceipt.transactionHash; - return receipt; - } - - function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) - internal - pure - virtual - returns (ReceiptLog[] memory) - { - ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); - for (uint256 i; i < rawLogs.length; i++) { - logs[i].logAddress = rawLogs[i].logAddress; - logs[i].blockHash = rawLogs[i].blockHash; - logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); - logs[i].data = rawLogs[i].data; - logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); - logs[i].topics = rawLogs[i].topics; - logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); - logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); - logs[i].removed = rawLogs[i].removed; - } - return logs; - } - - // Deploy a contract by fetching the contract bytecode from - // the artifacts directory - // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` - function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); - } - - function deployCode(string memory what) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); - } - - /// @dev deploy contract with value on construction - function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); - } - - function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); - } - - // creates a labeled address and the corresponding private key - function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { - privateKey = uint256(keccak256(abi.encodePacked(name))); - addr = vm.addr(privateKey); - vm.label(addr, name); - } - - // creates a labeled address - function makeAddr(string memory name) internal virtual returns (address addr) { - (addr,) = makeAddrAndKey(name); - } - - // Destroys an account immediately, sending the balance to beneficiary. - // Destroying means: balance will be zero, code will be empty, and nonce will be 0 - // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce - // only after tx ends, this will run immediately. - function destroyAccount(address who, address beneficiary) internal virtual { - uint256 currBalance = who.balance; - vm.etch(who, abi.encode()); - vm.deal(who, 0); - vm.resetNonce(who); - - uint256 beneficiaryBalance = beneficiary.balance; - vm.deal(beneficiary, currBalance + beneficiaryBalance); - } - - // creates a struct containing both a labeled address and the corresponding private key - function makeAccount(string memory name) internal virtual returns (Account memory account) { - (account.addr, account.key) = makeAddrAndKey(name); - } - - function deriveRememberKey(string memory mnemonic, uint32 index) - internal - virtual - returns (address who, uint256 privateKey) - { - privateKey = vm.deriveKey(mnemonic, index); - who = vm.rememberKey(privateKey); - } - - function _bytesToUint(bytes memory b) private pure returns (uint256) { - require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - function isFork() internal view virtual returns (bool status) { - try vm.activeFork() { - status = true; - } catch (bytes memory) {} - } - - modifier skipWhenForking() { - if (!isFork()) { - _; - } - } - - modifier skipWhenNotForking() { - if (isFork()) { - _; - } - } - - modifier noGasMetering() { - vm.pauseGasMetering(); - // To prevent turning gas monitoring back on with nested functions that use this modifier, - // we check if gasMetering started in the off position. If it did, we don't want to turn - // it back on until we exit the top level function that used the modifier - // - // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. - // funcA will have `gasStartedOff` as false, funcB will have it as true, - // so we only turn metering back on at the end of the funcA - bool gasStartedOff = gasMeteringOff; - gasMeteringOff = true; - - _; - - // if gas metering was on when this modifier was called, turn it back on at the end - if (!gasStartedOff) { - gasMeteringOff = false; - vm.resumeGasMetering(); - } - } - - // We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no - // compiler warnings when accessing chain ID in any solidity version supported by forge-std. We - // can't simply access the chain ID in a normal view or pure function because the solc View Pure - // Checker changed `chainid` from pure to view in 0.8.0. - function _viewChainId() private view returns (uint256 chainId) { - // Assembly required since `block.chainid` was introduced in 0.8.0. - assembly { - chainId := chainid() - } - - address(this); // Silence warnings in older Solc versions. - } - - function _pureChainId() private pure returns (uint256 chainId) { - function() internal view returns (uint256) fnIn = _viewChainId; - function() internal pure returns (uint256) pureChainId; - assembly { - pureChainId := fnIn - } - chainId = pureChainId(); - } -} - -// Wrappers around cheatcodes to avoid footguns -abstract contract StdCheats is StdCheatsSafe { - using stdStorage for StdStorage; - - StdStorage private stdstore; - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; - - // Skip forward or rewind time by the specified number of seconds - function skip(uint256 time) internal virtual { - vm.warp(vm.getBlockTimestamp() + time); - } - - function rewind(uint256 time) internal virtual { - vm.warp(vm.getBlockTimestamp() - time); - } - - // Setup a prank from an address that has some ether - function hoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender); - } - - function hoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender); - } - - function hoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender, origin); - } - - function hoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender, origin); - } - - // Start perpetual prank from an address that has some ether - function startHoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender); - } - - function startHoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender); - } - - // Start perpetual prank from an address that has some ether - // tx.origin is set to the origin parameter - function startHoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender, origin); - } - - function startHoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender, origin); - } - - function changePrank(address msgSender) internal virtual { - console2_log_StdCheats("changePrank is deprecated. Please use vm.startPrank instead."); - vm.stopPrank(); - vm.startPrank(msgSender); - } - - function changePrank(address msgSender, address txOrigin) internal virtual { - vm.stopPrank(); - vm.startPrank(msgSender, txOrigin); - } - - // The same as Vm's `deal` - // Use the alternative signature for ERC20 tokens - function deal(address to, uint256 give) internal virtual { - vm.deal(to, give); - } - - // Set the balance of an account for any ERC20 token - // Use the alternative signature to update `totalSupply` - function deal(address token, address to, uint256 give) internal virtual { - deal(token, to, give, false); - } - - // Set the balance of an account for any ERC1155 token - // Use the alternative signature to update `totalSupply` - function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { - dealERC1155(token, to, id, give, false); - } - - function deal(address token, address to, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd)); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0x18160ddd).checked_write(totSup); - } - } - - function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id)); - require( - totSupData.length != 0, - "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." - ); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); - } - } - - function dealERC721(address token, address to, uint256 id) internal virtual { - // check if token id is already minted and the actual owner. - (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); - require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); - - // get owner current balance - (, bytes memory fromBalData) = - token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); - uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); - - // get new user current balance - (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); - uint256 toPrevBal = abi.decode(toBalData, (uint256)); - - // update balances - stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); - - // update owner - stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); - } - - function deployCodeTo(string memory what, address where) internal virtual { - deployCodeTo(what, "", 0, where); - } - - function deployCodeTo(string memory what, bytes memory args, address where) internal virtual { - deployCodeTo(what, args, 0, where); - } - - function deployCodeTo(string memory what, bytes memory args, uint256 value, address where) internal virtual { - bytes memory creationCode = vm.getCode(what); - vm.etch(where, abi.encodePacked(creationCode, args)); - (bool success, bytes memory runtimeBytecode) = where.call{value: value}(""); - require(success, "StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); - vm.etch(where, runtimeBytecode); - } - - // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. - function console2_log_StdCheats(string memory p0) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string)", p0)); - status; - } -} diff --git a/grouperBot/lib/forge-std/src/StdConfig.sol b/grouperBot/lib/forge-std/src/StdConfig.sol deleted file mode 100644 index 506ac34..0000000 --- a/grouperBot/lib/forge-std/src/StdConfig.sol +++ /dev/null @@ -1,612 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {VmSafe} from "./Vm.sol"; -import {Variable, Type, TypeKind, LibVariable} from "./LibVariable.sol"; - -/// @notice A contract that parses a toml configuration file and load its -/// variables into storage, automatically casting them, on deployment. -/// -/// @dev This contract assumes a toml structure where top-level keys -/// represent chain ids or aliases. Under each chain key, variables are -/// organized by type in separate sub-tables like `[.]`, where -/// type must be: `bool`, `address`, `bytes32`, `uint`, `ìnt`, `string`, or `bytes`. -/// -/// Supported format: -/// ``` -/// [mainnet] -/// endpoint_url = "${MAINNET_RPC}" -/// -/// [mainnet.bool] -/// is_live = true -/// -/// [mainnet.address] -/// weth = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" -/// whitelisted_admins = [ -/// "${MAINNET_ADMIN}", -/// "0x00000000000000000000000000000000deadbeef", -/// "0x000000000000000000000000000000c0ffeebabe" -/// ] -/// -/// [mainnet.uint] -/// important_number = 123 -/// ``` -contract StdConfig { - using LibVariable for Type; - using LibVariable for TypeKind; - - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - /// @dev Types: `bool`, `address`, `bytes32`, `uint`, `ìnt`, `string`, `bytes`. - uint8 private constant NUM_TYPES = 7; - - // -- ERRORS --------------------------------------------------------------- - - error AlreadyInitialized(string key); - error InvalidChainKey(string aliasOrId); - error ChainNotInitialized(uint256 chainId); - error UnableToParseVariable(string key); - error WriteToFileInForbiddenCtxt(); - - // -- STORAGE (CACHE FROM CONFIG FILE) ------------------------------------ - - /// @dev Path to the loaded TOML configuration file. - string private _filePath; - - /// @dev List of top-level keys found in the TOML file, assumed to be chain names/aliases. - string[] private _chainKeys; - - /// @dev Storage for the configured RPC URL for each chain. - mapping(uint256 => string) private _rpcOf; - - /// @dev Storage for values, organized by chain ID and variable key. - mapping(uint256 => mapping(string => bytes)) private _dataOf; - - /// @dev Type cache for runtime checking when casting. - mapping(uint256 => mapping(string => Type)) private _typeOf; - - /// @dev When enabled, `set` will always write updates back to the configuration file. - /// Can only be enabled in a scripting context to prevent file corruption from - /// concurrent I/O access, as tests run in parallel. - bool private _writeToFile; - - // -- CONSTRUCTOR ---------------------------------------------------------- - - /// @notice Reads the TOML file and iterates through each top-level key, which is - /// assumed to be a chain name or ID. For each chain, it caches its RPC - /// endpoint and all variables defined in typed sub-tables like `[.]`, - /// where type must be: `bool`, `address`, `uint`, `bytes32`, `string`, or `bytes`. - /// - /// The constructor attempts to parse each variable first as a single value, - /// and if that fails, as an array of that type. If a variable cannot be - /// parsed as either, the constructor will revert with an error. - /// - /// @param configFilePath: The local path to the TOML configuration file. - /// @param writeToFile: Whether to write updates back to the TOML file. Only for scripts. - constructor(string memory configFilePath, bool writeToFile) { - if (writeToFile && !vm.isContext(VmSafe.ForgeContext.ScriptGroup)) { - revert WriteToFileInForbiddenCtxt(); - } - - _filePath = configFilePath; - _writeToFile = writeToFile; - string memory content = vm.resolveEnv(vm.readFile(configFilePath)); - string[] memory chain_keys = vm.parseTomlKeys(content, "$"); - - // Cache the entire configuration to storage - for (uint256 i = 0; i < chain_keys.length; i++) { - string memory chain_key = chain_keys[i]; - // Ignore top-level keys that are not tables - if (vm.parseTomlKeys(content, string.concat("$.", chain_key)).length == 0) { - continue; - } - uint256 chainId = resolveChainId(chain_key); - _chainKeys.push(chain_key); - - // Cache the configure rpc endpoint for that chain. - // Falls back to `[rpc_endpoints]`. Panics if no rpc endpoint is configured. - try vm.parseTomlString(content, string.concat("$.", chain_key, ".endpoint_url")) returns (string memory url) - { - _rpcOf[chainId] = vm.resolveEnv(url); - } catch { - _rpcOf[chainId] = vm.resolveEnv(vm.rpcUrl(chain_key)); - } - - // Iterate through all the available `TypeKind`s (except `None`) to create the sub-section paths - for (uint8 t = 1; t <= NUM_TYPES; t++) { - TypeKind ty = TypeKind(t); - string memory typePath = string.concat("$.", chain_key, ".", ty.toTomlKey()); - - try vm.parseTomlKeys(content, typePath) returns (string[] memory keys) { - for (uint256 j = 0; j < keys.length; j++) { - string memory key = keys[j]; - if (_typeOf[chainId][key].kind == TypeKind.None) { - _loadAndCacheValue(content, string.concat(typePath, ".", key), chainId, key, ty); - } else { - revert AlreadyInitialized(key); - } - } - } catch {} // Section does not exist, ignore. - } - } - } - - function _loadAndCacheValue( - string memory content, - string memory path, - uint256 chainId, - string memory key, - TypeKind ty - ) private { - bool success = false; - if (ty == TypeKind.Bool) { - try vm.parseTomlBool(content, path) returns (bool val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Bool, false); - success = true; - } catch { - try vm.parseTomlBoolArray(content, path) returns (bool[] memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Bool, true); - success = true; - } catch {} - } - } else if (ty == TypeKind.Address) { - try vm.parseTomlAddress(content, path) returns (address val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Address, false); - success = true; - } catch { - try vm.parseTomlAddressArray(content, path) returns (address[] memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Address, true); - success = true; - } catch {} - } - } else if (ty == TypeKind.Bytes32) { - try vm.parseTomlBytes32(content, path) returns (bytes32 val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Bytes32, false); - success = true; - } catch { - try vm.parseTomlBytes32Array(content, path) returns (bytes32[] memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Bytes32, true); - success = true; - } catch {} - } - } else if (ty == TypeKind.Uint256) { - try vm.parseTomlUint(content, path) returns (uint256 val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Uint256, false); - success = true; - } catch { - try vm.parseTomlUintArray(content, path) returns (uint256[] memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Uint256, true); - success = true; - } catch {} - } - } else if (ty == TypeKind.Int256) { - try vm.parseTomlInt(content, path) returns (int256 val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Int256, false); - success = true; - } catch { - try vm.parseTomlIntArray(content, path) returns (int256[] memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Int256, true); - success = true; - } catch {} - } - } else if (ty == TypeKind.Bytes) { - try vm.parseTomlBytes(content, path) returns (bytes memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Bytes, false); - success = true; - } catch { - try vm.parseTomlBytesArray(content, path) returns (bytes[] memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.Bytes, true); - success = true; - } catch {} - } - } else if (ty == TypeKind.String) { - try vm.parseTomlString(content, path) returns (string memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.String, false); - success = true; - } catch { - try vm.parseTomlStringArray(content, path) returns (string[] memory val) { - _dataOf[chainId][key] = abi.encode(val); - _typeOf[chainId][key] = Type(TypeKind.String, true); - success = true; - } catch {} - } - } - - if (!success) { - revert UnableToParseVariable(key); - } - } - - // -- HELPER FUNCTIONS ----------------------------------------------------- - - /// @notice Enable or disable automatic writing to the TOML file on `set`. - /// Can only be enabled when scripting. - function writeUpdatesBackToFile(bool enabled) public { - if (enabled && !vm.isContext(VmSafe.ForgeContext.ScriptGroup)) { - revert WriteToFileInForbiddenCtxt(); - } - - _writeToFile = enabled; - } - - /// @notice Resolves a chain alias or a chain id string to its numerical chain id. - /// @param aliasOrId The string representing the chain alias (i.e. "mainnet") or a numerical ID (i.e. "1"). - /// @return The numerical chain ID. - /// @dev It first attempts to parse the input as a number. If that fails, it uses `vm.getChain` to resolve a named alias. - /// Reverts if the alias is not valid or not a number. - function resolveChainId(string memory aliasOrId) public view returns (uint256) { - try vm.parseUint(aliasOrId) returns (uint256 chainId) { - return chainId; - } catch { - try vm.getChain(aliasOrId) returns (VmSafe.Chain memory chainInfo) { - return chainInfo.chainId; - } catch { - revert InvalidChainKey(aliasOrId); - } - } - } - - /// @dev Retrieves the chain key/alias from the configuration based on the chain ID. - function _getChainKeyFromId(uint256 chainId) private view returns (string memory) { - for (uint256 i = 0; i < _chainKeys.length; i++) { - if (resolveChainId(_chainKeys[i]) == chainId) { - return _chainKeys[i]; - } - } - revert ChainNotInitialized(chainId); - } - - /// @dev Ensures type consistency when setting a value - prevents changing types unless uninitialized. - /// Updates type only when the previous type was `None`. - function _ensureTypeConsistency(uint256 chainId, string memory key, Type memory ty) private { - Type memory current = _typeOf[chainId][key]; - - if (current.kind == TypeKind.None) { - _typeOf[chainId][key] = ty; - } else { - current.assertEq(ty); - } - } - - /// @dev Wraps a string in double quotes for JSON compatibility. - function _quote(string memory s) private pure returns (string memory) { - return string.concat('"', s, '"'); - } - - /// @dev Writes a JSON-formatted value to a specific key in the TOML file. - /// @param chainId The chain id to write under. - /// @param ty The type category ('bool', 'address', 'uint', 'bytes32', 'string', or 'bytes'). - /// @param key The variable key name. - /// @param jsonValue The JSON-formatted value to write. - function _writeToToml(uint256 chainId, string memory ty, string memory key, string memory jsonValue) private { - string memory chainKey = _getChainKeyFromId(chainId); - string memory valueKey = string.concat("$.", chainKey, ".", ty, ".", key); - vm.writeToml(jsonValue, _filePath, valueKey); - } - - // -- GETTER FUNCTIONS ----------------------------------------------------- - - /// @dev Reads a variable for a given chain id and key, and returns it in a generic container. - /// The caller should use `LibVariable` to safely coerce the type. - /// Example: `uint256 myVar = config.get("my_key").toUint256();` - /// - /// @param chain_id The chain ID to read from. - /// @param key The key of the variable to retrieve. - /// @return `Variable` struct containing the type and the ABI-encoded value. - function get(uint256 chain_id, string memory key) public view returns (Variable memory) { - return Variable(_typeOf[chain_id][key], _dataOf[chain_id][key]); - } - - /// @dev Reads a variable for the current chain and a given key, and returns it in a generic container. - /// The caller should use `LibVariable` to safely coerce the type. - /// Example: `uint256 myVar = config.get("my_key").toUint256();` - /// - /// @param key The key of the variable to retrieve. - /// @return `Variable` struct containing the type and the ABI-encoded value. - function get(string memory key) public view returns (Variable memory) { - return get(vm.getChainId(), key); - } - - /// @notice Returns the numerical chain ids for all configured chains. - function getChainIds() public view returns (uint256[] memory) { - string[] memory keys = _chainKeys; - - uint256[] memory ids = new uint256[](keys.length); - for (uint256 i = 0; i < keys.length; i++) { - ids[i] = resolveChainId(keys[i]); - } - - return ids; - } - - /// @notice Reads the RPC URL for a specific chain id. - function getRpcUrl(uint256 chainId) public view returns (string memory) { - return _rpcOf[chainId]; - } - - /// @notice Reads the RPC URL for the current chain. - function getRpcUrl() public view returns (string memory) { - return _rpcOf[vm.getChainId()]; - } - - // -- SETTER FUNCTIONS (SINGLE VALUES) ------------------------------------- - - /// @notice Sets a boolean value for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, bool value) public { - Type memory ty = Type(TypeKind.Bool, false); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); - } - - /// @notice Sets a boolean value for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, bool value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets an address value for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, address value) public { - Type memory ty = Type(TypeKind.Address, false); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); - } - - /// @notice Sets an address value for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, address value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a bytes32 value for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, bytes32 value) public { - Type memory ty = Type(TypeKind.Bytes32, false); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); - } - - /// @notice Sets a bytes32 value for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, bytes32 value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a uint256 value for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, uint256 value) public { - Type memory ty = Type(TypeKind.Uint256, false); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); - } - - /// @notice Sets a uint256 value for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, uint256 value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets an int256 value for a given key and chain ID. - function set(uint256 chainId, string memory key, int256 value) public { - Type memory ty = Type(TypeKind.Int256, false); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); - } - - /// @notice Sets an int256 value for a given key on the current chain. - function set(string memory key, int256 value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a string value for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, string memory value) public { - Type memory ty = Type(TypeKind.String, false); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(value)); - } - - /// @notice Sets a string value for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, string memory value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a bytes value for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, bytes memory value) public { - Type memory ty = Type(TypeKind.Bytes, false); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); - } - - /// @notice Sets a bytes value for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, bytes memory value) public { - set(vm.getChainId(), key, value); - } - - // -- SETTER FUNCTIONS (ARRAYS) -------------------------------------------- - - /// @notice Sets a boolean array for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, bool[] memory value) public { - Type memory ty = Type(TypeKind.Bool, true); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) { - string memory json = "["; - for (uint256 i = 0; i < value.length; i++) { - json = string.concat(json, vm.toString(value[i])); - if (i < value.length - 1) json = string.concat(json, ","); - } - json = string.concat(json, "]"); - _writeToToml(chainId, ty.kind.toTomlKey(), key, json); - } - } - - /// @notice Sets a boolean array for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, bool[] memory value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets an address array for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, address[] memory value) public { - Type memory ty = Type(TypeKind.Address, true); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) { - string memory json = "["; - for (uint256 i = 0; i < value.length; i++) { - json = string.concat(json, _quote(vm.toString(value[i]))); - if (i < value.length - 1) json = string.concat(json, ","); - } - json = string.concat(json, "]"); - _writeToToml(chainId, ty.kind.toTomlKey(), key, json); - } - } - - /// @notice Sets an address array for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, address[] memory value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a bytes32 array for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, bytes32[] memory value) public { - Type memory ty = Type(TypeKind.Bytes32, true); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) { - string memory json = "["; - for (uint256 i = 0; i < value.length; i++) { - json = string.concat(json, _quote(vm.toString(value[i]))); - if (i < value.length - 1) json = string.concat(json, ","); - } - json = string.concat(json, "]"); - _writeToToml(chainId, ty.kind.toTomlKey(), key, json); - } - } - - /// @notice Sets a bytes32 array for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, bytes32[] memory value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a uint256 array for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, uint256[] memory value) public { - Type memory ty = Type(TypeKind.Uint256, true); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) { - string memory json = "["; - for (uint256 i = 0; i < value.length; i++) { - json = string.concat(json, vm.toString(value[i])); - if (i < value.length - 1) json = string.concat(json, ","); - } - json = string.concat(json, "]"); - _writeToToml(chainId, ty.kind.toTomlKey(), key, json); - } - } - - /// @notice Sets a uint256 array for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, uint256[] memory value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a int256 array for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, int256[] memory value) public { - Type memory ty = Type(TypeKind.Int256, true); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) { - string memory json = "["; - for (uint256 i = 0; i < value.length; i++) { - json = string.concat(json, vm.toString(value[i])); - if (i < value.length - 1) json = string.concat(json, ","); - } - json = string.concat(json, "]"); - _writeToToml(chainId, ty.kind.toTomlKey(), key, json); - } - } - - /// @notice Sets a int256 array for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, int256[] memory value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a string array for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, string[] memory value) public { - Type memory ty = Type(TypeKind.String, true); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) { - string memory json = "["; - for (uint256 i = 0; i < value.length; i++) { - json = string.concat(json, _quote(value[i])); - if (i < value.length - 1) json = string.concat(json, ","); - } - json = string.concat(json, "]"); - _writeToToml(chainId, ty.kind.toTomlKey(), key, json); - } - } - - /// @notice Sets a string array for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, string[] memory value) public { - set(vm.getChainId(), key, value); - } - - /// @notice Sets a bytes array for a given key and chain ID. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(uint256 chainId, string memory key, bytes[] memory value) public { - Type memory ty = Type(TypeKind.Bytes, true); - _ensureTypeConsistency(chainId, key, ty); - _dataOf[chainId][key] = abi.encode(value); - if (_writeToFile) { - string memory json = "["; - for (uint256 i = 0; i < value.length; i++) { - json = string.concat(json, _quote(vm.toString(value[i]))); - if (i < value.length - 1) json = string.concat(json, ","); - } - json = string.concat(json, "]"); - _writeToToml(chainId, ty.kind.toTomlKey(), key, json); - } - } - - /// @notice Sets a bytes array for a given key on the current chain. - /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. - function set(string memory key, bytes[] memory value) public { - set(vm.getChainId(), key, value); - } -} diff --git a/grouperBot/lib/forge-std/src/StdConstants.sol b/grouperBot/lib/forge-std/src/StdConstants.sol deleted file mode 100644 index 2047d2b..0000000 --- a/grouperBot/lib/forge-std/src/StdConstants.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {IMulticall3} from "./interfaces/IMulticall3.sol"; -import {Vm} from "./Vm.sol"; - -library StdConstants { - /// @dev Cheat code address. - /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`. - Vm internal constant VM = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - /// @dev console.sol and console2.sol work by executing a staticcall to this address. - /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`. - address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; - /// @dev Used when deploying with create2. - /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy. - address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - /// @dev The default address for tx.origin and msg.sender. - /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`. - address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; - /// @dev The address of the first contract `CREATE`d by a running test contract. - /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. - /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`. - address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; - /// @dev Deterministic deployment address of the Multicall3 contract. - /// Taken from https://www.multicall3.com. - IMulticall3 internal constant MULTICALL3_ADDRESS = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); - /// @dev The order of the secp256k1 curve. - uint256 internal constant SECP256K1_ORDER = - 115792089237316195423570985008687907852837564279074904382605163141518161494337; -} diff --git a/grouperBot/lib/forge-std/src/StdError.sol b/grouperBot/lib/forge-std/src/StdError.sol deleted file mode 100644 index a302191..0000000 --- a/grouperBot/lib/forge-std/src/StdError.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test -pragma solidity >=0.6.2 <0.9.0; - -library stdError { - bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); - bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); - bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); - bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); - bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); - bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); - bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); - bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); - bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); -} diff --git a/grouperBot/lib/forge-std/src/StdInvariant.sol b/grouperBot/lib/forge-std/src/StdInvariant.sol deleted file mode 100644 index 056db98..0000000 --- a/grouperBot/lib/forge-std/src/StdInvariant.sol +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -abstract contract StdInvariant { - struct FuzzSelector { - address addr; - bytes4[] selectors; - } - - struct FuzzArtifactSelector { - string artifact; - bytes4[] selectors; - } - - struct FuzzInterface { - address addr; - string[] artifacts; - } - - address[] private _excludedContracts; - address[] private _excludedSenders; - address[] private _targetedContracts; - address[] private _targetedSenders; - - string[] private _excludedArtifacts; - string[] private _targetedArtifacts; - - FuzzArtifactSelector[] private _targetedArtifactSelectors; - - FuzzSelector[] private _excludedSelectors; - FuzzSelector[] private _targetedSelectors; - - FuzzInterface[] private _targetedInterfaces; - - // Functions for users: - // These are intended to be called in tests. - - function excludeContract(address newExcludedContract_) internal { - _excludedContracts.push(newExcludedContract_); - } - - function excludeSelector(FuzzSelector memory newExcludedSelector_) internal { - _excludedSelectors.push(newExcludedSelector_); - } - - function excludeSender(address newExcludedSender_) internal { - _excludedSenders.push(newExcludedSender_); - } - - function excludeArtifact(string memory newExcludedArtifact_) internal { - _excludedArtifacts.push(newExcludedArtifact_); - } - - function targetArtifact(string memory newTargetedArtifact_) internal { - _targetedArtifacts.push(newTargetedArtifact_); - } - - function targetArtifactSelector(FuzzArtifactSelector memory newTargetedArtifactSelector_) internal { - _targetedArtifactSelectors.push(newTargetedArtifactSelector_); - } - - function targetContract(address newTargetedContract_) internal { - _targetedContracts.push(newTargetedContract_); - } - - function targetSelector(FuzzSelector memory newTargetedSelector_) internal { - _targetedSelectors.push(newTargetedSelector_); - } - - function targetSender(address newTargetedSender_) internal { - _targetedSenders.push(newTargetedSender_); - } - - function targetInterface(FuzzInterface memory newTargetedInterface_) internal { - _targetedInterfaces.push(newTargetedInterface_); - } - - // Functions for forge: - // These are called by forge to run invariant tests and don't need to be called in tests. - - function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { - excludedArtifacts_ = _excludedArtifacts; - } - - function excludeContracts() public view returns (address[] memory excludedContracts_) { - excludedContracts_ = _excludedContracts; - } - - function excludeSelectors() public view returns (FuzzSelector[] memory excludedSelectors_) { - excludedSelectors_ = _excludedSelectors; - } - - function excludeSenders() public view returns (address[] memory excludedSenders_) { - excludedSenders_ = _excludedSenders; - } - - function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { - targetedArtifacts_ = _targetedArtifacts; - } - - function targetArtifactSelectors() public view returns (FuzzArtifactSelector[] memory targetedArtifactSelectors_) { - targetedArtifactSelectors_ = _targetedArtifactSelectors; - } - - function targetContracts() public view returns (address[] memory targetedContracts_) { - targetedContracts_ = _targetedContracts; - } - - function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { - targetedSelectors_ = _targetedSelectors; - } - - function targetSenders() public view returns (address[] memory targetedSenders_) { - targetedSenders_ = _targetedSenders; - } - - function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) { - targetedInterfaces_ = _targetedInterfaces; - } -} diff --git a/grouperBot/lib/forge-std/src/StdJson.sol b/grouperBot/lib/forge-std/src/StdJson.sol deleted file mode 100644 index 2a033c0..0000000 --- a/grouperBot/lib/forge-std/src/StdJson.sol +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -// Helpers for parsing and writing JSON files -// To parse: -// ``` -// using stdJson for string; -// string memory json = vm.readFile(""); -// json.readUint(""); -// ``` -// To write: -// ``` -// using stdJson for string; -// string memory json = "json"; -// json.serialize("a", uint256(123)); -// string memory semiFinal = json.serialize("b", string("test")); -// string memory finalJson = json.serialize("c", semiFinal); -// finalJson.write(""); -// ``` - -library stdJson { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function keyExists(string memory json, string memory key) internal view returns (bool) { - return vm.keyExistsJson(json, key); - } - - function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { - return vm.parseJson(json, key); - } - - function readUint(string memory json, string memory key) internal pure returns (uint256) { - return vm.parseJsonUint(json, key); - } - - function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) { - return vm.parseJsonUintArray(json, key); - } - - function readInt(string memory json, string memory key) internal pure returns (int256) { - return vm.parseJsonInt(json, key); - } - - function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) { - return vm.parseJsonIntArray(json, key); - } - - function readBytes32(string memory json, string memory key) internal pure returns (bytes32) { - return vm.parseJsonBytes32(json, key); - } - - function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) { - return vm.parseJsonBytes32Array(json, key); - } - - function readString(string memory json, string memory key) internal pure returns (string memory) { - return vm.parseJsonString(json, key); - } - - function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) { - return vm.parseJsonStringArray(json, key); - } - - function readAddress(string memory json, string memory key) internal pure returns (address) { - return vm.parseJsonAddress(json, key); - } - - function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) { - return vm.parseJsonAddressArray(json, key); - } - - function readBool(string memory json, string memory key) internal pure returns (bool) { - return vm.parseJsonBool(json, key); - } - - function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) { - return vm.parseJsonBoolArray(json, key); - } - - function readBytes(string memory json, string memory key) internal pure returns (bytes memory) { - return vm.parseJsonBytes(json, key); - } - - function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) { - return vm.parseJsonBytesArray(json, key); - } - - function readUintOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) { - return keyExists(json, key) ? readUint(json, key) : defaultValue; - } - - function readUintArrayOr(string memory json, string memory key, uint256[] memory defaultValue) - internal - view - returns (uint256[] memory) - { - return keyExists(json, key) ? readUintArray(json, key) : defaultValue; - } - - function readIntOr(string memory json, string memory key, int256 defaultValue) internal view returns (int256) { - return keyExists(json, key) ? readInt(json, key) : defaultValue; - } - - function readIntArrayOr(string memory json, string memory key, int256[] memory defaultValue) - internal - view - returns (int256[] memory) - { - return keyExists(json, key) ? readIntArray(json, key) : defaultValue; - } - - function readBytes32Or(string memory json, string memory key, bytes32 defaultValue) - internal - view - returns (bytes32) - { - return keyExists(json, key) ? readBytes32(json, key) : defaultValue; - } - - function readBytes32ArrayOr(string memory json, string memory key, bytes32[] memory defaultValue) - internal - view - returns (bytes32[] memory) - { - return keyExists(json, key) ? readBytes32Array(json, key) : defaultValue; - } - - function readStringOr(string memory json, string memory key, string memory defaultValue) - internal - view - returns (string memory) - { - return keyExists(json, key) ? readString(json, key) : defaultValue; - } - - function readStringArrayOr(string memory json, string memory key, string[] memory defaultValue) - internal - view - returns (string[] memory) - { - return keyExists(json, key) ? readStringArray(json, key) : defaultValue; - } - - function readAddressOr(string memory json, string memory key, address defaultValue) - internal - view - returns (address) - { - return keyExists(json, key) ? readAddress(json, key) : defaultValue; - } - - function readAddressArrayOr(string memory json, string memory key, address[] memory defaultValue) - internal - view - returns (address[] memory) - { - return keyExists(json, key) ? readAddressArray(json, key) : defaultValue; - } - - function readBoolOr(string memory json, string memory key, bool defaultValue) internal view returns (bool) { - return keyExists(json, key) ? readBool(json, key) : defaultValue; - } - - function readBoolArrayOr(string memory json, string memory key, bool[] memory defaultValue) - internal - view - returns (bool[] memory) - { - return keyExists(json, key) ? readBoolArray(json, key) : defaultValue; - } - - function readBytesOr(string memory json, string memory key, bytes memory defaultValue) - internal - view - returns (bytes memory) - { - return keyExists(json, key) ? readBytes(json, key) : defaultValue; - } - - function readBytesArrayOr(string memory json, string memory key, bytes[] memory defaultValue) - internal - view - returns (bytes[] memory) - { - return keyExists(json, key) ? readBytesArray(json, key) : defaultValue; - } - - function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { - return vm.serializeJson(jsonKey, rootObject); - } - - function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bool[] memory value) - internal - returns (string memory) - { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256[] memory value) - internal - returns (string memory) - { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256[] memory value) - internal - returns (string memory) - { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address[] memory value) - internal - returns (string memory) - { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string[] memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function write(string memory jsonKey, string memory path) internal { - vm.writeJson(jsonKey, path); - } - - function write(string memory jsonKey, string memory path, string memory valueKey) internal { - vm.writeJson(jsonKey, path, valueKey); - } -} diff --git a/grouperBot/lib/forge-std/src/StdMath.sol b/grouperBot/lib/forge-std/src/StdMath.sol deleted file mode 100644 index 459523b..0000000 --- a/grouperBot/lib/forge-std/src/StdMath.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -library stdMath { - int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; - - function abs(int256 a) internal pure returns (uint256) { - // Required or it will fail when `a = type(int256).min` - if (a == INT256_MIN) { - return 57896044618658097711785492504343953926634992332820282019728792003956564819968; - } - - return uint256(a > 0 ? a : -a); - } - - function delta(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a - b : b - a; - } - - function delta(int256 a, int256 b) internal pure returns (uint256) { - // a and b are of the same sign - // this works thanks to two's complement, the left-most bit is the sign bit - if ((a ^ b) > -1) { - return delta(abs(a), abs(b)); - } - - // a and b are of opposite signs - return abs(a) + abs(b); - } - - function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - - return absDelta * 1e18 / b; - } - - function percentDelta(int256 a, int256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - uint256 absB = abs(b); - - return absDelta * 1e18 / absB; - } -} diff --git a/grouperBot/lib/forge-std/src/StdStorage.sol b/grouperBot/lib/forge-std/src/StdStorage.sol deleted file mode 100644 index 1627af7..0000000 --- a/grouperBot/lib/forge-std/src/StdStorage.sol +++ /dev/null @@ -1,473 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {Vm} from "./Vm.sol"; - -struct FindData { - uint256 slot; - uint256 offsetLeft; - uint256 offsetRight; - bool found; -} - -struct StdStorage { - mapping(address => mapping(bytes4 => mapping(bytes32 => FindData))) finds; - bytes32[] _keys; - bytes4 _sig; - uint256 _depth; - address _target; - bytes32 _set; - bool _enable_packed_slots; - bytes _calldata; -} - -library stdStorageSafe { - event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); - event WARNING_UninitedSlot(address who, uint256 slot); - - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return bytes4(keccak256(bytes(sigStr))); - } - - function getCallParams(StdStorage storage self) internal view returns (bytes memory) { - if (self._calldata.length == 0) { - return flatten(self._keys); - } else { - return self._calldata; - } - } - - // Calls target contract with configured parameters - function callTarget(StdStorage storage self) internal view returns (bool, bytes32) { - bytes memory cd = abi.encodePacked(self._sig, getCallParams(self)); - (bool success, bytes memory rdat) = self._target.staticcall(cd); - bytes32 result = bytesToBytes32(rdat, 32 * self._depth); - - return (success, result); - } - - // Tries mutating slot value to determine if the targeted value is stored in it. - // If current value is 0, then we are setting slot value to type(uint256).max - // Otherwise, we set it to 0. That way, return value should always be affected. - function checkSlotMutatesCall(StdStorage storage self, bytes32 slot) internal returns (bool) { - bytes32 prevSlotValue = vm.load(self._target, slot); - (bool success, bytes32 prevReturnValue) = callTarget(self); - - bytes32 testVal = prevReturnValue == bytes32(0) ? bytes32(UINT256_MAX) : bytes32(0); - vm.store(self._target, slot, testVal); - - (, bytes32 newReturnValue) = callTarget(self); - - vm.store(self._target, slot, prevSlotValue); - - return (success && (prevReturnValue != newReturnValue)); - } - - // Tries setting one of the bits in slot to 1 until return value changes. - // Index of resulted bit is an offset packed slot has from left/right side - function findOffset(StdStorage storage self, bytes32 slot, bool left) internal returns (bool, uint256) { - for (uint256 offset = 0; offset < 256; offset++) { - uint256 valueToPut = left ? (1 << (255 - offset)) : (1 << offset); - vm.store(self._target, slot, bytes32(valueToPut)); - - (bool success, bytes32 data) = callTarget(self); - - if (success && (uint256(data) > 0)) { - return (true, offset); - } - } - return (false, 0); - } - - function findOffsets(StdStorage storage self, bytes32 slot) internal returns (bool, uint256, uint256) { - bytes32 prevSlotValue = vm.load(self._target, slot); - - (bool foundLeft, uint256 offsetLeft) = findOffset(self, slot, true); - (bool foundRight, uint256 offsetRight) = findOffset(self, slot, false); - - // `findOffset` may mutate slot value, so we are setting it to initial value - vm.store(self._target, slot, prevSlotValue); - return (foundLeft && foundRight, offsetLeft, offsetRight); - } - - function find(StdStorage storage self) internal returns (FindData storage) { - return find(self, true); - } - - /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against - // slot complexity: - // if flat, will be bytes32(uint256(uint)); - // if map, will be keccak256(abi.encode(key, uint(slot))); - // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); - // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); - function find(StdStorage storage self, bool _clear) internal returns (FindData storage) { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes memory params = getCallParams(self); - - // calldata to test against - if (self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { - if (_clear) { - clear(self); - } - return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; - } - vm.record(); - (, bytes32 callResult) = callTarget(self); - (bytes32[] memory reads,) = vm.accesses(address(who)); - - if (reads.length == 0) { - revert("stdStorage find(StdStorage): No storage use detected for target."); - } else { - for (uint256 i = reads.length; --i >= 0;) { - bytes32 prev = vm.load(who, reads[i]); - if (prev == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[i])); - } - - if (!checkSlotMutatesCall(self, reads[i])) { - continue; - } - - (uint256 offsetLeft, uint256 offsetRight) = (0, 0); - - if (self._enable_packed_slots) { - bool found; - (found, offsetLeft, offsetRight) = findOffsets(self, reads[i]); - if (!found) { - continue; - } - } - - // Check that value between found offsets is equal to the current call result - uint256 curVal = (uint256(prev) & getMaskByOffsets(offsetLeft, offsetRight)) >> offsetRight; - - if (uint256(callResult) != curVal) { - continue; - } - - emit SlotFound(who, fsig, keccak256(abi.encodePacked(params, field_depth)), uint256(reads[i])); - self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))] = - FindData(uint256(reads[i]), offsetLeft, offsetRight, true); - break; - } - } - - require( - self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found, - "stdStorage find(StdStorage): Slot(s) not found." - ); - - if (_clear) { - clear(self); - } - return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - self._target = _target; - return self; - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - self._sig = _sig; - return self; - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - self._sig = sigs(_sig); - return self; - } - - function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { - self._calldata = _calldata; - return self; - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - self._keys.push(bytes32(uint256(uint160(who)))); - return self; - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - self._keys.push(bytes32(amt)); - return self; - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - self._keys.push(key); - return self; - } - - function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { - self._enable_packed_slots = true; - return self; - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - self._depth = _depth; - return self; - } - - function read(StdStorage storage self) private returns (bytes memory) { - FindData storage data = find(self, false); - uint256 mask = getMaskByOffsets(data.offsetLeft, data.offsetRight); - uint256 value = (uint256(vm.load(self._target, bytes32(data.slot))) & mask) >> data.offsetRight; - clear(self); - return abi.encode(value); - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return abi.decode(read(self), (bytes32)); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - int256 v = read_int(self); - if (v == 0) return false; - if (v == 1) return true; - revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - } - - function read_address(StdStorage storage self) internal returns (address) { - return abi.decode(read(self), (address)); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return abi.decode(read(self), (uint256)); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return abi.decode(read(self), (int256)); - } - - function parent(StdStorage storage self) internal returns (uint256, bytes32) { - address who = self._target; - uint256 field_depth = self._depth; - vm.startMappingRecording(); - uint256 child = find(self, true).slot - field_depth; - (bool found, bytes32 key, bytes32 parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); - if (!found) { - revert( - "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." - ); - } - return (uint256(parent_slot), key); - } - - function root(StdStorage storage self) internal returns (uint256) { - address who = self._target; - uint256 field_depth = self._depth; - vm.startMappingRecording(); - uint256 child = find(self, true).slot - field_depth; - bool found; - bytes32 root_slot; - bytes32 parent_slot; - (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); - if (!found) { - revert( - "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." - ); - } - while (found) { - root_slot = parent_slot; - (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(root_slot)); - } - return uint256(root_slot); - } - - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } - - function clear(StdStorage storage self) internal { - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - delete self._enable_packed_slots; - delete self._calldata; - } - - // Returns mask which contains non-zero bits for values between `offsetLeft` and `offsetRight` - // (slotValue & mask) >> offsetRight will be the value of the given packed variable - function getMaskByOffsets(uint256 offsetLeft, uint256 offsetRight) internal pure returns (uint256 mask) { - // mask = ((1 << (256 - (offsetRight + offsetLeft))) - 1) << offsetRight; - // using assembly because (1 << 256) causes overflow - assembly { - mask := shl(offsetRight, sub(shl(sub(256, add(offsetRight, offsetLeft)), 1), 1)) - } - } - - // Returns slot value with updated packed variable. - function getUpdatedSlotValue(bytes32 curValue, uint256 varValue, uint256 offsetLeft, uint256 offsetRight) - internal - pure - returns (bytes32 newValue) - { - return bytes32((uint256(curValue) & ~getMaskByOffsets(offsetLeft, offsetRight)) | (varValue << offsetRight)); - } -} - -library stdStorage { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return stdStorageSafe.sigs(sigStr); - } - - function find(StdStorage storage self) internal returns (uint256) { - return find(self, true); - } - - function find(StdStorage storage self, bool _clear) internal returns (uint256) { - return stdStorageSafe.find(self, _clear).slot; - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - return stdStorageSafe.target(self, _target); - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, who); - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, amt); - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, key); - } - - function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { - return stdStorageSafe.with_calldata(self, _calldata); - } - - function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { - return stdStorageSafe.enable_packed_slots(self); - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - return stdStorageSafe.depth(self, _depth); - } - - function clear(StdStorage storage self) internal { - stdStorageSafe.clear(self); - } - - function checked_write(StdStorage storage self, address who) internal { - checked_write(self, bytes32(uint256(uint160(who)))); - } - - function checked_write(StdStorage storage self, uint256 amt) internal { - checked_write(self, bytes32(amt)); - } - - function checked_write_int(StdStorage storage self, int256 val) internal { - checked_write(self, bytes32(uint256(val))); - } - - function checked_write(StdStorage storage self, bool write) internal { - bytes32 t; - /// @solidity memory-safe-assembly - assembly { - t := write - } - checked_write(self, t); - } - - function checked_write(StdStorage storage self, bytes32 set) internal { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes memory params = stdStorageSafe.getCallParams(self); - - if (!self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { - find(self, false); - } - FindData storage data = self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; - if ((data.offsetLeft + data.offsetRight) > 0) { - uint256 maxVal = 2 ** (256 - (data.offsetLeft + data.offsetRight)); - require( - uint256(set) < maxVal, - string( - abi.encodePacked( - "stdStorage find(StdStorage): Packed slot. We can't fit value greater than ", - vm.toString(maxVal) - ) - ) - ); - } - bytes32 curVal = vm.load(who, bytes32(data.slot)); - bytes32 valToSet = stdStorageSafe.getUpdatedSlotValue(curVal, uint256(set), data.offsetLeft, data.offsetRight); - - vm.store(who, bytes32(data.slot), valToSet); - - (bool success, bytes32 callResult) = stdStorageSafe.callTarget(self); - - if (!success || callResult != set) { - vm.store(who, bytes32(data.slot), curVal); - revert("stdStorage find(StdStorage): Failed to write value."); - } - clear(self); - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return stdStorageSafe.read_bytes32(self); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - return stdStorageSafe.read_bool(self); - } - - function read_address(StdStorage storage self) internal returns (address) { - return stdStorageSafe.read_address(self); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.read_uint(self); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return stdStorageSafe.read_int(self); - } - - function parent(StdStorage storage self) internal returns (uint256, bytes32) { - return stdStorageSafe.parent(self); - } - - function root(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.root(self); - } -} diff --git a/grouperBot/lib/forge-std/src/StdStyle.sol b/grouperBot/lib/forge-std/src/StdStyle.sol deleted file mode 100644 index d371e0c..0000000 --- a/grouperBot/lib/forge-std/src/StdStyle.sol +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -import {VmSafe} from "./Vm.sol"; - -library StdStyle { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - string constant RED = "\u001b[91m"; - string constant GREEN = "\u001b[92m"; - string constant YELLOW = "\u001b[93m"; - string constant BLUE = "\u001b[94m"; - string constant MAGENTA = "\u001b[95m"; - string constant CYAN = "\u001b[96m"; - string constant BOLD = "\u001b[1m"; - string constant DIM = "\u001b[2m"; - string constant ITALIC = "\u001b[3m"; - string constant UNDERLINE = "\u001b[4m"; - string constant INVERSE = "\u001b[7m"; - string constant RESET = "\u001b[0m"; - - function styleConcat(string memory style, string memory self) private pure returns (string memory) { - return string(abi.encodePacked(style, self, RESET)); - } - - function red(string memory self) internal pure returns (string memory) { - return styleConcat(RED, self); - } - - function red(uint256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(int256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(address self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(bool self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes(bytes memory self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes32(bytes32 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function green(string memory self) internal pure returns (string memory) { - return styleConcat(GREEN, self); - } - - function green(uint256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(int256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(address self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(bool self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes(bytes memory self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes32(bytes32 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function yellow(string memory self) internal pure returns (string memory) { - return styleConcat(YELLOW, self); - } - - function yellow(uint256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(int256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(address self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(bool self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes(bytes memory self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes32(bytes32 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function blue(string memory self) internal pure returns (string memory) { - return styleConcat(BLUE, self); - } - - function blue(uint256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(int256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(address self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(bool self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes(bytes memory self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes32(bytes32 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function magenta(string memory self) internal pure returns (string memory) { - return styleConcat(MAGENTA, self); - } - - function magenta(uint256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(int256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(address self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(bool self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes(bytes memory self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes32(bytes32 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function cyan(string memory self) internal pure returns (string memory) { - return styleConcat(CYAN, self); - } - - function cyan(uint256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(int256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(address self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(bool self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes(bytes memory self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes32(bytes32 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function bold(string memory self) internal pure returns (string memory) { - return styleConcat(BOLD, self); - } - - function bold(uint256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(int256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(address self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(bool self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes(bytes memory self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes32(bytes32 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function dim(string memory self) internal pure returns (string memory) { - return styleConcat(DIM, self); - } - - function dim(uint256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(int256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(address self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(bool self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes(bytes memory self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes32(bytes32 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function italic(string memory self) internal pure returns (string memory) { - return styleConcat(ITALIC, self); - } - - function italic(uint256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(int256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(address self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(bool self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes(bytes memory self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes32(bytes32 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function underline(string memory self) internal pure returns (string memory) { - return styleConcat(UNDERLINE, self); - } - - function underline(uint256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(int256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(address self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(bool self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes(bytes memory self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes32(bytes32 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function inverse(string memory self) internal pure returns (string memory) { - return styleConcat(INVERSE, self); - } - - function inverse(uint256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(int256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(address self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(bool self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes(bytes memory self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes32(bytes32 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } -} diff --git a/grouperBot/lib/forge-std/src/StdToml.sol b/grouperBot/lib/forge-std/src/StdToml.sol deleted file mode 100644 index 7ad3be2..0000000 --- a/grouperBot/lib/forge-std/src/StdToml.sol +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -// Helpers for parsing and writing TOML files -// To parse: -// ``` -// using stdToml for string; -// string memory toml = vm.readFile(""); -// toml.readUint(""); -// ``` -// To write: -// ``` -// using stdToml for string; -// string memory json = "json"; -// json.serialize("a", uint256(123)); -// string memory semiFinal = json.serialize("b", string("test")); -// string memory finalJson = json.serialize("c", semiFinal); -// finalJson.write(""); -// ``` - -library stdToml { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function keyExists(string memory toml, string memory key) internal view returns (bool) { - return vm.keyExistsToml(toml, key); - } - - function parseRaw(string memory toml, string memory key) internal pure returns (bytes memory) { - return vm.parseToml(toml, key); - } - - function readUint(string memory toml, string memory key) internal pure returns (uint256) { - return vm.parseTomlUint(toml, key); - } - - function readUintArray(string memory toml, string memory key) internal pure returns (uint256[] memory) { - return vm.parseTomlUintArray(toml, key); - } - - function readInt(string memory toml, string memory key) internal pure returns (int256) { - return vm.parseTomlInt(toml, key); - } - - function readIntArray(string memory toml, string memory key) internal pure returns (int256[] memory) { - return vm.parseTomlIntArray(toml, key); - } - - function readBytes32(string memory toml, string memory key) internal pure returns (bytes32) { - return vm.parseTomlBytes32(toml, key); - } - - function readBytes32Array(string memory toml, string memory key) internal pure returns (bytes32[] memory) { - return vm.parseTomlBytes32Array(toml, key); - } - - function readString(string memory toml, string memory key) internal pure returns (string memory) { - return vm.parseTomlString(toml, key); - } - - function readStringArray(string memory toml, string memory key) internal pure returns (string[] memory) { - return vm.parseTomlStringArray(toml, key); - } - - function readAddress(string memory toml, string memory key) internal pure returns (address) { - return vm.parseTomlAddress(toml, key); - } - - function readAddressArray(string memory toml, string memory key) internal pure returns (address[] memory) { - return vm.parseTomlAddressArray(toml, key); - } - - function readBool(string memory toml, string memory key) internal pure returns (bool) { - return vm.parseTomlBool(toml, key); - } - - function readBoolArray(string memory toml, string memory key) internal pure returns (bool[] memory) { - return vm.parseTomlBoolArray(toml, key); - } - - function readBytes(string memory toml, string memory key) internal pure returns (bytes memory) { - return vm.parseTomlBytes(toml, key); - } - - function readBytesArray(string memory toml, string memory key) internal pure returns (bytes[] memory) { - return vm.parseTomlBytesArray(toml, key); - } - - function readUintOr(string memory toml, string memory key, uint256 defaultValue) internal view returns (uint256) { - return keyExists(toml, key) ? readUint(toml, key) : defaultValue; - } - - function readUintArrayOr(string memory toml, string memory key, uint256[] memory defaultValue) - internal - view - returns (uint256[] memory) - { - return keyExists(toml, key) ? readUintArray(toml, key) : defaultValue; - } - - function readIntOr(string memory toml, string memory key, int256 defaultValue) internal view returns (int256) { - return keyExists(toml, key) ? readInt(toml, key) : defaultValue; - } - - function readIntArrayOr(string memory toml, string memory key, int256[] memory defaultValue) - internal - view - returns (int256[] memory) - { - return keyExists(toml, key) ? readIntArray(toml, key) : defaultValue; - } - - function readBytes32Or(string memory toml, string memory key, bytes32 defaultValue) - internal - view - returns (bytes32) - { - return keyExists(toml, key) ? readBytes32(toml, key) : defaultValue; - } - - function readBytes32ArrayOr(string memory toml, string memory key, bytes32[] memory defaultValue) - internal - view - returns (bytes32[] memory) - { - return keyExists(toml, key) ? readBytes32Array(toml, key) : defaultValue; - } - - function readStringOr(string memory toml, string memory key, string memory defaultValue) - internal - view - returns (string memory) - { - return keyExists(toml, key) ? readString(toml, key) : defaultValue; - } - - function readStringArrayOr(string memory toml, string memory key, string[] memory defaultValue) - internal - view - returns (string[] memory) - { - return keyExists(toml, key) ? readStringArray(toml, key) : defaultValue; - } - - function readAddressOr(string memory toml, string memory key, address defaultValue) - internal - view - returns (address) - { - return keyExists(toml, key) ? readAddress(toml, key) : defaultValue; - } - - function readAddressArrayOr(string memory toml, string memory key, address[] memory defaultValue) - internal - view - returns (address[] memory) - { - return keyExists(toml, key) ? readAddressArray(toml, key) : defaultValue; - } - - function readBoolOr(string memory toml, string memory key, bool defaultValue) internal view returns (bool) { - return keyExists(toml, key) ? readBool(toml, key) : defaultValue; - } - - function readBoolArrayOr(string memory toml, string memory key, bool[] memory defaultValue) - internal - view - returns (bool[] memory) - { - return keyExists(toml, key) ? readBoolArray(toml, key) : defaultValue; - } - - function readBytesOr(string memory toml, string memory key, bytes memory defaultValue) - internal - view - returns (bytes memory) - { - return keyExists(toml, key) ? readBytes(toml, key) : defaultValue; - } - - function readBytesArrayOr(string memory toml, string memory key, bytes[] memory defaultValue) - internal - view - returns (bytes[] memory) - { - return keyExists(toml, key) ? readBytesArray(toml, key) : defaultValue; - } - - function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { - return vm.serializeJson(jsonKey, rootObject); - } - - function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bool[] memory value) - internal - returns (string memory) - { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256[] memory value) - internal - returns (string memory) - { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256[] memory value) - internal - returns (string memory) - { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address[] memory value) - internal - returns (string memory) - { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string[] memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function write(string memory jsonKey, string memory path) internal { - vm.writeToml(jsonKey, path); - } - - function write(string memory jsonKey, string memory path, string memory valueKey) internal { - vm.writeToml(jsonKey, path, valueKey); - } -} diff --git a/grouperBot/lib/forge-std/src/StdUtils.sol b/grouperBot/lib/forge-std/src/StdUtils.sol deleted file mode 100644 index 9321df1..0000000 --- a/grouperBot/lib/forge-std/src/StdUtils.sol +++ /dev/null @@ -1,208 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {IMulticall3} from "./interfaces/IMulticall3.sol"; -import {VmSafe} from "./Vm.sol"; - -abstract contract StdUtils { - /*////////////////////////////////////////////////////////////////////////// - CONSTANTS - //////////////////////////////////////////////////////////////////////////*/ - - IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; - uint256 private constant INT256_MIN_ABS = - 57896044618658097711785492504343953926634992332820282019728792003956564819968; - uint256 private constant SECP256K1_ORDER = - 115792089237316195423570985008687907852837564279074904382605163141518161494337; - uint256 private constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. - address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - - /*////////////////////////////////////////////////////////////////////////// - INTERNAL FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { - require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); - // If x is between min and max, return x directly. This is to ensure that dictionary values - // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 - if (x >= min && x <= max) return x; - - uint256 size = max - min + 1; - - // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. - // This helps ensure coverage of the min/max values. - if (x <= 3 && size > x) return min + x; - if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); - - // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. - if (x > max) { - uint256 diff = x - max; - uint256 rem = diff % size; - if (rem == 0) return max; - result = min + rem - 1; - } else if (x < min) { - uint256 diff = min - x; - uint256 rem = diff % size; - if (rem == 0) return min; - result = max - rem + 1; - } - } - - function bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { - result = _bound(x, min, max); - console2_log_StdUtils("Bound result", result); - } - - function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { - require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); - - // Shifting all int256 values to uint256 to use _bound function. The range of two types are: - // int256 : -(2**255) ~ (2**255 - 1) - // uint256: 0 ~ (2**256 - 1) - // So, add 2**255, INT256_MIN_ABS to the integer values. - // - // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. - // So, use `~uint256(x) + 1` instead. - uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); - uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); - uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); - - uint256 y = _bound(_x, _min, _max); - - // To move it back to int256 value, subtract INT256_MIN_ABS at here. - result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); - } - - function bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { - result = _bound(x, min, max); - console2_log_StdUtils("Bound result", vm.toString(result)); - } - - function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) { - result = _bound(privateKey, 1, SECP256K1_ORDER - 1); - } - - function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { - require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce - function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { - console2_log_StdUtils("computeCreateAddress is deprecated. Please use vm.computeCreateAddress instead."); - return vm.computeCreateAddress(deployer, nonce); - } - - function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) - internal - pure - virtual - returns (address) - { - console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); - return vm.computeCreate2Address(salt, initcodeHash, deployer); - } - - /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { - console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); - return vm.computeCreate2Address(salt, initCodeHash); - } - - /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { - return hashInitCode(creationCode, ""); - } - - /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - /// @param args the ABI-encoded arguments to the constructor of C - function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(creationCode, args)); - } - - // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. - function getTokenBalances(address token, address[] memory addresses) - internal - virtual - returns (uint256[] memory balances) - { - uint256 tokenCodeSize; - assembly { - tokenCodeSize := extcodesize(token) - } - require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - - // ABI encode the aggregate call to Multicall3. - uint256 length = addresses.length; - IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); - for (uint256 i = 0; i < length; ++i) { - // 0x70a08231 = bytes4("balanceOf(address)")) - calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); - } - - // Make the aggregate call. - (, bytes[] memory returnData) = multicall.aggregate(calls); - - // ABI decode the return data and return the balances. - balances = new uint256[](length); - for (uint256 i = 0; i < length; ++i) { - balances[i] = abi.decode(returnData[i], (uint256)); - } - } - - /*////////////////////////////////////////////////////////////////////////// - PRIVATE FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { - return address(uint160(uint256(bytesValue))); - } - - // This section is used to prevent the compilation of console, which shortens the compilation time when console is - // not used elsewhere. We also trick the compiler into letting us make the console log methods as `pure` to avoid - // any breaking changes to function signatures. - function _castLogPayloadViewToPure(function(bytes memory) internal view fnIn) - internal - pure - returns (function(bytes memory) internal pure fnOut) - { - assembly { - fnOut := fnIn - } - } - - function _sendLogPayload(bytes memory payload) internal pure { - _castLogPayloadViewToPure(_sendLogPayloadView)(payload); - } - - function _sendLogPayloadView(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE2_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function console2_log_StdUtils(string memory p0) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function console2_log_StdUtils(string memory p0, uint256 p1) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function console2_log_StdUtils(string memory p0, string memory p1) private pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } -} diff --git a/grouperBot/lib/forge-std/src/Test.sol b/grouperBot/lib/forge-std/src/Test.sol deleted file mode 100644 index 11b18f2..0000000 --- a/grouperBot/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -// 💬 ABOUT -// Forge Std's default Test. - -// 🧩 MODULES -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {safeconsole} from "./safeconsole.sol"; -import {StdAssertions} from "./StdAssertions.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheats} from "./StdCheats.sol"; -import {StdConstants} from "./StdConstants.sol"; -import {stdError} from "./StdError.sol"; -import {StdInvariant} from "./StdInvariant.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {StdStyle} from "./StdStyle.sol"; -import {stdToml} from "./StdToml.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {Vm} from "./Vm.sol"; - -// 📦 BOILERPLATE -import {TestBase} from "./Base.sol"; - -// ⭐️ TEST -abstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils { - // Note: IS_TEST() must return true. - bool public IS_TEST = true; -} diff --git a/grouperBot/lib/forge-std/src/Vm.sol b/grouperBot/lib/forge-std/src/Vm.sol deleted file mode 100644 index cd88370..0000000 --- a/grouperBot/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,2494 +0,0 @@ -// Automatically @generated by scripts/vm.py. Do not modify manually. - -// SPDX-License-Identifier: MIT OR Apache-2.0 -pragma solidity >=0.6.2 <0.9.0; -pragma experimental ABIEncoderV2; - -/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may -/// result in Script simulations differing from on-chain execution. It is recommended to only use -/// these cheats in scripts. -interface VmSafe { - /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. - enum CallerMode { - // No caller modification is currently active. - None, - // A one time broadcast triggered by a `vm.broadcast()` call is currently active. - Broadcast, - // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active. - RecurrentBroadcast, - // A one time prank triggered by a `vm.prank()` call is currently active. - Prank, - // A recurrent prank triggered by a `vm.startPrank()` call is currently active. - RecurrentPrank - } - - /// The kind of account access that occurred. - enum AccountAccessKind { - // The account was called. - Call, - // The account was called via delegatecall. - DelegateCall, - // The account was called via callcode. - CallCode, - // The account was called via staticcall. - StaticCall, - // The account was created. - Create, - // The account was selfdestructed. - SelfDestruct, - // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess). - Resume, - // The account's balance was read. - Balance, - // The account's codesize was read. - Extcodesize, - // The account's codehash was read. - Extcodehash, - // The account's code was copied. - Extcodecopy - } - - /// Forge execution contexts. - enum ForgeContext { - // Test group execution context (test, coverage or snapshot). - TestGroup, - // `forge test` execution context. - Test, - // `forge coverage` execution context. - Coverage, - // `forge snapshot` execution context. - Snapshot, - // Script group execution context (dry run, broadcast or resume). - ScriptGroup, - // `forge script` execution context. - ScriptDryRun, - // `forge script --broadcast` execution context. - ScriptBroadcast, - // `forge script --resume` execution context. - ScriptResume, - // Unknown `forge` execution context. - Unknown - } - - /// The transaction type (`txType`) of the broadcast. - enum BroadcastTxType { - // Represents a CALL broadcast tx. - Call, - // Represents a CREATE broadcast tx. - Create, - // Represents a CREATE2 broadcast tx. - Create2 - } - - /// An Ethereum log. Returned by `getRecordedLogs`. - struct Log { - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The address of the log's emitter. - address emitter; - } - - /// An RPC URL and its alias. Returned by `rpcUrlStructs`. - struct Rpc { - // The alias of the RPC URL. - string key; - // The RPC URL. - string url; - } - - /// An RPC log object. Returned by `eth_getLogs`. - struct EthGetLogs { - // The address of the log's emitter. - address emitter; - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The block hash. - bytes32 blockHash; - // The block number. - uint64 blockNumber; - // The transaction hash. - bytes32 transactionHash; - // The transaction index in the block. - uint64 transactionIndex; - // The log index. - uint256 logIndex; - // Whether the log was removed. - bool removed; - } - - /// A single entry in a directory listing. Returned by `readDir`. - struct DirEntry { - // The error message, if any. - string errorMessage; - // The path of the entry. - string path; - // The depth of the entry. - uint64 depth; - // Whether the entry is a directory. - bool isDir; - // Whether the entry is a symlink. - bool isSymlink; - } - - /// Metadata information about a file. - /// This structure is returned from the `fsMetadata` function and represents known - /// metadata about a file such as its permissions, size, modification - /// times, etc. - struct FsMetadata { - // True if this metadata is for a directory. - bool isDir; - // True if this metadata is for a symlink. - bool isSymlink; - // The size of the file, in bytes, this metadata is for. - uint256 length; - // True if this metadata is for a readonly (unwritable) file. - bool readOnly; - // The last modification time listed in this metadata. - uint256 modified; - // The last access time of this metadata. - uint256 accessed; - // The creation time listed in this metadata. - uint256 created; - } - - /// A wallet with a public and private key. - struct Wallet { - // The wallet's address. - address addr; - // The wallet's public key `X`. - uint256 publicKeyX; - // The wallet's public key `Y`. - uint256 publicKeyY; - // The wallet's private key. - uint256 privateKey; - } - - /// The result of a `tryFfi` call. - struct FfiResult { - // The exit code of the call. - int32 exitCode; - // The optionally hex-decoded `stdout` data. - bytes stdout; - // The `stderr` data. - bytes stderr; - } - - /// Information on the chain and fork. - struct ChainInfo { - // The fork identifier. Set to zero if no fork is active. - uint256 forkId; - // The chain ID of the current fork. - uint256 chainId; - } - - /// Information about a blockchain. - struct Chain { - // The chain name. - string name; - // The chain's Chain ID. - uint256 chainId; - // The chain's alias. (i.e. what gets specified in `foundry.toml`). - string chainAlias; - // A default RPC endpoint for this chain. - string rpcUrl; - } - - /// The result of a `stopAndReturnStateDiff` call. - struct AccountAccess { - // The chain and fork the access occurred. - ChainInfo chainInfo; - // The kind of account access that determines what the account is. - // If kind is Call, DelegateCall, StaticCall or CallCode, then the account is the callee. - // If kind is Create, then the account is the newly created account. - // If kind is SelfDestruct, then the account is the selfdestruct recipient. - // If kind is a Resume, then account represents a account context that has resumed. - AccountAccessKind kind; - // The account that was accessed. - // It's either the account created, callee or a selfdestruct recipient for CREATE, CALL or SELFDESTRUCT. - address account; - // What accessed the account. - address accessor; - // If the account was initialized or empty prior to the access. - // An account is considered initialized if it has code, a - // non-zero nonce, or a non-zero balance. - bool initialized; - // The previous balance of the accessed account. - uint256 oldBalance; - // The potential new balance of the accessed account. - // That is, all balance changes are recorded here, even if reverts occurred. - uint256 newBalance; - // Code of the account deployed by CREATE. - bytes deployedCode; - // Value passed along with the account access - uint256 value; - // Input data provided to the CREATE or CALL - bytes data; - // If this access reverted in either the current or parent context. - bool reverted; - // An ordered list of storage accesses made during an account access operation. - StorageAccess[] storageAccesses; - // Call depth traversed during the recording of state differences - uint64 depth; - // The previous nonce of the accessed account. - uint64 oldNonce; - // The new nonce of the accessed account. - uint64 newNonce; - } - - /// The storage accessed during an `AccountAccess`. - struct StorageAccess { - // The account whose storage was accessed. - address account; - // The slot that was accessed. - bytes32 slot; - // If the access was a write. - bool isWrite; - // The previous value of the slot. - bytes32 previousValue; - // The new value of the slot. - bytes32 newValue; - // If the access was reverted. - bool reverted; - } - - /// Gas used. Returned by `lastCallGas`. - struct Gas { - // The gas limit of the call. - uint64 gasLimit; - // The total gas used. - uint64 gasTotalUsed; - // DEPRECATED: The amount of gas used for memory expansion. Ref: - uint64 gasMemoryUsed; - // The amount of gas refunded. - int64 gasRefunded; - // The amount of gas remaining. - uint64 gasRemaining; - } - - /// The result of the `stopDebugTraceRecording` call - struct DebugStep { - // The stack before executing the step of the run. - // stack\[0\] represents the top of the stack. - // and only stack data relevant to the opcode execution is contained. - uint256[] stack; - // The memory input data before executing the step of the run. - // only input data relevant to the opcode execution is contained. - // e.g. for MLOAD, it will have memory\[offset:offset+32\] copied here. - // the offset value can be get by the stack data. - bytes memoryInput; - // The opcode that was accessed. - uint8 opcode; - // The call depth of the step. - uint64 depth; - // Whether the call end up with out of gas error. - bool isOutOfGas; - // The contract address where the opcode is running - address contractAddr; - } - - /// Represents a transaction's broadcast details. - struct BroadcastTxSummary { - // The hash of the transaction that was broadcasted - bytes32 txHash; - // Represent the type of transaction among CALL, CREATE, CREATE2 - BroadcastTxType txType; - // The address of the contract that was called or created. - // This is address of the contract that is created if the txType is CREATE or CREATE2. - address contractAddress; - // The block number the transaction landed in. - uint64 blockNumber; - // Status of the transaction, retrieved from the transaction receipt. - bool success; - } - - /// Holds a signed EIP-7702 authorization for an authority account to delegate to an implementation. - struct SignedDelegation { - // The y-parity of the recovered secp256k1 signature (0 or 1). - uint8 v; - // First 32 bytes of the signature. - bytes32 r; - // Second 32 bytes of the signature. - bytes32 s; - // The current nonce of the authority account at signing time. - // Used to ensure signature can't be replayed after account nonce changes. - uint64 nonce; - // Address of the contract implementation that will be delegated to. - // Gets encoded into delegation code: 0xef0100 || implementation. - address implementation; - } - - /// Represents a "potential" revert reason from a single subsequent call when using `vm.assumeNoReverts`. - /// Reverts that match will result in a FOUNDRY::ASSUME rejection, whereas unmatched reverts will be surfaced - /// as normal. - struct PotentialRevert { - // The allowed origin of the revert opcode; address(0) allows reverts from any address - address reverter; - // When true, only matches on the beginning of the revert data, otherwise, matches on entire revert data - bool partialMatch; - // The data to use to match encountered reverts - bytes revertData; - } - - /// An EIP-2930 access list item. - struct AccessListItem { - // The address to be added in access list. - address target; - // The storage keys to be added in access list. - bytes32[] storageKeys; - } - - // ======== Crypto ======== - - /// Derives a private key from the name, labels the account with that name, and returns the wallet. - function createWallet(string calldata walletLabel) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key and returns the wallet. - function createWallet(uint256 privateKey) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key, labels the account with that name, and returns the wallet. - function createWallet(uint256 privateKey, string calldata walletLabel) external returns (Wallet memory wallet); - - /// Derive a private key from a provided mnemonic string (or mnemonic file path) - /// at the derivation path `m/44'/60'/0'/0/{index}`. - function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); - - /// Derive a private key from a provided mnemonic string (or mnemonic file path) - /// at `{derivationPath}{index}`. - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) - external - pure - returns (uint256 privateKey); - - /// Derive a private key from a provided mnemonic string (or mnemonic file path) in the specified language - /// at the derivation path `m/44'/60'/0'/0/{index}`. - function deriveKey(string calldata mnemonic, uint32 index, string calldata language) - external - pure - returns (uint256 privateKey); - - /// Derive a private key from a provided mnemonic string (or mnemonic file path) in the specified language - /// at `{derivationPath}{index}`. - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) - external - pure - returns (uint256 privateKey); - - /// Derives secp256r1 public key from the provided `privateKey`. - function publicKeyP256(uint256 privateKey) external pure returns (uint256 publicKeyX, uint256 publicKeyY); - - /// Adds a private key to the local forge wallet and returns the address. - function rememberKey(uint256 privateKey) external returns (address keyAddr); - - /// Derive a set number of wallets from a mnemonic at the derivation path `m/44'/60'/0'/0/{0..count}`. - /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. - function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count) - external - returns (address[] memory keyAddrs); - - /// Derive a set number of wallets from a mnemonic in the specified language at the derivation path `m/44'/60'/0'/0/{0..count}`. - /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. - function rememberKeys( - string calldata mnemonic, - string calldata derivationPath, - string calldata language, - uint32 count - ) external returns (address[] memory keyAddrs); - - /// Signs data with a `Wallet`. - /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the - /// signature's `s` value, and the recovery id `v` in a single bytes32. - /// This format reduces the signature size from 65 to 64 bytes. - function signCompact(Wallet calldata wallet, bytes32 digest) external returns (bytes32 r, bytes32 vs); - - /// Signs `digest` with `privateKey` using the secp256k1 curve. - /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the - /// signature's `s` value, and the recovery id `v` in a single bytes32. - /// This format reduces the signature size from 65 to 64 bytes. - function signCompact(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 vs); - - /// Signs `digest` with signer provided to script using the secp256k1 curve. - /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the - /// signature's `s` value, and the recovery id `v` in a single bytes32. - /// This format reduces the signature size from 65 to 64 bytes. - /// If `--sender` is provided, the signer with provided address is used, otherwise, - /// if exactly one signer is provided to the script, that signer is used. - /// Raises error if signer passed through `--sender` does not match any unlocked signers or - /// if `--sender` is not provided and not exactly one signer is passed to the script. - function signCompact(bytes32 digest) external pure returns (bytes32 r, bytes32 vs); - - /// Signs `digest` with signer provided to script using the secp256k1 curve. - /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the - /// signature's `s` value, and the recovery id `v` in a single bytes32. - /// This format reduces the signature size from 65 to 64 bytes. - /// Raises error if none of the signers passed into the script have provided address. - function signCompact(address signer, bytes32 digest) external pure returns (bytes32 r, bytes32 vs); - - /// Signs `digest` with `privateKey` using the secp256r1 curve. - function signP256(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 s); - - /// Signs data with a `Wallet`. - function sign(Wallet calldata wallet, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s); - - /// Signs `digest` with `privateKey` using the secp256k1 curve. - function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - - /// Signs `digest` with signer provided to script using the secp256k1 curve. - /// If `--sender` is provided, the signer with provided address is used, otherwise, - /// if exactly one signer is provided to the script, that signer is used. - /// Raises error if signer passed through `--sender` does not match any unlocked signers or - /// if `--sender` is not provided and not exactly one signer is passed to the script. - function sign(bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - - /// Signs `digest` with signer provided to script using the secp256k1 curve. - /// Raises error if none of the signers passed into the script have provided address. - function sign(address signer, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - - // ======== Environment ======== - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name) external view returns (address value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name) external view returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name) external view returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); - - /// Gets the environment variable `name` and returns true if it exists, else returns false. - function envExists(string calldata name) external view returns (bool result); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name) external view returns (int256 value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bool defaultValue) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, uint256 defaultValue) external view returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) - external - view - returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) - external - view - returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) - external - view - returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) - external - view - returns (bytes[] memory value); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, int256 defaultValue) external view returns (int256 value); - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, address defaultValue) external view returns (address value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes32 defaultValue) external view returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata defaultValue) external view returns (string memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes calldata defaultValue) external view returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) - external - view - returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) - external - view - returns (uint256[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) - external - view - returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name) external view returns (string memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name, string calldata delim) external view returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name) external view returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); - - /// Returns true if `forge` command was executed in given context. - function isContext(ForgeContext context) external view returns (bool result); - - /// Resolves the env variable placeholders of a given input string. - function resolveEnv(string calldata input) external returns (string memory); - - /// Sets environment variables. - function setEnv(string calldata name, string calldata value) external; - - // ======== EVM ======== - - /// Gets all accessed reads and write slot from a `vm.record` session, for a given address. - function accesses(address target) external view returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); - - /// Gets the address for a given private key. - function addr(uint256 privateKey) external pure returns (address keyAddr); - - /// Gets all the logs according to specified filter. - function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] calldata topics) - external - view - returns (EthGetLogs[] memory logs); - - /// Gets the current `block.blobbasefee`. - /// You should use this instead of `block.blobbasefee` if you use `vm.blobBaseFee`, as `block.blobbasefee` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlobBaseFee() external view returns (uint256 blobBaseFee); - - /// Gets the current `block.number`. - /// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockNumber() external view returns (uint256 height); - - /// Gets the current `block.timestamp`. - /// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockTimestamp() external view returns (uint256 timestamp); - - /// Gets the current `block.chainid` of the currently selected environment. - /// You should use this instead of `block.chainid` if you use `vm.selectFork` or `vm.createSelectFork`, as `block.chainid` could be assumed - /// to be constant across a transaction, and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getChainId() external view returns (uint256 blockChainId); - - /// Gets the map key and parent of a mapping at a given slot, for a given address. - function getMappingKeyAndParentOf(address target, bytes32 elementSlot) - external - view - returns (bool found, bytes32 key, bytes32 parent); - - /// Gets the number of elements in the mapping at the given slot, for a given address. - function getMappingLength(address target, bytes32 mappingSlot) external view returns (uint256 length); - - /// Gets the elements at index idx of the mapping at the given slot, for a given address. The - /// index must be less than the length of the mapping (i.e. the number of keys in the mapping). - function getMappingSlotAt(address target, bytes32 mappingSlot, uint256 idx) external view returns (bytes32 value); - - /// Gets the nonce of an account. - function getNonce(address account) external view returns (uint64 nonce); - - /// Get the nonce of a `Wallet`. - function getNonce(Wallet calldata wallet) external view returns (uint64 nonce); - - /// Gets the RLP encoded block header for a given block number. - /// Returns the block header in the same format as `cast block --raw`. - function getRawBlockHeader(uint256 blockNumber) external view returns (bytes memory rlpHeader); - - /// Gets all the recorded logs. - function getRecordedLogs() external view returns (Log[] memory logs); - - /// Returns state diffs from current `vm.startStateDiffRecording` session. - function getStateDiff() external view returns (string memory diff); - - /// Returns state diffs from current `vm.startStateDiffRecording` session, in json format. - function getStateDiffJson() external view returns (string memory diff); - - /// Returns an array of `StorageAccess` from current `vm.stateStateDiffRecording` session - function getStorageAccesses() external view returns (StorageAccess[] memory storageAccesses); - - /// Gets the gas used in the last call from the callee perspective. - function lastCallGas() external view returns (Gas memory gas); - - /// Loads a storage slot from an address. - function load(address target, bytes32 slot) external view returns (bytes32 data); - - /// Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. - function pauseGasMetering() external; - - /// Records all storage reads and writes. Use `accesses` to get the recorded data. - /// Subsequent calls to `record` will clear the previous data. - function record() external; - - /// Record all the transaction logs. - function recordLogs() external; - - /// Reset gas metering (i.e. gas usage is set to gas limit). - function resetGasMetering() external; - - /// Resumes gas metering (i.e. gas usage is counted again). Noop if already on. - function resumeGasMetering() external; - - /// Performs an Ethereum JSON-RPC request to the current fork URL. - function rpc(string calldata method, string calldata params) external returns (bytes memory data); - - /// Performs an Ethereum JSON-RPC request to the given endpoint. - function rpc(string calldata urlOrAlias, string calldata method, string calldata params) - external - returns (bytes memory data); - - /// Records the debug trace during the run. - function startDebugTraceRecording() external; - - /// Starts recording all map SSTOREs for later retrieval. - function startMappingRecording() external; - - /// Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order, - /// along with the context of the calls - function startStateDiffRecording() external; - - /// Stop debug trace recording and returns the recorded debug trace. - function stopAndReturnDebugTraceRecording() external returns (DebugStep[] memory step); - - /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. - function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); - - /// Stops recording all map SSTOREs for later retrieval and clears the recorded data. - function stopMappingRecording() external; - - /// Stops recording storage reads and writes. - function stopRecord() external; - - // ======== Filesystem ======== - - /// Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. - /// `path` is relative to the project root. - function closeFile(string calldata path) external; - - /// Copies the contents of one file to another. This function will **overwrite** the contents of `to`. - /// On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`. - /// Both `from` and `to` are relative to the project root. - function copyFile(string calldata from, string calldata to) external returns (uint64 copied); - - /// Creates a new, empty directory at the provided path. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - User lacks permissions to modify `path`. - /// - A parent of the given path doesn't exist and `recursive` is false. - /// - `path` already exists and `recursive` is false. - /// `path` is relative to the project root. - function createDir(string calldata path, bool recursive) external; - - /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - function deployCode(string calldata artifactPath) external returns (address deployedAddress); - - /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - /// Additionally accepts abi-encoded constructor arguments. - function deployCode(string calldata artifactPath, bytes calldata constructorArgs) - external - returns (address deployedAddress); - - /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - /// Additionally accepts `msg.value`. - function deployCode(string calldata artifactPath, uint256 value) external returns (address deployedAddress); - - /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - /// Additionally accepts abi-encoded constructor arguments and `msg.value`. - function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value) - external - returns (address deployedAddress); - - /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - function deployCode(string calldata artifactPath, bytes32 salt) external returns (address deployedAddress); - - /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - /// Additionally accepts abi-encoded constructor arguments. - function deployCode(string calldata artifactPath, bytes calldata constructorArgs, bytes32 salt) - external - returns (address deployedAddress); - - /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - /// Additionally accepts `msg.value`. - function deployCode(string calldata artifactPath, uint256 value, bytes32 salt) - external - returns (address deployedAddress); - - /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - /// Additionally accepts abi-encoded constructor arguments and `msg.value`. - function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value, bytes32 salt) - external - returns (address deployedAddress); - - /// Returns true if the given path points to an existing entity, else returns false. - function exists(string calldata path) external view returns (bool result); - - /// Performs a foreign function call via the terminal. - function ffi(string[] calldata commandInput) external returns (bytes memory result); - - /// Given a path, query the file system to get information about a file, directory, etc. - function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); - - /// Gets the artifact path from code (aka. creation code). - function getArtifactPathByCode(bytes calldata code) external view returns (string memory path); - - /// Gets the artifact path from deployed code (aka. runtime code). - function getArtifactPathByDeployedCode(bytes calldata deployedCode) external view returns (string memory path); - - /// Returns the most recent broadcast for the given contract on `chainId` matching `txType`. - /// For example: - /// The most recent deployment can be fetched by passing `txType` as `CREATE` or `CREATE2`. - /// The most recent call can be fetched by passing `txType` as `CALL`. - function getBroadcast(string calldata contractName, uint64 chainId, BroadcastTxType txType) - external - view - returns (BroadcastTxSummary memory); - - /// Returns all broadcasts for the given contract on `chainId` with the specified `txType`. - /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. - function getBroadcasts(string calldata contractName, uint64 chainId, BroadcastTxType txType) - external - view - returns (BroadcastTxSummary[] memory); - - /// Returns all broadcasts for the given contract on `chainId`. - /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. - function getBroadcasts(string calldata contractName, uint64 chainId) - external - view - returns (BroadcastTxSummary[] memory); - - /// Gets the creation bytecode from an artifact file. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); - - /// Gets the deployed bytecode from an artifact file. Takes in the relative path to the json file or the path to the - /// artifact in the form of :: where and parts are optional. - function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); - - /// Returns the most recent deployment for the current `chainId`. - function getDeployment(string calldata contractName) external view returns (address deployedAddress); - - /// Returns the most recent deployment for the given contract on `chainId` - function getDeployment(string calldata contractName, uint64 chainId) - external - view - returns (address deployedAddress); - - /// Returns all deployments for the given contract on `chainId` - /// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber. - /// The most recent deployment is the first element, and the oldest is the last. - function getDeployments(string calldata contractName, uint64 chainId) - external - view - returns (address[] memory deployedAddresses); - - /// Returns true if the path exists on disk and is pointing at a directory, else returns false. - function isDir(string calldata path) external view returns (bool result); - - /// Returns true if the path exists on disk and is pointing at a regular file, else returns false. - function isFile(string calldata path) external view returns (bool result); - - /// Get the path of the current project root. - function projectRoot() external view returns (string memory path); - - /// Prompts the user for a string value in the terminal. - function prompt(string calldata promptText) external returns (string memory input); - - /// Prompts the user for an address in the terminal. - function promptAddress(string calldata promptText) external returns (address); - - /// Prompts the user for a hidden string value in the terminal. - function promptSecret(string calldata promptText) external returns (string memory input); - - /// Prompts the user for hidden uint256 in the terminal (usually pk). - function promptSecretUint(string calldata promptText) external returns (uint256); - - /// Prompts the user for uint256 in the terminal. - function promptUint(string calldata promptText) external returns (uint256); - - /// Reads the directory at the given path recursively, up to `maxDepth`. - /// `maxDepth` defaults to 1, meaning only the direct children of the given directory will be returned. - /// Follows symbolic links if `followLinks` is true. - function readDir(string calldata path) external view returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth, bool followLinks) - external - view - returns (DirEntry[] memory entries); - - /// Reads the entire content of file to string. `path` is relative to the project root. - function readFile(string calldata path) external view returns (string memory data); - - /// Reads the entire content of file as binary. `path` is relative to the project root. - function readFileBinary(string calldata path) external view returns (bytes memory data); - - /// Reads next line of file to string. - function readLine(string calldata path) external view returns (string memory line); - - /// Reads a symbolic link, returning the path that the link points to. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - `path` is not a symbolic link. - /// - `path` does not exist. - function readLink(string calldata linkPath) external view returns (string memory targetPath); - - /// Removes a directory at the provided path. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - `path` doesn't exist. - /// - `path` isn't a directory. - /// - User lacks permissions to modify `path`. - /// - The directory is not empty and `recursive` is false. - /// `path` is relative to the project root. - function removeDir(string calldata path, bool recursive) external; - - /// Removes a file from the filesystem. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - `path` points to a directory. - /// - The file doesn't exist. - /// - The user lacks permissions to remove the file. - /// `path` is relative to the project root. - function removeFile(string calldata path) external; - - /// Performs a foreign function call via terminal and returns the exit code, stdout, and stderr. - function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result); - - /// Returns the time since unix epoch in milliseconds. - function unixTime() external view returns (uint256 milliseconds); - - /// Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. - /// `path` is relative to the project root. - function writeFile(string calldata path, string calldata data) external; - - /// Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. - /// `path` is relative to the project root. - function writeFileBinary(string calldata path, bytes calldata data) external; - - /// Writes line to file, creating a file if it does not exist. - /// `path` is relative to the project root. - function writeLine(string calldata path, string calldata data) external; - - // ======== JSON ======== - - /// Checks if `key` exists in a JSON object. - function keyExistsJson(string calldata json, string calldata key) external view returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `address`. - function parseJsonAddress(string calldata json, string calldata key) external pure returns (address); - - /// Parses a string of JSON data at `key` and coerces it to `address[]`. - function parseJsonAddressArray(string calldata json, string calldata key) - external - pure - returns (address[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bool`. - function parseJsonBool(string calldata json, string calldata key) external pure returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `bool[]`. - function parseJsonBoolArray(string calldata json, string calldata key) external pure returns (bool[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes`. - function parseJsonBytes(string calldata json, string calldata key) external pure returns (bytes memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32`. - function parseJsonBytes32(string calldata json, string calldata key) external pure returns (bytes32); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32[]`. - function parseJsonBytes32Array(string calldata json, string calldata key) - external - pure - returns (bytes32[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes[]`. - function parseJsonBytesArray(string calldata json, string calldata key) external pure returns (bytes[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `int256`. - function parseJsonInt(string calldata json, string calldata key) external pure returns (int256); - - /// Parses a string of JSON data at `key` and coerces it to `int256[]`. - function parseJsonIntArray(string calldata json, string calldata key) external pure returns (int256[] memory); - - /// Returns an array of all the keys in a JSON object. - function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys); - - /// Parses a string of JSON data at `key` and coerces it to `string`. - function parseJsonString(string calldata json, string calldata key) external pure returns (string memory); - - /// Parses a string of JSON data at `key` and coerces it to `string[]`. - function parseJsonStringArray(string calldata json, string calldata key) external pure returns (string[] memory); - - /// Parses a string of JSON data at `key` and coerces it to type array corresponding to `typeDescription`. - function parseJsonTypeArray(string calldata json, string calldata key, string calldata typeDescription) - external - pure - returns (bytes memory); - - /// Parses a string of JSON data and coerces it to type corresponding to `typeDescription`. - function parseJsonType(string calldata json, string calldata typeDescription) - external - pure - returns (bytes memory); - - /// Parses a string of JSON data at `key` and coerces it to type corresponding to `typeDescription`. - function parseJsonType(string calldata json, string calldata key, string calldata typeDescription) - external - pure - returns (bytes memory); - - /// Parses a string of JSON data at `key` and coerces it to `uint256`. - function parseJsonUint(string calldata json, string calldata key) external pure returns (uint256); - - /// Parses a string of JSON data at `key` and coerces it to `uint256[]`. - function parseJsonUintArray(string calldata json, string calldata key) external pure returns (uint256[] memory); - - /// ABI-encodes a JSON object. - function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); - - /// ABI-encodes a JSON object at `key`. - function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); - - /// See `serializeJson`. - function serializeAddress(string calldata objectKey, string calldata valueKey, address value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBool(string calldata objectKey, string calldata valueKey, bool value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) - external - returns (string memory json); - - /// Serializes a key and value to a JSON object stored in-memory that can be later written to a file. - /// Returns the stringified version of the specific JSON file up to that moment. - function serializeJson(string calldata objectKey, string calldata value) external returns (string memory json); - - /// See `serializeJson`. - function serializeJsonType(string calldata typeDescription, bytes calldata value) - external - pure - returns (string memory json); - - /// See `serializeJson`. - function serializeJsonType( - string calldata objectKey, - string calldata valueKey, - string calldata typeDescription, - bytes calldata value - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUintToHex(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) - external - returns (string memory json); - - /// Write a serialized JSON object to a file. If the file exists, it will be overwritten. - function writeJson(string calldata json, string calldata path) external; - - /// Write a serialized JSON object to an **existing** JSON file, replacing a value with key = - /// This is useful to replace a specific value of a JSON file, without having to parse the entire thing. - /// This cheatcode will create new keys if they didn't previously exist. - function writeJson(string calldata json, string calldata path, string calldata valueKey) external; - - /// Checks if `key` exists in a JSON object - /// `keyExists` is being deprecated in favor of `keyExistsJson`. It will be removed in future versions. - function keyExists(string calldata json, string calldata key) external view returns (bool); - - // ======== Scripting ======== - - /// Attach an EIP-4844 blob to the next call - function attachBlob(bytes calldata blob) external; - - /// Designate the next call as an EIP-7702 transaction - function attachDelegation(SignedDelegation calldata signedDelegation) external; - - /// Designate the next call as an EIP-7702 transaction, with optional cross-chain validity. - function attachDelegation(SignedDelegation calldata signedDelegation, bool crossChain) external; - - /// Takes a signed transaction and broadcasts it to the network. - function broadcastRawTransaction(bytes calldata data) external; - - /// Has the next call (at this call depth only) create transactions that can later be signed and sent onchain. - /// Broadcasting address is determined by checking the following in order: - /// 1. If `--sender` argument was provided, that address is used. - /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. - /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. - function broadcast() external; - - /// Has the next call (at this call depth only) create a transaction with the address provided - /// as the sender that can later be signed and sent onchain. - function broadcast(address signer) external; - - /// Has the next call (at this call depth only) create a transaction with the private key - /// provided as the sender that can later be signed and sent onchain. - function broadcast(uint256 privateKey) external; - - /// Returns addresses of available unlocked wallets in the script environment. - function getWallets() external view returns (address[] memory wallets); - - /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction - function signAndAttachDelegation(address implementation, uint256 privateKey) - external - returns (SignedDelegation memory signedDelegation); - - /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction for specific nonce - function signAndAttachDelegation(address implementation, uint256 privateKey, uint64 nonce) - external - returns (SignedDelegation memory signedDelegation); - - /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction, with optional cross-chain validity. - function signAndAttachDelegation(address implementation, uint256 privateKey, bool crossChain) - external - returns (SignedDelegation memory signedDelegation); - - /// Sign an EIP-7702 authorization for delegation - function signDelegation(address implementation, uint256 privateKey) - external - returns (SignedDelegation memory signedDelegation); - - /// Sign an EIP-7702 authorization for delegation for specific nonce - function signDelegation(address implementation, uint256 privateKey, uint64 nonce) - external - returns (SignedDelegation memory signedDelegation); - - /// Sign an EIP-7702 authorization for delegation, with optional cross-chain validity. - function signDelegation(address implementation, uint256 privateKey, bool crossChain) - external - returns (SignedDelegation memory signedDelegation); - - /// Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain. - /// Broadcasting address is determined by checking the following in order: - /// 1. If `--sender` argument was provided, that address is used. - /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. - /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. - function startBroadcast() external; - - /// Has all subsequent calls (at this call depth only) create transactions with the address - /// provided that can later be signed and sent onchain. - function startBroadcast(address signer) external; - - /// Has all subsequent calls (at this call depth only) create transactions with the private key - /// provided that can later be signed and sent onchain. - function startBroadcast(uint256 privateKey) external; - - /// Stops collecting onchain transactions. - function stopBroadcast() external; - - // ======== String ======== - - /// Returns true if `search` is found in `subject`, false otherwise. - function contains(string calldata subject, string calldata search) external pure returns (bool result); - - /// Returns the index of the first occurrence of a `key` in an `input` string. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `key` is not found. - /// Returns 0 in case of an empty `key`. - function indexOf(string calldata input, string calldata key) external pure returns (uint256); - - /// Parses the given `string` into an `address`. - function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); - - /// Parses the given `string` into a `bool`. - function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); - - /// Parses the given `string` into `bytes`. - function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); - - /// Parses the given `string` into a `bytes32`. - function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); - - /// Parses the given `string` into a `int256`. - function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); - - /// Parses the given `string` into a `uint256`. - function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); - - /// Replaces occurrences of `from` in the given `string` with `to`. - function replace(string calldata input, string calldata from, string calldata to) - external - pure - returns (string memory output); - - /// Splits the given `string` into an array of strings divided by the `delimiter`. - function split(string calldata input, string calldata delimiter) external pure returns (string[] memory outputs); - - /// Converts the given `string` value to Lowercase. - function toLowercase(string calldata input) external pure returns (string memory output); - - /// Converts the given value to a `string`. - function toString(address value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes calldata value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes32 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bool value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(uint256 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(int256 value) external pure returns (string memory stringifiedValue); - - /// Converts the given `string` value to Uppercase. - function toUppercase(string calldata input) external pure returns (string memory output); - - /// Trims leading and trailing whitespace from the given `string` value. - function trim(string calldata input) external pure returns (string memory output); - - // ======== Testing ======== - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. - function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqAbsDecimal( - int256 left, - int256 right, - uint256 maxDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Includes error message into revert string on failure. - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string calldata error) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Includes error message into revert string on failure. - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string calldata error) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. - function assertApproxEqRelDecimal(uint256 left, uint256 right, uint256 maxPercentDelta, uint256 decimals) - external - pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. - function assertApproxEqRelDecimal(int256 left, int256 right, uint256 maxPercentDelta, uint256 decimals) - external - pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Includes error message into revert string on failure. - function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta, string calldata error) - external - pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Includes error message into revert string on failure. - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta, string calldata error) - external - pure; - - /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. - function assertEqDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `bool` values are equal. - function assertEq(bool left, bool right) external pure; - - /// Asserts that two `bool` values are equal and includes error message into revert string on failure. - function assertEq(bool left, bool right, string calldata error) external pure; - - /// Asserts that two `string` values are equal. - function assertEq(string calldata left, string calldata right) external pure; - - /// Asserts that two `string` values are equal and includes error message into revert string on failure. - function assertEq(string calldata left, string calldata right, string calldata error) external pure; - - /// Asserts that two `bytes` values are equal. - function assertEq(bytes calldata left, bytes calldata right) external pure; - - /// Asserts that two `bytes` values are equal and includes error message into revert string on failure. - function assertEq(bytes calldata left, bytes calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bool` values are equal. - function assertEq(bool[] calldata left, bool[] calldata right) external pure; - - /// Asserts that two arrays of `bool` values are equal and includes error message into revert string on failure. - function assertEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `uint256 values are equal. - function assertEq(uint256[] calldata left, uint256[] calldata right) external pure; - - /// Asserts that two arrays of `uint256` values are equal and includes error message into revert string on failure. - function assertEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `int256` values are equal. - function assertEq(int256[] calldata left, int256[] calldata right) external pure; - - /// Asserts that two arrays of `int256` values are equal and includes error message into revert string on failure. - function assertEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are equal. - function assertEq(uint256 left, uint256 right) external pure; - - /// Asserts that two arrays of `address` values are equal. - function assertEq(address[] calldata left, address[] calldata right) external pure; - - /// Asserts that two arrays of `address` values are equal and includes error message into revert string on failure. - function assertEq(address[] calldata left, address[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes32` values are equal. - function assertEq(bytes32[] calldata left, bytes32[] calldata right) external pure; - - /// Asserts that two arrays of `bytes32` values are equal and includes error message into revert string on failure. - function assertEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `string` values are equal. - function assertEq(string[] calldata left, string[] calldata right) external pure; - - /// Asserts that two arrays of `string` values are equal and includes error message into revert string on failure. - function assertEq(string[] calldata left, string[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes` values are equal. - function assertEq(bytes[] calldata left, bytes[] calldata right) external pure; - - /// Asserts that two arrays of `bytes` values are equal and includes error message into revert string on failure. - function assertEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are equal and includes error message into revert string on failure. - function assertEq(uint256 left, uint256 right, string calldata error) external pure; - - /// Asserts that two `int256` values are equal. - function assertEq(int256 left, int256 right) external pure; - - /// Asserts that two `int256` values are equal and includes error message into revert string on failure. - function assertEq(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `address` values are equal. - function assertEq(address left, address right) external pure; - - /// Asserts that two `address` values are equal and includes error message into revert string on failure. - function assertEq(address left, address right, string calldata error) external pure; - - /// Asserts that two `bytes32` values are equal. - function assertEq(bytes32 left, bytes32 right) external pure; - - /// Asserts that two `bytes32` values are equal and includes error message into revert string on failure. - function assertEq(bytes32 left, bytes32 right, string calldata error) external pure; - - /// Asserts that the given condition is false. - function assertFalse(bool condition) external pure; - - /// Asserts that the given condition is false and includes error message into revert string on failure. - function assertFalse(bool condition, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. - function assertGeDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - function assertGe(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Includes error message into revert string on failure. - function assertGe(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - function assertGe(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Includes error message into revert string on failure. - function assertGe(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. - function assertGtDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - function assertGt(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Includes error message into revert string on failure. - function assertGt(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - function assertGt(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Includes error message into revert string on failure. - function assertGt(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. - function assertLeDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - function assertLe(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Includes error message into revert string on failure. - function assertLe(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - function assertLe(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Includes error message into revert string on failure. - function assertLe(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. - function assertLtDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - function assertLt(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Includes error message into revert string on failure. - function assertLt(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - function assertLt(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Includes error message into revert string on failure. - function assertLt(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; - - /// Asserts that two `bool` values are not equal. - function assertNotEq(bool left, bool right) external pure; - - /// Asserts that two `bool` values are not equal and includes error message into revert string on failure. - function assertNotEq(bool left, bool right, string calldata error) external pure; - - /// Asserts that two `string` values are not equal. - function assertNotEq(string calldata left, string calldata right) external pure; - - /// Asserts that two `string` values are not equal and includes error message into revert string on failure. - function assertNotEq(string calldata left, string calldata right, string calldata error) external pure; - - /// Asserts that two `bytes` values are not equal. - function assertNotEq(bytes calldata left, bytes calldata right) external pure; - - /// Asserts that two `bytes` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes calldata left, bytes calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bool` values are not equal. - function assertNotEq(bool[] calldata left, bool[] calldata right) external pure; - - /// Asserts that two arrays of `bool` values are not equal and includes error message into revert string on failure. - function assertNotEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `uint256` values are not equal. - function assertNotEq(uint256[] calldata left, uint256[] calldata right) external pure; - - /// Asserts that two arrays of `uint256` values are not equal and includes error message into revert string on failure. - function assertNotEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `int256` values are not equal. - function assertNotEq(int256[] calldata left, int256[] calldata right) external pure; - - /// Asserts that two arrays of `int256` values are not equal and includes error message into revert string on failure. - function assertNotEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are not equal. - function assertNotEq(uint256 left, uint256 right) external pure; - - /// Asserts that two arrays of `address` values are not equal. - function assertNotEq(address[] calldata left, address[] calldata right) external pure; - - /// Asserts that two arrays of `address` values are not equal and includes error message into revert string on failure. - function assertNotEq(address[] calldata left, address[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes32` values are not equal. - function assertNotEq(bytes32[] calldata left, bytes32[] calldata right) external pure; - - /// Asserts that two arrays of `bytes32` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `string` values are not equal. - function assertNotEq(string[] calldata left, string[] calldata right) external pure; - - /// Asserts that two arrays of `string` values are not equal and includes error message into revert string on failure. - function assertNotEq(string[] calldata left, string[] calldata right, string calldata error) external pure; - - /// Asserts that two arrays of `bytes` values are not equal. - function assertNotEq(bytes[] calldata left, bytes[] calldata right) external pure; - - /// Asserts that two arrays of `bytes` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; - - /// Asserts that two `uint256` values are not equal and includes error message into revert string on failure. - function assertNotEq(uint256 left, uint256 right, string calldata error) external pure; - - /// Asserts that two `int256` values are not equal. - function assertNotEq(int256 left, int256 right) external pure; - - /// Asserts that two `int256` values are not equal and includes error message into revert string on failure. - function assertNotEq(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `address` values are not equal. - function assertNotEq(address left, address right) external pure; - - /// Asserts that two `address` values are not equal and includes error message into revert string on failure. - function assertNotEq(address left, address right, string calldata error) external pure; - - /// Asserts that two `bytes32` values are not equal. - function assertNotEq(bytes32 left, bytes32 right) external pure; - - /// Asserts that two `bytes32` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes32 left, bytes32 right, string calldata error) external pure; - - /// Asserts that the given condition is true. - function assertTrue(bool condition) external pure; - - /// Asserts that the given condition is true and includes error message into revert string on failure. - function assertTrue(bool condition, string calldata error) external pure; - - /// If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool condition) external pure; - - /// Discard this run's fuzz inputs and generate new ones if next call reverted. - function assumeNoRevert() external pure; - - /// Discard this run's fuzz inputs and generate new ones if next call reverts with the potential revert parameters. - function assumeNoRevert(PotentialRevert calldata potentialRevert) external pure; - - /// Discard this run's fuzz inputs and generate new ones if next call reverts with the any of the potential revert parameters. - function assumeNoRevert(PotentialRevert[] calldata potentialReverts) external pure; - - /// Writes a breakpoint to jump to in the debugger. - function breakpoint(string calldata char) external pure; - - /// Writes a conditional breakpoint to jump to in the debugger. - function breakpoint(string calldata char, bool value) external pure; - - /// Returns true if the current Foundry version is greater than or equal to the given version. - /// The given version string must be in the format `major.minor.patch`. - /// This is equivalent to `foundryVersionCmp(version) >= 0`. - function foundryVersionAtLeast(string calldata version) external view returns (bool); - - /// Compares the current Foundry version with the given version string. - /// The given version string must be in the format `major.minor.patch`. - /// Returns: - /// -1 if current Foundry version is less than the given version - /// 0 if current Foundry version equals the given version - /// 1 if current Foundry version is greater than the given version - /// This result can then be used with a comparison operator against `0`. - /// For example, to check if the current Foundry version is greater than or equal to `1.0.0`: - /// `if (foundryVersionCmp("1.0.0") >= 0) { ... }` - function foundryVersionCmp(string calldata version) external view returns (int256); - - /// Returns a Chain struct for specific alias - function getChain(string calldata chainAlias) external view returns (Chain memory chain); - - /// Returns a Chain struct for specific chainId - function getChain(uint256 chainId) external view returns (Chain memory chain); - - /// Returns the Foundry version. - /// Format: -+.. - /// Sample output: 0.3.0-nightly+3cb96bde9b.1737036656.debug - /// Note: Build timestamps may vary slightly across platforms due to separate CI jobs. - /// For reliable version comparisons, use UNIX format (e.g., >= 1700000000) - /// to compare timestamps while ignoring minor time differences. - function getFoundryVersion() external view returns (string memory version); - - /// Returns the RPC url for the given alias. - function rpcUrl(string calldata rpcAlias) external view returns (string memory json); - - /// Returns all rpc urls and their aliases as structs. - function rpcUrlStructs() external view returns (Rpc[] memory urls); - - /// Returns all rpc urls and their aliases `[alias, url][]`. - function rpcUrls() external view returns (string[2][] memory urls); - - /// Suspends execution of the main thread for `duration` milliseconds. - function sleep(uint256 duration) external; - - // ======== Toml ======== - - /// Checks if `key` exists in a TOML table. - function keyExistsToml(string calldata toml, string calldata key) external view returns (bool); - - /// Parses a string of TOML data at `key` and coerces it to `address`. - function parseTomlAddress(string calldata toml, string calldata key) external pure returns (address); - - /// Parses a string of TOML data at `key` and coerces it to `address[]`. - function parseTomlAddressArray(string calldata toml, string calldata key) - external - pure - returns (address[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bool`. - function parseTomlBool(string calldata toml, string calldata key) external pure returns (bool); - - /// Parses a string of TOML data at `key` and coerces it to `bool[]`. - function parseTomlBoolArray(string calldata toml, string calldata key) external pure returns (bool[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes`. - function parseTomlBytes(string calldata toml, string calldata key) external pure returns (bytes memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes32`. - function parseTomlBytes32(string calldata toml, string calldata key) external pure returns (bytes32); - - /// Parses a string of TOML data at `key` and coerces it to `bytes32[]`. - function parseTomlBytes32Array(string calldata toml, string calldata key) - external - pure - returns (bytes32[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes[]`. - function parseTomlBytesArray(string calldata toml, string calldata key) external pure returns (bytes[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `int256`. - function parseTomlInt(string calldata toml, string calldata key) external pure returns (int256); - - /// Parses a string of TOML data at `key` and coerces it to `int256[]`. - function parseTomlIntArray(string calldata toml, string calldata key) external pure returns (int256[] memory); - - /// Returns an array of all the keys in a TOML table. - function parseTomlKeys(string calldata toml, string calldata key) external pure returns (string[] memory keys); - - /// Parses a string of TOML data at `key` and coerces it to `string`. - function parseTomlString(string calldata toml, string calldata key) external pure returns (string memory); - - /// Parses a string of TOML data at `key` and coerces it to `string[]`. - function parseTomlStringArray(string calldata toml, string calldata key) external pure returns (string[] memory); - - /// Parses a string of TOML data at `key` and coerces it to type array corresponding to `typeDescription`. - function parseTomlTypeArray(string calldata toml, string calldata key, string calldata typeDescription) - external - pure - returns (bytes memory); - - /// Parses a string of TOML data and coerces it to type corresponding to `typeDescription`. - function parseTomlType(string calldata toml, string calldata typeDescription) - external - pure - returns (bytes memory); - - /// Parses a string of TOML data at `key` and coerces it to type corresponding to `typeDescription`. - function parseTomlType(string calldata toml, string calldata key, string calldata typeDescription) - external - pure - returns (bytes memory); - - /// Parses a string of TOML data at `key` and coerces it to `uint256`. - function parseTomlUint(string calldata toml, string calldata key) external pure returns (uint256); - - /// Parses a string of TOML data at `key` and coerces it to `uint256[]`. - function parseTomlUintArray(string calldata toml, string calldata key) external pure returns (uint256[] memory); - - /// ABI-encodes a TOML table. - function parseToml(string calldata toml) external pure returns (bytes memory abiEncodedData); - - /// ABI-encodes a TOML table at `key`. - function parseToml(string calldata toml, string calldata key) external pure returns (bytes memory abiEncodedData); - - /// Takes serialized JSON, converts to TOML and write a serialized TOML to a file. - function writeToml(string calldata json, string calldata path) external; - - /// Takes serialized JSON, converts to TOML and write a serialized TOML table to an **existing** TOML file, replacing a value with key = - /// This is useful to replace a specific value of a TOML file, without having to parse the entire thing. - /// This cheatcode will create new keys if they didn't previously exist. - function writeToml(string calldata json, string calldata path, string calldata valueKey) external; - - // ======== Utilities ======== - - /// Returns an uint256 value bounded in given range and different from the current one. - function bound(uint256 current, uint256 min, uint256 max) external view returns (uint256); - - /// Returns an int256 value bounded in given range and different from the current one. - function bound(int256 current, int256 min, int256 max) external view returns (int256); - - /// Compute the address of a contract created with CREATE2 using the given CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer) - external - pure - returns (address); - - /// Compute the address of a contract created with CREATE2 using the default CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) external pure returns (address); - - /// Compute the address a contract will be deployed at for a given deployer address and nonce. - function computeCreateAddress(address deployer, uint256 nonce) external pure returns (address); - - /// Utility cheatcode to copy storage of `from` contract to another `to` contract. - function copyStorage(address from, address to) external; - - /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data. - /// Supports 2 different inputs: - /// 1. Name of the type (i.e. "PermitSingle"): - /// * requires previous binding generation with `forge bind-json`. - /// * bindings will be retrieved from the path configured in `foundry.toml`. - /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)"). - /// * Note: the cheatcode will use the canonical type even if the input is malformated - /// with the wrong order of elements or with extra whitespaces. - function eip712HashStruct(string calldata typeNameOrDefinition, bytes calldata abiEncodedData) - external - pure - returns (bytes32 typeHash); - - /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data. - /// Requires previous binding generation with `forge bind-json`. - /// Params: - /// * `bindingsPath`: path where the output of `forge bind-json` is stored. - /// * `typeName`: Name of the type (i.e. "PermitSingle"). - /// * `abiEncodedData`: ABI-encoded data for the struct that is being hashed. - function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) - external - pure - returns (bytes32 typeHash); - - /// Generates the hash of the canonical EIP-712 type representation. - /// Supports 2 different inputs: - /// 1. Name of the type (i.e. "Transaction"): - /// * requires previous binding generation with `forge bind-json`. - /// * bindings will be retrieved from the path configured in `foundry.toml`. - /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)"). - /// * Note: the cheatcode will output the canonical type even if the input is malformated - /// with the wrong order of elements or with extra whitespaces. - function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash); - - /// Generates the hash of the canonical EIP-712 type representation. - /// Requires previous binding generation with `forge bind-json`. - /// Params: - /// * `bindingsPath`: path where the output of `forge bind-json` is stored. - /// * `typeName`: Name of the type (i.e. "Transaction"). - function eip712HashType(string calldata bindingsPath, string calldata typeName) - external - pure - returns (bytes32 typeHash); - - /// Generates a ready-to-sign digest of human-readable typed data following the EIP-712 standard. - function eip712HashTypedData(string calldata jsonData) external pure returns (bytes32 digest); - - /// Returns ENS namehash for provided string. - function ensNamehash(string calldata name) external pure returns (bytes32); - - /// Gets the label for the specified address. - function getLabel(address account) external view returns (string memory currentLabel); - - /// Labels an address in call traces. - function label(address account, string calldata newLabel) external; - - /// Pauses collection of call traces. Useful in cases when you want to skip tracing of - /// complex calls which are not useful for debugging. - function pauseTracing() external view; - - /// Returns a random `address`. - function randomAddress() external view returns (address); - - /// Returns a random `bool`. - function randomBool() external view returns (bool); - - /// Returns a random byte array value of the given length. - function randomBytes(uint256 len) external view returns (bytes memory); - - /// Returns a random fixed-size byte array of length 4. - function randomBytes4() external view returns (bytes4); - - /// Returns a random fixed-size byte array of length 8. - function randomBytes8() external view returns (bytes8); - - /// Returns a random `int256` value. - function randomInt() external view returns (int256); - - /// Returns a random `int256` value of given bits. - function randomInt(uint256 bits) external view returns (int256); - - /// Returns a random uint256 value. - function randomUint() external view returns (uint256); - - /// Returns random uint256 value between the provided range (=min..=max). - function randomUint(uint256 min, uint256 max) external view returns (uint256); - - /// Returns a random `uint256` value of given bits. - function randomUint(uint256 bits) external view returns (uint256); - - /// Unpauses collection of call traces. - function resumeTracing() external view; - - /// Utility cheatcode to set arbitrary storage for given target address. - function setArbitraryStorage(address target) external; - - /// Utility cheatcode to set arbitrary storage for given target address and overwrite - /// any storage slots that have been previously set. - function setArbitraryStorage(address target, bool overwrite) external; - - /// Set RNG seed. - function setSeed(uint256 seed) external; - - /// Randomly shuffles an array. - function shuffle(uint256[] calldata array) external returns (uint256[] memory); - - /// Sorts an array in ascending order. - function sort(uint256[] calldata array) external returns (uint256[] memory); - - /// Encodes a `bytes` value to a base64url string. - function toBase64URL(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64url string. - function toBase64URL(string calldata data) external pure returns (string memory); - - /// Encodes a `bytes` value to a base64 string. - function toBase64(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64 string. - function toBase64(string calldata data) external pure returns (string memory); -} - -/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used -/// in tests, but it is not recommended to use these cheats in scripts. -interface Vm is VmSafe { - // ======== EVM ======== - - /// Utility cheatcode to set an EIP-2930 access list for all subsequent transactions. - function accessList(AccessListItem[] calldata access) external; - - /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. - function activeFork() external view returns (uint256 forkId); - - /// In forking mode, explicitly grant the given address cheatcode access. - function allowCheatcodes(address account) external; - - /// Sets `block.blobbasefee` - function blobBaseFee(uint256 newBlobBaseFee) external; - - /// Sets the blobhashes in the transaction. - /// Not available on EVM versions before Cancun. - /// If used on unsupported EVM versions it will revert. - function blobhashes(bytes32[] calldata hashes) external; - - /// Sets `block.chainid`. - function chainId(uint256 newChainId) external; - - /// Clears all mocked calls. - function clearMockedCalls() external; - - /// Clones a source account code, state, balance and nonce to a target account and updates in-memory EVM state. - function cloneAccount(address source, address target) external; - - /// Sets `block.coinbase`. - function coinbase(address newCoinbase) external; - - /// Marks the slots of an account and the account address as cold. - function cool(address target) external; - - /// Utility cheatcode to mark specific storage slot as cold, simulating no prior read. - function coolSlot(address target, bytes32 slot) external; - - /// Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork. - function createFork(string calldata urlOrAlias) external returns (uint256 forkId); - - /// Creates a new fork with the given endpoint and block and returns the identifier of the fork. - function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - - /// Creates a new fork with the given endpoint and at the block the given transaction was mined in, - /// replays all transaction mined in the block before the transaction, and returns the identifier of the fork. - function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - - /// Creates and also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); - - /// Creates and also selects a new fork with the given endpoint and block and returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - - /// Creates and also selects new fork with the given endpoint and at the block the given transaction was mined in, - /// replays all transaction mined in the block before the transaction, returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - - /// Sets an address' balance. - function deal(address account, uint256 newBalance) external; - - /// Removes the snapshot with the given ID created by `snapshot`. - /// Takes the snapshot ID to delete. - /// Returns `true` if the snapshot was successfully deleted. - /// Returns `false` if the snapshot does not exist. - function deleteStateSnapshot(uint256 snapshotId) external returns (bool success); - - /// Removes _all_ snapshots previously created by `snapshot`. - function deleteStateSnapshots() external; - - /// Sets `block.difficulty`. - /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead. - /// Reverts if used on unsupported EVM versions. - function difficulty(uint256 newDifficulty) external; - - /// Dump a genesis JSON file's `allocs` to disk. - function dumpState(string calldata pathToStateJson) external; - - /// Sets an address' code. - function etch(address target, bytes calldata newRuntimeBytecode) external; - - /// Sets `block.basefee`. - function fee(uint256 newBasefee) external; - - /// Gets the blockhashes from the current transaction. - /// Not available on EVM versions before Cancun. - /// If used on unsupported EVM versions it will revert. - function getBlobhashes() external view returns (bytes32[] memory hashes); - - /// Returns true if the account is marked as persistent. - function isPersistent(address account) external view returns (bool persistent); - - /// Load a genesis JSON file's `allocs` into the in-memory EVM state. - function loadAllocs(string calldata pathToAllocsJson) external; - - /// Marks that the account(s) should use persistent storage across fork swaps in a multifork setup - /// Meaning, changes made to the state of this account will be kept when switching forks. - function makePersistent(address account) external; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1) external; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1, address account2) external; - - /// See `makePersistent(address)`. - function makePersistent(address[] calldata accounts) external; - - /// Reverts a call to an address with specified revert data. - function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; - - /// Reverts a call to an address with a specific `msg.value`, with specified revert data. - function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) - external; - - /// Reverts a call to an address with specified revert data. - /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. - function mockCallRevert(address callee, bytes4 data, bytes calldata revertData) external; - - /// Reverts a call to an address with a specific `msg.value`, with specified revert data. - /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. - function mockCallRevert(address callee, uint256 msgValue, bytes4 data, bytes calldata revertData) external; - - /// Mocks a call to an address, returning specified data. - /// Calldata can either be strict or a partial match, e.g. if you only - /// pass a Solidity selector to the expected calldata, then the entire Solidity - /// function will be mocked. - function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; - - /// Mocks a call to an address with a specific `msg.value`, returning specified data. - /// Calldata match takes precedence over `msg.value` in case of ambiguity. - function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; - - /// Mocks a call to an address, returning specified data. - /// Calldata can either be strict or a partial match, e.g. if you only - /// pass a Solidity selector to the expected calldata, then the entire Solidity - /// function will be mocked. - /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. - function mockCall(address callee, bytes4 data, bytes calldata returnData) external; - - /// Mocks a call to an address with a specific `msg.value`, returning specified data. - /// Calldata match takes precedence over `msg.value` in case of ambiguity. - /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. - function mockCall(address callee, uint256 msgValue, bytes4 data, bytes calldata returnData) external; - - /// Mocks multiple calls to an address, returning specified data for each call. - function mockCalls(address callee, bytes calldata data, bytes[] calldata returnData) external; - - /// Mocks multiple calls to an address with a specific `msg.value`, returning specified data for each call. - function mockCalls(address callee, uint256 msgValue, bytes calldata data, bytes[] calldata returnData) external; - - /// Whenever a call is made to `callee` with calldata `data`, this cheatcode instead calls - /// `target` with the same calldata. This functionality is similar to a delegate call made to - /// `target` contract from `callee`. - /// Can be used to substitute a call to a function with another implementation that captures - /// the primary logic of the original function but is easier to reason about. - /// If calldata is not a strict match then partial match by selector is attempted. - function mockFunction(address callee, address target, bytes calldata data) external; - - /// Utility cheatcode to remove any EIP-2930 access list set by `accessList` cheatcode. - function noAccessList() external; - - /// Sets the *next* call's `msg.sender` to be the input address. - function prank(address msgSender) external; - - /// Sets the *next* call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. - function prank(address msgSender, address txOrigin) external; - - /// Sets the *next* delegate call's `msg.sender` to be the input address. - function prank(address msgSender, bool delegateCall) external; - - /// Sets the *next* delegate call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. - function prank(address msgSender, address txOrigin, bool delegateCall) external; - - /// Sets `block.prevrandao`. - /// Not available on EVM versions before Paris. Use `difficulty` instead. - /// If used on unsupported EVM versions it will revert. - function prevrandao(bytes32 newPrevrandao) external; - - /// Sets `block.prevrandao`. - /// Not available on EVM versions before Paris. Use `difficulty` instead. - /// If used on unsupported EVM versions it will revert. - function prevrandao(uint256 newPrevrandao) external; - - /// Reads the current `msg.sender` and `tx.origin` from state and reports if there is any active caller modification. - function readCallers() external view returns (CallerMode callerMode, address msgSender, address txOrigin); - - /// Resets the nonce of an account to 0 for EOAs and 1 for contract accounts. - function resetNonce(address account) external; - - /// Revert the state of the EVM to a previous snapshot - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted. - /// Returns `false` if the snapshot does not exist. - /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteStateSnapshot`. - function revertToState(uint256 snapshotId) external returns (bool success); - - /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted and deleted. - /// Returns `false` if the snapshot does not exist. - function revertToStateAndDelete(uint256 snapshotId) external returns (bool success); - - /// Revokes persistent status from the address, previously added via `makePersistent`. - function revokePersistent(address account) external; - - /// See `revokePersistent(address)`. - function revokePersistent(address[] calldata accounts) external; - - /// Sets `block.height`. - function roll(uint256 newHeight) external; - - /// Updates the currently active fork to given block number - /// This is similar to `roll` but for the currently active fork. - function rollFork(uint256 blockNumber) external; - - /// Updates the currently active fork to given transaction. This will `rollFork` with the number - /// of the block the transaction was mined in and replays all transaction mined before it in the block. - function rollFork(bytes32 txHash) external; - - /// Updates the given fork to given block number. - function rollFork(uint256 forkId, uint256 blockNumber) external; - - /// Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block. - function rollFork(uint256 forkId, bytes32 txHash) external; - - /// Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256 forkId) external; - - /// Set blockhash for the current block. - /// It only sets the blockhash for blocks where `block.number - 256 <= number < block.number`. - function setBlockhash(uint256 blockNumber, bytes32 blockHash) external; - - /// Sets the nonce of an account. Must be higher than the current nonce of the account. - function setNonce(address account, uint64 newNonce) external; - - /// Sets the nonce of an account to an arbitrary value. - function setNonceUnsafe(address account, uint64 newNonce) external; - - /// Snapshot capture the gas usage of the last call by name from the callee perspective. - function snapshotGasLastCall(string calldata name) external returns (uint256 gasUsed); - - /// Snapshot capture the gas usage of the last call by name in a group from the callee perspective. - function snapshotGasLastCall(string calldata group, string calldata name) external returns (uint256 gasUsed); - - /// Snapshot the current state of the evm. - /// Returns the ID of the snapshot that was created. - /// To revert a snapshot use `revertToState`. - function snapshotState() external returns (uint256 snapshotId); - - /// Snapshot capture an arbitrary numerical value by name. - /// The group name is derived from the contract name. - function snapshotValue(string calldata name, uint256 value) external; - - /// Snapshot capture an arbitrary numerical value by name in a group. - function snapshotValue(string calldata group, string calldata name, uint256 value) external; - - /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called. - function startPrank(address msgSender) external; - - /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. - function startPrank(address msgSender, address txOrigin) external; - - /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called. - function startPrank(address msgSender, bool delegateCall) external; - - /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. - function startPrank(address msgSender, address txOrigin, bool delegateCall) external; - - /// Start a snapshot capture of the current gas usage by name. - /// The group name is derived from the contract name. - function startSnapshotGas(string calldata name) external; - - /// Start a snapshot capture of the current gas usage by name in a group. - function startSnapshotGas(string calldata group, string calldata name) external; - - /// Resets subsequent calls' `msg.sender` to be `address(this)`. - function stopPrank() external; - - /// Stop the snapshot capture of the current gas by latest snapshot name, capturing the gas used since the start. - function stopSnapshotGas() external returns (uint256 gasUsed); - - /// Stop the snapshot capture of the current gas usage by name, capturing the gas used since the start. - /// The group name is derived from the contract name. - function stopSnapshotGas(string calldata name) external returns (uint256 gasUsed); - - /// Stop the snapshot capture of the current gas usage by name in a group, capturing the gas used since the start. - function stopSnapshotGas(string calldata group, string calldata name) external returns (uint256 gasUsed); - - /// Stores a value to an address' storage slot. - function store(address target, bytes32 slot, bytes32 value) external; - - /// Fetches the given transaction from the active fork and executes it on the current state. - function transact(bytes32 txHash) external; - - /// Fetches the given transaction from the given fork and executes it on the current state. - function transact(uint256 forkId, bytes32 txHash) external; - - /// Sets `tx.gasprice`. - function txGasPrice(uint256 newGasPrice) external; - - /// Utility cheatcode to mark specific storage slot as warm, simulating a prior read. - function warmSlot(address target, bytes32 slot) external; - - /// Sets `block.timestamp`. - function warp(uint256 newTimestamp) external; - - /// `deleteSnapshot` is being deprecated in favor of `deleteStateSnapshot`. It will be removed in future versions. - function deleteSnapshot(uint256 snapshotId) external returns (bool success); - - /// `deleteSnapshots` is being deprecated in favor of `deleteStateSnapshots`. It will be removed in future versions. - function deleteSnapshots() external; - - /// `revertToAndDelete` is being deprecated in favor of `revertToStateAndDelete`. It will be removed in future versions. - function revertToAndDelete(uint256 snapshotId) external returns (bool success); - - /// `revertTo` is being deprecated in favor of `revertToState`. It will be removed in future versions. - function revertTo(uint256 snapshotId) external returns (bool success); - - /// `snapshot` is being deprecated in favor of `snapshotState`. It will be removed in future versions. - function snapshot() external returns (uint256 snapshotId); - - // ======== Testing ======== - - /// Expect a call to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; - - /// Expect given number of calls to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) - external; - - /// Expects a call to an address with the specified calldata. - /// Calldata can either be a strict or a partial match. - function expectCall(address callee, bytes calldata data) external; - - /// Expects given number of calls to an address with the specified calldata. - function expectCall(address callee, bytes calldata data, uint64 count) external; - - /// Expects a call to an address with the specified `msg.value` and calldata. - function expectCall(address callee, uint256 msgValue, bytes calldata data) external; - - /// Expects given number of calls to an address with the specified `msg.value` and calldata. - function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; - - /// Expect a call to an address with the specified `msg.value`, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; - - /// Expects given number of calls to an address with the specified `msg.value`, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; - - /// Expects the deployment of the specified bytecode by the specified address using the CREATE opcode - function expectCreate(bytes calldata bytecode, address deployer) external; - - /// Expects the deployment of the specified bytecode by the specified address using the CREATE2 opcode - function expectCreate2(bytes calldata bytecode, address deployer) external; - - /// Prepare an expected anonymous log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.). - /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if - /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans). - function expectEmitAnonymous(bool checkTopic0, bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) - external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmitAnonymous( - bool checkTopic0, - bool checkTopic1, - bool checkTopic2, - bool checkTopic3, - bool checkData, - address emitter - ) external; - - /// Prepare an expected anonymous log with all topic and data checks enabled. - /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if - /// logs were emitted in the expected order with the expected topics and data. - function expectEmitAnonymous() external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmitAnonymous(address emitter) external; - - /// Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.). - /// Call this function, then emit an event, then call a function. Internally after the call, we check if - /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans). - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) - external; - - /// Prepare an expected log with all topic and data checks enabled. - /// Call this function, then emit an event, then call a function. Internally after the call, we check if - /// logs were emitted in the expected order with the expected topics and data. - function expectEmit() external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit(address emitter) external; - - /// Expect a given number of logs with the provided topics. - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, uint64 count) external; - - /// Expect a given number of logs from a specific emitter with the provided topics. - function expectEmit( - bool checkTopic1, - bool checkTopic2, - bool checkTopic3, - bool checkData, - address emitter, - uint64 count - ) external; - - /// Expect a given number of logs with all topic and data checks enabled. - function expectEmit(uint64 count) external; - - /// Expect a given number of logs from a specific emitter with all topic and data checks enabled. - function expectEmit(address emitter, uint64 count) external; - - /// Expects an error on next call that starts with the revert data. - function expectPartialRevert(bytes4 revertData) external; - - /// Expects an error on next call to reverter address, that starts with the revert data. - function expectPartialRevert(bytes4 revertData, address reverter) external; - - /// Expects an error on next call with any revert data. - function expectRevert() external; - - /// Expects an error on next call that exactly matches the revert data. - function expectRevert(bytes4 revertData) external; - - /// Expects a `count` number of reverts from the upcoming calls from the reverter address that match the revert data. - function expectRevert(bytes4 revertData, address reverter, uint64 count) external; - - /// Expects a `count` number of reverts from the upcoming calls from the reverter address that exactly match the revert data. - function expectRevert(bytes calldata revertData, address reverter, uint64 count) external; - - /// Expects an error on next call that exactly matches the revert data. - function expectRevert(bytes calldata revertData) external; - - /// Expects an error with any revert data on next call to reverter address. - function expectRevert(address reverter) external; - - /// Expects an error from reverter address on next call, with any revert data. - function expectRevert(bytes4 revertData, address reverter) external; - - /// Expects an error from reverter address on next call, that exactly matches the revert data. - function expectRevert(bytes calldata revertData, address reverter) external; - - /// Expects a `count` number of reverts from the upcoming calls with any revert data or reverter. - function expectRevert(uint64 count) external; - - /// Expects a `count` number of reverts from the upcoming calls that match the revert data. - function expectRevert(bytes4 revertData, uint64 count) external; - - /// Expects a `count` number of reverts from the upcoming calls that exactly match the revert data. - function expectRevert(bytes calldata revertData, uint64 count) external; - - /// Expects a `count` number of reverts from the upcoming calls from the reverter address. - function expectRevert(address reverter, uint64 count) external; - - /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other - /// memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. - function expectSafeMemory(uint64 min, uint64 max) external; - - /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. - /// If any other memory is written to, the test will fail. Can be called multiple times to add more ranges - /// to the set. - function expectSafeMemoryCall(uint64 min, uint64 max) external; - - /// Marks a test as skipped. Must be called at the top level of a test. - function skip(bool skipTest) external; - - /// Marks a test as skipped with a reason. Must be called at the top level of a test. - function skip(bool skipTest, string calldata reason) external; - - /// Stops all safe memory expectation in the current subcontext. - function stopExpectSafeMemory() external; - - // ======== Utilities ======== - - /// Causes the next contract creation (via new) to fail and return its initcode in the returndata buffer. - /// This allows type-safe access to the initcode payload that would be used for contract creation. - /// Example usage: - /// vm.interceptInitcode(); - /// bytes memory initcode; - /// try new MyContract(param1, param2) { assert(false); } - /// catch (bytes memory interceptedInitcode) { initcode = interceptedInitcode; } - function interceptInitcode() external; -} diff --git a/grouperBot/lib/forge-std/src/console.sol b/grouperBot/lib/forge-std/src/console.sol deleted file mode 100644 index 4fdb667..0000000 --- a/grouperBot/lib/forge-std/src/console.sol +++ /dev/null @@ -1,1560 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -library console { - address constant CONSOLE_ADDRESS = - 0x000000000000000000636F6e736F6c652e6c6f67; - - function _sendLogPayloadImplementation(bytes memory payload) internal view { - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - pop( - staticcall( - gas(), - consoleAddress, - add(payload, 32), - mload(payload), - 0, - 0 - ) - ) - } - } - - function _castToPure( - function(bytes memory) internal view fnIn - ) internal pure returns (function(bytes memory) pure fnOut) { - assembly { - fnOut := fnIn - } - } - - function _sendLogPayload(bytes memory payload) internal pure { - _castToPure(_sendLogPayloadImplementation)(payload); - } - - function log() internal pure { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function logUint(uint256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function logString(string memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function log(int256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function log(string memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint256 p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); - } - - function log(uint256 p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); - } - - function log(uint256 p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); - } - - function log(uint256 p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); - } - - function log(string memory p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function log(string memory p0, int256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); - } - - function log(bool p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); - } - - function log(address p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } -} diff --git a/grouperBot/lib/forge-std/src/console2.sol b/grouperBot/lib/forge-std/src/console2.sol deleted file mode 100644 index 03531d9..0000000 --- a/grouperBot/lib/forge-std/src/console2.sol +++ /dev/null @@ -1,4 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -import {console as console2} from "./console.sol"; diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC1155.sol b/grouperBot/lib/forge-std/src/interfaces/IERC1155.sol deleted file mode 100644 index ffc8298..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC1155.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import {IERC165} from "./IERC165.sol"; - -/// @title ERC-1155 Multi Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-1155 -/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. -interface IERC1155 is IERC165 { - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_id` argument MUST be the token type being transferred. - /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferSingle( - address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value - ); - - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_ids` argument MUST be the list of tokens being transferred. - /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferBatch( - address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values - ); - - /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. - /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". - event URI(string _value, uint256 indexed _id); - - /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. - /// - MUST revert on any other error. - /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). - /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _id ID of the token type - /// @param _value Transfer amount - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` - function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; - - /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if length of `_ids` is not the same as length of `_values`. - /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. - /// - MUST revert on any other error. - /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). - /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). - /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _ids IDs of each token type (order and length must match _values array) - /// @param _values Transfer amounts per token type (order and length must match _ids array) - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` - function safeBatchTransferFrom( - address _from, - address _to, - uint256[] calldata _ids, - uint256[] calldata _values, - bytes calldata _data - ) external; - - /// @notice Get the balance of an account's tokens. - /// @param _owner The address of the token holder - /// @param _id ID of the token - /// @return The _owner's balance of the token type requested - function balanceOf(address _owner, uint256 _id) external view returns (uint256); - - /// @notice Get the balance of multiple account/token pairs - /// @param _owners The addresses of the token holders - /// @param _ids ID of the tokens - /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) - function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) - external - view - returns (uint256[] memory); - - /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. - /// @dev MUST emit the ApprovalForAll event on success. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Queries the approval status of an operator for a given owner. - /// @param _owner The owner of the tokens - /// @param _operator Address of authorized operator - /// @return True if the operator is approved, false if not - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC165.sol b/grouperBot/lib/forge-std/src/interfaces/IERC165.sol deleted file mode 100644 index 9af4bf8..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC165.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -interface IERC165 { - /// @notice Query if a contract implements an interface - /// @param interfaceID The interface identifier, as specified in ERC-165 - /// @dev Interface identification is specified in ERC-165. This function - /// uses less than 30,000 gas. - /// @return `true` if the contract implements `interfaceID` and - /// `interfaceID` is not 0xffffffff, `false` otherwise - function supportsInterface(bytes4 interfaceID) external view returns (bool); -} diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC20.sol b/grouperBot/lib/forge-std/src/interfaces/IERC20.sol deleted file mode 100644 index ba40806..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC20.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -/// @dev Interface of the ERC20 standard as defined in the EIP. -/// @dev This includes the optional name, symbol, and decimals metadata. -interface IERC20 { - /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). - event Transfer(address indexed from, address indexed to, uint256 value); - - /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` - /// is the new allowance. - event Approval(address indexed owner, address indexed spender, uint256 value); - - /// @notice Returns the amount of tokens in existence. - function totalSupply() external view returns (uint256); - - /// @notice Returns the amount of tokens owned by `account`. - function balanceOf(address account) external view returns (uint256); - - /// @notice Moves `amount` tokens from the caller's account to `to`. - function transfer(address to, uint256 amount) external returns (bool); - - /// @notice Returns the remaining number of tokens that `spender` is allowed - /// to spend on behalf of `owner` - function allowance(address owner, address spender) external view returns (uint256); - - /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. - /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - function approve(address spender, uint256 amount) external returns (bool); - - /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. - /// `amount` is then deducted from the caller's allowance. - function transferFrom(address from, address to, uint256 amount) external returns (bool); - - /// @notice Returns the name of the token. - function name() external view returns (string memory); - - /// @notice Returns the symbol of the token. - function symbol() external view returns (string memory); - - /// @notice Returns the decimals places of the token. - function decimals() external view returns (uint8); -} diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC4626.sol b/grouperBot/lib/forge-std/src/interfaces/IERC4626.sol deleted file mode 100644 index c645a0f..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC4626.sol +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import {IERC20} from "./IERC20.sol"; - -/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in -/// https://eips.ethereum.org/EIPS/eip-4626 -interface IERC4626 is IERC20 { - event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares - ); - - /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - /// @dev - /// - MUST be an ERC-20 token contract. - /// - MUST NOT revert. - function asset() external view returns (address assetTokenAddress); - - /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. - /// @dev - /// - SHOULD include any compounding that occurs from yield. - /// - MUST be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT revert. - function totalAssets() external view returns (uint256 totalManagedAssets); - - /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - /// through a deposit call. - /// @dev - /// - MUST return a limited value if receiver is subject to some deposit limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - /// - MUST NOT revert. - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - /// in the same transaction. - /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - /// deposit would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// deposit execution, and are accounted for during deposit. - /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - /// @dev - /// - MUST return a limited value if receiver is subject to some mint limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - /// - MUST NOT revert. - function maxMint(address receiver) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - /// same transaction. - /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - /// would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by minting. - function previewMint(uint256 shares) external view returns (uint256 assets); - - /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - /// execution, and are accounted for during mint. - /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - /// Vault, through a withdrawal call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST NOT revert. - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - /// called - /// in the same transaction. - /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - /// the withdrawal would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// withdraw execution, and are accounted for during withdrawal. - /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); - - /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - /// through a redeem call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - /// - MUST NOT revert. - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - /// same transaction. - /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - /// redemption would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// redeem execution, and are accounted for during redeem. - /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); -} diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC6909.sol b/grouperBot/lib/forge-std/src/interfaces/IERC6909.sol deleted file mode 100644 index 6e11cb4..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC6909.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import {IERC165} from "./IERC165.sol"; - -/// @dev Required interface of an ERC-6909 compliant contract, as defined in -/// https://eips.ethereum.org/EIPS/eip-6909 -interface IERC6909 is IERC165 { - /// @dev Emitted when the allowance of a `spender` for an `owner` is set for a token of type `id`. - event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount); - - /// @dev Emitted when `owner` grants or revokes operator status for a `spender`. - event OperatorSet(address indexed owner, address indexed spender, bool approved); - - /// @dev Emitted when `amount` tokens of type `id` are moved from `sender` to `receiver` initiated by `caller`. - event Transfer( - address caller, address indexed sender, address indexed receiver, uint256 indexed id, uint256 amount - ); - - ///@dev Returns the amount of tokens of type `id` owned by `owner`. - function balanceOf(address owner, uint256 id) external view returns (uint256); - - /// @dev Returns the amount of tokens of type `id` that `spender` is allowed to spend on behalf of `owner`. - /// NOTE: Does not include operator allowances. - function allowance(address owner, address spender, uint256 id) external view returns (uint256); - - /// @dev Returns true if `spender` is set as an operator for `owner`. - function isOperator(address owner, address spender) external view returns (bool); - - /// @dev Sets an approval to `spender` for `amount` tokens of type `id` from the caller's tokens. - /// Must return true. - function approve(address spender, uint256 id, uint256 amount) external returns (bool); - - /// @dev Grants or revokes unlimited transfer permission of any token id to `spender` for the caller's tokens. - /// Must return true. - function setOperator(address spender, bool approved) external returns (bool); - - /// @dev Transfers `amount` of token type `id` from the caller's account to `receiver`. - /// Must return true. - function transfer(address receiver, uint256 id, uint256 amount) external returns (bool); - - /// @dev Transfers `amount` of token type `id` from `sender` to `receiver`. - /// Must return true. - function transferFrom(address sender, address receiver, uint256 id, uint256 amount) external returns (bool); -} - -/// @dev Optional extension of {IERC6909} that adds metadata functions. -interface IERC6909Metadata is IERC6909 { - /// @dev Returns the name of the token of type `id`. - function name(uint256 id) external view returns (string memory); - - /// @dev Returns the ticker symbol of the token of type `id`. - function symbol(uint256 id) external view returns (string memory); - - /// @dev Returns the number of decimals for the token of type `id`. - function decimals(uint256 id) external view returns (uint8); -} - -/// @dev Optional extension of {IERC6909} that adds content URI functions. -interface IERC6909ContentURI is IERC6909 { - /// @dev Returns URI for the contract. - function contractURI() external view returns (string memory); - - /// @dev Returns the URI for the token of type `id`. - function tokenURI(uint256 id) external view returns (string memory); -} - -/// @dev Optional extension of {IERC6909} that adds a token supply function. -interface IERC6909TokenSupply is IERC6909 { - /// @dev Returns the total supply of the token of type `id`. - function totalSupply(uint256 id) external view returns (uint256); -} diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC721.sol b/grouperBot/lib/forge-std/src/interfaces/IERC721.sol deleted file mode 100644 index 21a4a94..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC721.sol +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import {IERC165} from "./IERC165.sol"; - -/// @title ERC-721 Non-Fungible Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. -interface IERC721 is IERC165 { - /// @dev This emits when ownership of any NFT changes by any mechanism. - /// This event emits when NFTs are created (`from` == 0) and destroyed - /// (`to` == 0). Exception: during contract creation, any number of NFTs - /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the approved address for that NFT (if any) is reset to none. - event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); - - /// @dev This emits when the approved address for an NFT is changed or - /// reaffirmed. The zero address indicates there is no approved address. - /// When a Transfer event emits, this also indicates that the approved - /// address for that NFT (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); - - /// @dev This emits when an operator is enabled or disabled for an owner. - /// The operator can manage all NFTs of the owner. - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. - /// @param _owner An address for whom to query the balance - /// @return The number of NFTs owned by `_owner`, possibly zero - function balanceOf(address _owner) external view returns (uint256); - - /// @notice Find the owner of an NFT - /// @dev NFTs assigned to zero address are considered invalid, and queries - /// about them do throw. - /// @param _tokenId The identifier for an NFT - /// @return The address of the owner of the NFT - function ownerOf(uint256 _tokenId) external view returns (address); - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. When transfer is complete, this function - /// checks if `_to` is a smart contract (code size > 0). If so, it calls - /// `onERC721Received` on `_to` and throws if the return value is not - /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - /// @param data Additional data with no specified format, sent in call to `_to` - function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev This works identically to the other function with an extra data parameter, - /// except this function just sets data to "". - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE - /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE - /// THEY MAY BE PERMANENTLY LOST - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function transferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Change or reaffirm the approved address for an NFT - /// @dev The zero address indicates there is no approved address. - /// Throws unless `msg.sender` is the current NFT owner, or an authorized - /// operator of the current owner. - /// @param _approved The new approved NFT controller - /// @param _tokenId The NFT to approve - function approve(address _approved, uint256 _tokenId) external payable; - - /// @notice Enable or disable approval for a third party ("operator") to manage - /// all of `msg.sender`'s assets - /// @dev Emits the ApprovalForAll event. The contract MUST allow - /// multiple operators per owner. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Get the approved address for a single NFT - /// @dev Throws if `_tokenId` is not a valid NFT. - /// @param _tokenId The NFT to find the approved address for - /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) external view returns (address); - - /// @notice Query if an address is an authorized operator for another address - /// @param _owner The address that owns the NFTs - /// @param _operator The address that acts on behalf of the owner - /// @return True if `_operator` is an approved operator for `_owner`, false otherwise - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} - -/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. -interface IERC721TokenReceiver { - /// @notice Handle the receipt of an NFT - /// @dev The ERC721 smart contract calls this function on the recipient - /// after a `transfer`. This function MAY throw to revert and reject the - /// transfer. Return of other than the magic value MUST result in the - /// transaction being reverted. - /// Note: the contract address is always the message sender. - /// @param _operator The address which called `safeTransferFrom` function - /// @param _from The address which previously owned the token - /// @param _tokenId The NFT identifier which is being transferred - /// @param _data Additional data with no specified format - /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - /// unless throwing - function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) - external - returns (bytes4); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. -interface IERC721Metadata is IERC721 { - /// @notice A descriptive name for a collection of NFTs in this contract - function name() external view returns (string memory _name); - - /// @notice An abbreviated name for NFTs in this contract - function symbol() external view returns (string memory _symbol); - - /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. - /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC - /// 3986. The URI may point to a JSON file that conforms to the "ERC721 - /// Metadata JSON Schema". - function tokenURI(uint256 _tokenId) external view returns (string memory); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x780e9d63. -interface IERC721Enumerable is IERC721 { - /// @notice Count NFTs tracked by this contract - /// @return A count of valid NFTs tracked by this contract, where each one of - /// them has an assigned and queryable owner not equal to the zero address - function totalSupply() external view returns (uint256); - - /// @notice Enumerate valid NFTs - /// @dev Throws if `_index` >= `totalSupply()`. - /// @param _index A counter less than `totalSupply()` - /// @return The token identifier for the `_index`th NFT, - /// (sort order not specified) - function tokenByIndex(uint256 _index) external view returns (uint256); - - /// @notice Enumerate NFTs assigned to an owner - /// @dev Throws if `_index` >= `balanceOf(_owner)` or if - /// `_owner` is the zero address, representing invalid NFTs. - /// @param _owner An address where we are interested in NFTs owned by them - /// @param _index A counter less than `balanceOf(_owner)` - /// @return The token identifier for the `_index`th NFT assigned to `_owner`, - /// (sort order not specified) - function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); -} diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC7540.sol b/grouperBot/lib/forge-std/src/interfaces/IERC7540.sol deleted file mode 100644 index 91a38ca..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC7540.sol +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import {IERC7575} from "./IERC7575.sol"; - -/// @dev Interface of the base operator logic of ERC7540, as defined in -/// https://eips.ethereum.org/EIPS/eip-7540 -interface IERC7540Operator { - /** - * @dev The event emitted when an operator is set. - * - * @param controller The address of the controller. - * @param operator The address of the operator. - * @param approved The approval status. - */ - event OperatorSet(address indexed controller, address indexed operator, bool approved); - - /** - * @dev Sets or removes an operator for the caller. - * - * @param operator The address of the operator. - * @param approved The approval status. - * @return Whether the call was executed successfully or not - */ - function setOperator(address operator, bool approved) external returns (bool); - - /** - * @dev Returns `true` if the `operator` is approved as an operator for an `controller`. - * - * @param controller The address of the controller. - * @param operator The address of the operator. - * @return status The approval status - */ - function isOperator(address controller, address operator) external view returns (bool status); -} - -/// @dev Interface of the asynchronous deposit Vault interface of ERC7540, as defined in -/// https://eips.ethereum.org/EIPS/eip-7540 -interface IERC7540Deposit is IERC7540Operator { - event DepositRequest( - address indexed controller, address indexed owner, uint256 indexed requestId, address sender, uint256 assets - ); - /** - * @dev Transfers assets from sender into the Vault and submits a Request for asynchronous deposit. - * - * - MUST support ERC-20 approve / transferFrom on asset as a deposit Request flow. - * - MUST revert if all of assets cannot be requested for deposit. - * - owner MUST be msg.sender unless some unspecified explicit approval is given by the caller, - * approval of ERC-20 tokens from owner to sender is NOT enough. - * - * @param assets the amount of deposit assets to transfer from owner - * @param controller the controller of the request who will be able to operate the request - * @param owner the source of the deposit assets - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault's underlying asset token. - */ - - function requestDeposit(uint256 assets, address controller, address owner) external returns (uint256 requestId); - - /** - * @dev Returns the amount of requested assets in Pending state. - * - * - MUST NOT include any assets in Claimable state for deposit or mint. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. - */ - function pendingDepositRequest(uint256 requestId, address controller) - external - view - returns (uint256 pendingAssets); - - /** - * @dev Returns the amount of requested assets in Claimable state for the controller to deposit or mint. - * - * - MUST NOT include any assets in Pending state. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. - */ - function claimableDepositRequest(uint256 requestId, address controller) - external - view - returns (uint256 claimableAssets); - - /** - * @dev Mints shares Vault shares to receiver by claiming the Request of the controller. - * - * - MUST emit the Deposit event. - * - controller MUST equal msg.sender unless the controller has approved the msg.sender as an operator. - */ - function deposit(uint256 assets, address receiver, address controller) external returns (uint256 shares); - - /** - * @dev Mints exactly shares Vault shares to receiver by claiming the Request of the controller. - * - * - MUST emit the Deposit event. - * - controller MUST equal msg.sender unless the controller has approved the msg.sender as an operator. - */ - function mint(uint256 shares, address receiver, address controller) external returns (uint256 assets); -} - -/// @dev Interface of the asynchronous deposit Vault interface of ERC7540, as defined in -/// https://eips.ethereum.org/EIPS/eip-7540 -interface IERC7540Redeem is IERC7540Operator { - event RedeemRequest( - address indexed controller, address indexed owner, uint256 indexed requestId, address sender, uint256 assets - ); - - /** - * @dev Assumes control of shares from sender into the Vault and submits a Request for asynchronous redeem. - * - * - MUST support a redeem Request flow where the control of shares is taken from sender directly - * where msg.sender has ERC-20 approval over the shares of owner. - * - MUST revert if all of shares cannot be requested for redeem. - * - * @param shares the amount of shares to be redeemed to transfer from owner - * @param controller the controller of the request who will be able to operate the request - * @param owner the source of the shares to be redeemed - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault's share token. - */ - function requestRedeem(uint256 shares, address controller, address owner) external returns (uint256 requestId); - - /** - * @dev Returns the amount of requested shares in Pending state. - * - * - MUST NOT include any shares in Claimable state for redeem or withdraw. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. - */ - function pendingRedeemRequest(uint256 requestId, address controller) - external - view - returns (uint256 pendingShares); - - /** - * @dev Returns the amount of requested shares in Claimable state for the controller to redeem or withdraw. - * - * - MUST NOT include any shares in Pending state for redeem or withdraw. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. - */ - function claimableRedeemRequest(uint256 requestId, address controller) - external - view - returns (uint256 claimableShares); -} - -/// @dev Interface of the fully asynchronous Vault interface of ERC7540, as defined in -/// https://eips.ethereum.org/EIPS/eip-7540 -interface IERC7540 is IERC7540Deposit, IERC7540Redeem, IERC7575 {} diff --git a/grouperBot/lib/forge-std/src/interfaces/IERC7575.sol b/grouperBot/lib/forge-std/src/interfaces/IERC7575.sol deleted file mode 100644 index 207e3e7..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IERC7575.sol +++ /dev/null @@ -1,241 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import {IERC165} from "./IERC165.sol"; - -/// @dev Interface of the ERC7575 "Multi-Asset ERC-4626 Vaults", as defined in -/// https://eips.ethereum.org/EIPS/eip-7575 -interface IERC7575 is IERC165 { - event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); - event Withdraw( - address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares - ); - - /** - * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - * - * - MUST be an ERC-20 token contract. - * - MUST NOT revert. - */ - function asset() external view returns (address assetTokenAddress); - - /** - * @dev Returns the address of the share token - * - * - MUST be an ERC-20 token contract. - * - MUST NOT revert. - */ - function share() external view returns (address shareTokenAddress); - - /** - * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - * scenario where all the conditions are met. - * - * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - * - MUST NOT revert. - * - * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - * from. - */ - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - * scenario where all the conditions are met. - * - * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - * - MUST NOT revert. - * - * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - * from. - */ - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Returns the total amount of the underlying asset that is “managed” by Vault. - * - * - SHOULD include any compounding that occurs from yield. - * - MUST be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT revert. - */ - function totalAssets() external view returns (uint256 totalManagedAssets); - - /** - * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - * through a deposit call. - * - * - MUST return a limited value if receiver is subject to some deposit limit. - * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - * - MUST NOT revert. - */ - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - * current on-chain conditions. - * - * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - * in the same transaction. - * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - * deposit would be accepted, regardless if the user has enough tokens approved, etc. - * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by depositing. - */ - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - * - * - MUST emit the Deposit event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * deposit execution, and are accounted for during deposit. - * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - * approving enough underlying tokens to the Vault contract, etc). - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - */ - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /** - * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - * - MUST return a limited value if receiver is subject to some mint limit. - * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - * - MUST NOT revert. - */ - function maxMint(address receiver) external view returns (uint256 maxShares); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - * current on-chain conditions. - * - * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - * same transaction. - * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - * would be accepted, regardless if the user has enough tokens approved, etc. - * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by minting. - */ - function previewMint(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - * - * - MUST emit the Deposit event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - * execution, and are accounted for during mint. - * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - * approving enough underlying tokens to the Vault contract, etc). - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - */ - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /** - * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - * Vault, through a withdraw call. - * - * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - * - MUST NOT revert. - */ - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - * given current on-chain conditions. - * - * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - * called - * in the same transaction. - * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - * the withdrawal would be accepted, regardless if the user has enough shares, etc. - * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by depositing. - */ - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. - * - * - MUST emit the Withdraw event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * withdraw execution, and are accounted for during withdraw. - * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - * not having enough shares, etc). - * - * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - * Those methods should be performed separately. - */ - function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); - - /** - * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - * through a redeem call. - * - * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - * - MUST NOT revert. - */ - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - * given current on-chain conditions. - * - * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - * same transaction. - * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - * redemption would be accepted, regardless if the user has enough shares, etc. - * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by redeeming. - */ - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. - * - * - MUST emit the Withdraw event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * redeem execution, and are accounted for during redeem. - * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - * not having enough shares, etc). - * - * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - * Those methods should be performed separately. - */ - function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); -} - -/// @dev Interface of the ERC20 share token, as defined in -/// https://eips.ethereum.org/EIPS/eip-7575 -interface IERC7575Share is IERC165 { - event VaultUpdate(address indexed asset, address vault); - - /** - * @dev Returns the address of the Vault for the given asset. - * - * @param asset the ERC-20 token to deposit with into the Vault - */ - function vault(address asset) external view returns (address); -} diff --git a/grouperBot/lib/forge-std/src/interfaces/IMulticall3.sol b/grouperBot/lib/forge-std/src/interfaces/IMulticall3.sol deleted file mode 100644 index 0d031b7..0000000 --- a/grouperBot/lib/forge-std/src/interfaces/IMulticall3.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -interface IMulticall3 { - struct Call { - address target; - bytes callData; - } - - struct Call3 { - address target; - bool allowFailure; - bytes callData; - } - - struct Call3Value { - address target; - bool allowFailure; - uint256 value; - bytes callData; - } - - struct Result { - bool success; - bytes returnData; - } - - function aggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes[] memory returnData); - - function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); - - function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); - - function blockAndAggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); - - function getBasefee() external view returns (uint256 basefee); - - function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); - - function getBlockNumber() external view returns (uint256 blockNumber); - - function getChainId() external view returns (uint256 chainid); - - function getCurrentBlockCoinbase() external view returns (address coinbase); - - function getCurrentBlockDifficulty() external view returns (uint256 difficulty); - - function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); - - function getCurrentBlockTimestamp() external view returns (uint256 timestamp); - - function getEthBalance(address addr) external view returns (uint256 balance); - - function getLastBlockHash() external view returns (bytes32 blockHash); - - function tryAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (Result[] memory returnData); - - function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); -} diff --git a/grouperBot/lib/forge-std/src/safeconsole.sol b/grouperBot/lib/forge-std/src/safeconsole.sol deleted file mode 100644 index 87c475a..0000000 --- a/grouperBot/lib/forge-std/src/safeconsole.sol +++ /dev/null @@ -1,13937 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -/// @author philogy -/// @dev Code generated automatically by script. -library safeconsole { - uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67; - - // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374) - // for the view-to-pure log trick. - function _sendLogPayload(uint256 offset, uint256 size) private pure { - function(uint256, uint256) internal view fnIn = _sendLogPayloadView; - function(uint256, uint256) internal pure pureSendLogPayload; - /// @solidity memory-safe-assembly - assembly { - pureSendLogPayload := fnIn - } - pureSendLogPayload(offset, size); - } - - function _sendLogPayloadView(uint256 offset, uint256 size) private view { - /// @solidity memory-safe-assembly - assembly { - pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0)) - } - } - - function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure { - function(uint256, uint256, uint256) internal view fnIn = _memcopyView; - function(uint256, uint256, uint256) internal pure pureMemcopy; - /// @solidity memory-safe-assembly - assembly { - pureMemcopy := fnIn - } - pureMemcopy(fromOffset, toOffset, length); - } - - function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view { - /// @solidity memory-safe-assembly - assembly { - pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length)) - } - } - - function logMemory(uint256 offset, uint256 length) internal pure { - if (offset >= 0x60) { - // Sufficient memory before slice to prepare call header. - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(sub(offset, 0x60)) - m1 := mload(sub(offset, 0x40)) - m2 := mload(sub(offset, 0x20)) - // Selector of `log(bytes)`. - mstore(sub(offset, 0x60), 0x0be77f56) - mstore(sub(offset, 0x40), 0x20) - mstore(sub(offset, 0x20), length) - } - _sendLogPayload(offset - 0x44, length + 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(sub(offset, 0x60), m0) - mstore(sub(offset, 0x40), m1) - mstore(sub(offset, 0x20), m2) - } - } else { - // Insufficient space, so copy slice forward, add header and reverse. - bytes32 m0; - bytes32 m1; - bytes32 m2; - uint256 endOffset = offset + length; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(add(endOffset, 0x00)) - m1 := mload(add(endOffset, 0x20)) - m2 := mload(add(endOffset, 0x40)) - } - _memcopy(offset, offset + 0x60, length); - /// @solidity memory-safe-assembly - assembly { - // Selector of `log(bytes)`. - mstore(add(offset, 0x00), 0x0be77f56) - mstore(add(offset, 0x20), 0x20) - mstore(add(offset, 0x40), length) - } - _sendLogPayload(offset + 0x1c, length + 0x44); - _memcopy(offset + 0x60, offset, length); - /// @solidity memory-safe-assembly - assembly { - mstore(add(endOffset, 0x00), m0) - mstore(add(endOffset, 0x20), m1) - mstore(add(endOffset, 0x40), m2) - } - } - } - - function log(address p0) internal pure { - bytes32 m0; - bytes32 m1; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(address)`. - mstore(0x00, 0x2c2ecbc2) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(bool p0) internal pure { - bytes32 m0; - bytes32 m1; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(bool)`. - mstore(0x00, 0x32458eed) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(uint256 p0) internal pure { - bytes32 m0; - bytes32 m1; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(uint256)`. - mstore(0x00, 0xf82c50f1) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(bytes32 p0) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(string)`. - mstore(0x00, 0x41304fac) - mstore(0x20, 0x20) - writeString(0x40, p0) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,address)`. - mstore(0x00, 0xdaf0d4aa) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,bool)`. - mstore(0x00, 0x75b605d3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,uint256)`. - mstore(0x00, 0x8309e8a8) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,string)`. - mstore(0x00, 0x759f86bb) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,address)`. - mstore(0x00, 0x853c4849) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,bool)`. - mstore(0x00, 0x2a110e83) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,uint256)`. - mstore(0x00, 0x399174d3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,string)`. - mstore(0x00, 0x8feac525) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,address)`. - mstore(0x00, 0x69276c86) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,bool)`. - mstore(0x00, 0x1c9d7eb3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,uint256)`. - mstore(0x00, 0xf666715a) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,string)`. - mstore(0x00, 0x643fd0df) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,address)`. - mstore(0x00, 0x319af333) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,bool)`. - mstore(0x00, 0xc3b55635) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,uint256)`. - mstore(0x00, 0xb60e72cc) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,string)`. - mstore(0x00, 0x4b5c4277) - mstore(0x20, 0x40) - mstore(0x40, 0x80) - writeString(0x60, p0) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,address)`. - mstore(0x00, 0x018c84c2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,bool)`. - mstore(0x00, 0xf2a66286) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,uint256)`. - mstore(0x00, 0x17fe6185) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,address,string)`. - mstore(0x00, 0x007150be) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,address)`. - mstore(0x00, 0xf11699ed) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,bool)`. - mstore(0x00, 0xeb830c92) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,uint256)`. - mstore(0x00, 0x9c4f99fb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,bool,string)`. - mstore(0x00, 0x212255cc) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,address)`. - mstore(0x00, 0x7bc0d848) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,bool)`. - mstore(0x00, 0x678209a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,uint256)`. - mstore(0x00, 0xb69bcaf6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,uint256,string)`. - mstore(0x00, 0xa1f2e8aa) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,address)`. - mstore(0x00, 0xf08744e8) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,bool)`. - mstore(0x00, 0xcf020fb1) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,uint256)`. - mstore(0x00, 0x67dd6ff1) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(address,string,string)`. - mstore(0x00, 0xfb772265) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bool p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,address)`. - mstore(0x00, 0xd2763667) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,bool)`. - mstore(0x00, 0x18c9c746) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,uint256)`. - mstore(0x00, 0x5f7b9afb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,address,string)`. - mstore(0x00, 0xde9a9270) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,address)`. - mstore(0x00, 0x1078f68d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,bool)`. - mstore(0x00, 0x50709698) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,uint256)`. - mstore(0x00, 0x12f21602) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,bool,string)`. - mstore(0x00, 0x2555fa46) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,address)`. - mstore(0x00, 0x088ef9d2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,bool)`. - mstore(0x00, 0xe8defba9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,uint256)`. - mstore(0x00, 0x37103367) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,uint256,string)`. - mstore(0x00, 0xc3fc3970) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,address)`. - mstore(0x00, 0x9591b953) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,bool)`. - mstore(0x00, 0xdbb4c247) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,uint256)`. - mstore(0x00, 0x1093ee11) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(bool,string,string)`. - mstore(0x00, 0xb076847f) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(uint256 p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,address)`. - mstore(0x00, 0xbcfd9be0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,bool)`. - mstore(0x00, 0x9b6ec042) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,uint256)`. - mstore(0x00, 0x5a9b5ed5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,address,string)`. - mstore(0x00, 0x63cb41f9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,address)`. - mstore(0x00, 0x35085f7b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,bool)`. - mstore(0x00, 0x20718650) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,uint256)`. - mstore(0x00, 0x20098014) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,bool,string)`. - mstore(0x00, 0x85775021) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,address)`. - mstore(0x00, 0x5c96b331) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,bool)`. - mstore(0x00, 0x4766da72) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,uint256)`. - mstore(0x00, 0xd1ed7a3c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,uint256,string)`. - mstore(0x00, 0x71d04af2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,address)`. - mstore(0x00, 0x7afac959) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,bool)`. - mstore(0x00, 0x4ceda75a) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,uint256)`. - mstore(0x00, 0x37aa7d4c) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(uint256,string,string)`. - mstore(0x00, 0xb115611f) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,address)`. - mstore(0x00, 0xfcec75e0) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,bool)`. - mstore(0x00, 0xc91d5ed4) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,uint256)`. - mstore(0x00, 0x0d26b925) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,address,string)`. - mstore(0x00, 0xe0e9ad4f) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,address)`. - mstore(0x00, 0x932bbb38) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,bool)`. - mstore(0x00, 0x850b7ad6) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,uint256)`. - mstore(0x00, 0xc95958d6) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,bool,string)`. - mstore(0x00, 0xe298f47d) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,address)`. - mstore(0x00, 0x1c7ec448) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,bool)`. - mstore(0x00, 0xca7733b1) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,uint256)`. - mstore(0x00, 0xca47c4eb) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,uint256,string)`. - mstore(0x00, 0x5970e089) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,address)`. - mstore(0x00, 0x95ed0195) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,bool)`. - mstore(0x00, 0xb0e0f9b5) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,uint256)`. - mstore(0x00, 0x5821efa1) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - // Selector of `log(string,string,string)`. - mstore(0x00, 0x2ced7cef) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, 0xe0) - writeString(0x80, p0) - writeString(0xc0, p1) - writeString(0x100, p2) - } - _sendLogPayload(0x1c, 0x124); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - } - } - - function log(address p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,address)`. - mstore(0x00, 0x665bf134) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,bool)`. - mstore(0x00, 0x0e378994) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,uint256)`. - mstore(0x00, 0x94250d77) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,address,string)`. - mstore(0x00, 0xf808da20) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,address)`. - mstore(0x00, 0x9f1bc36e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,bool)`. - mstore(0x00, 0x2cd4134a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,uint256)`. - mstore(0x00, 0x3971e78c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,bool,string)`. - mstore(0x00, 0xaa6540c8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,address)`. - mstore(0x00, 0x8da6def5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,bool)`. - mstore(0x00, 0x9b4254e2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,uint256)`. - mstore(0x00, 0xbe553481) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,uint256,string)`. - mstore(0x00, 0xfdb4f990) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,address)`. - mstore(0x00, 0x8f736d16) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,bool)`. - mstore(0x00, 0x6f1a594e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,uint256)`. - mstore(0x00, 0xef1cefe7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,address,string,string)`. - mstore(0x00, 0x21bdaf25) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,address)`. - mstore(0x00, 0x660375dd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,bool)`. - mstore(0x00, 0xa6f50b0f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,uint256)`. - mstore(0x00, 0xa75c59de) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,address,string)`. - mstore(0x00, 0x2dd778e6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,address)`. - mstore(0x00, 0xcf394485) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,bool)`. - mstore(0x00, 0xcac43479) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,uint256)`. - mstore(0x00, 0x8c4e5de6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,bool,string)`. - mstore(0x00, 0xdfc4a2e8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,address)`. - mstore(0x00, 0xccf790a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,bool)`. - mstore(0x00, 0xc4643e20) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,uint256)`. - mstore(0x00, 0x386ff5f4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,uint256,string)`. - mstore(0x00, 0x0aa6cfad) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,address)`. - mstore(0x00, 0x19fd4956) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,bool)`. - mstore(0x00, 0x50ad461d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,uint256)`. - mstore(0x00, 0x80e6a20b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,bool,string,string)`. - mstore(0x00, 0x475c5c33) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,address)`. - mstore(0x00, 0x478d1c62) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,bool)`. - mstore(0x00, 0xa1bcc9b3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,uint256)`. - mstore(0x00, 0x100f650e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,address,string)`. - mstore(0x00, 0x1da986ea) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,address)`. - mstore(0x00, 0xa31bfdcc) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,bool)`. - mstore(0x00, 0x3bf5e537) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,uint256)`. - mstore(0x00, 0x22f6b999) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,bool,string)`. - mstore(0x00, 0xc5ad85f9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,address)`. - mstore(0x00, 0x20e3984d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,bool)`. - mstore(0x00, 0x66f1bc67) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,uint256)`. - mstore(0x00, 0x34f0e636) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,uint256,string)`. - mstore(0x00, 0x4a28c017) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,address)`. - mstore(0x00, 0x5c430d47) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,bool)`. - mstore(0x00, 0xcf18105c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,uint256)`. - mstore(0x00, 0xbf01f891) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,uint256,string,string)`. - mstore(0x00, 0x88a8c406) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,address)`. - mstore(0x00, 0x0d36fa20) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,bool)`. - mstore(0x00, 0x0df12b76) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,uint256)`. - mstore(0x00, 0x457fe3cf) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,address,string)`. - mstore(0x00, 0xf7e36245) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,address)`. - mstore(0x00, 0x205871c2) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,bool)`. - mstore(0x00, 0x5f1d5c9f) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,uint256)`. - mstore(0x00, 0x515e38b6) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,bool,string)`. - mstore(0x00, 0xbc0b61fe) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,address)`. - mstore(0x00, 0x63183678) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,bool)`. - mstore(0x00, 0x0ef7e050) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,uint256)`. - mstore(0x00, 0x1dc8e1b8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,uint256,string)`. - mstore(0x00, 0x448830a8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,address)`. - mstore(0x00, 0xa04e2f87) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,bool)`. - mstore(0x00, 0x35a5071f) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,uint256)`. - mstore(0x00, 0x159f8927) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(address,string,string,string)`. - mstore(0x00, 0x5d02c50b) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bool p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,address)`. - mstore(0x00, 0x1d14d001) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,bool)`. - mstore(0x00, 0x46600be0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,uint256)`. - mstore(0x00, 0x0c66d1be) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,address,string)`. - mstore(0x00, 0xd812a167) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,address)`. - mstore(0x00, 0x1c41a336) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,bool)`. - mstore(0x00, 0x6a9c478b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,uint256)`. - mstore(0x00, 0x07831502) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,bool,string)`. - mstore(0x00, 0x4a66cb34) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,address)`. - mstore(0x00, 0x136b05dd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,bool)`. - mstore(0x00, 0xd6019f1c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,uint256)`. - mstore(0x00, 0x7bf181a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,uint256,string)`. - mstore(0x00, 0x51f09ff8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,address)`. - mstore(0x00, 0x6f7c603e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,bool)`. - mstore(0x00, 0xe2bfd60b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,uint256)`. - mstore(0x00, 0xc21f64c7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,address,string,string)`. - mstore(0x00, 0xa73c1db6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,address)`. - mstore(0x00, 0xf4880ea4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,bool)`. - mstore(0x00, 0xc0a302d8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,uint256)`. - mstore(0x00, 0x4c123d57) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,address,string)`. - mstore(0x00, 0xa0a47963) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,address)`. - mstore(0x00, 0x8c329b1a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,bool)`. - mstore(0x00, 0x3b2a5ce0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,uint256)`. - mstore(0x00, 0x6d7045c1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,bool,string)`. - mstore(0x00, 0x2ae408d4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,address)`. - mstore(0x00, 0x54a7a9a0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,bool)`. - mstore(0x00, 0x619e4d0e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,uint256)`. - mstore(0x00, 0x0bb00eab) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,uint256,string)`. - mstore(0x00, 0x7dd4d0e0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,address)`. - mstore(0x00, 0xf9ad2b89) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,bool)`. - mstore(0x00, 0xb857163a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,uint256)`. - mstore(0x00, 0xe3a9ca2f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,bool,string,string)`. - mstore(0x00, 0x6d1e8751) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,address)`. - mstore(0x00, 0x26f560a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,bool)`. - mstore(0x00, 0xb4c314ff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,uint256)`. - mstore(0x00, 0x1537dc87) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,address,string)`. - mstore(0x00, 0x1bb3b09a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,address)`. - mstore(0x00, 0x9acd3616) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,bool)`. - mstore(0x00, 0xceb5f4d7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,uint256)`. - mstore(0x00, 0x7f9bbca2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,bool,string)`. - mstore(0x00, 0x9143dbb1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,address)`. - mstore(0x00, 0x00dd87b9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,bool)`. - mstore(0x00, 0xbe984353) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,uint256)`. - mstore(0x00, 0x374bb4b2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,uint256,string)`. - mstore(0x00, 0x8e69fb5d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,address)`. - mstore(0x00, 0xfedd1fff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,bool)`. - mstore(0x00, 0xe5e70b2b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,uint256)`. - mstore(0x00, 0x6a1199e2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,uint256,string,string)`. - mstore(0x00, 0xf5bc2249) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,address)`. - mstore(0x00, 0x2b2b18dc) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,bool)`. - mstore(0x00, 0x6dd434ca) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,uint256)`. - mstore(0x00, 0xa5cada94) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,address,string)`. - mstore(0x00, 0x12d6c788) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,address)`. - mstore(0x00, 0x538e06ab) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,bool)`. - mstore(0x00, 0xdc5e935b) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,uint256)`. - mstore(0x00, 0x1606a393) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,bool,string)`. - mstore(0x00, 0x483d0416) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,address)`. - mstore(0x00, 0x1596a1ce) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,bool)`. - mstore(0x00, 0x6b0e5d53) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,uint256)`. - mstore(0x00, 0x28863fcb) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,uint256,string)`. - mstore(0x00, 0x1ad96de6) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,address)`. - mstore(0x00, 0x97d394d8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,bool)`. - mstore(0x00, 0x1e4b87e5) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,uint256)`. - mstore(0x00, 0x7be0c3eb) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(bool,string,string,string)`. - mstore(0x00, 0x1762e32a) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(uint256 p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,address)`. - mstore(0x00, 0x2488b414) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,bool)`. - mstore(0x00, 0x091ffaf5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,uint256)`. - mstore(0x00, 0x736efbb6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,address,string)`. - mstore(0x00, 0x031c6f73) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,address)`. - mstore(0x00, 0xef72c513) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,bool)`. - mstore(0x00, 0xe351140f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,uint256)`. - mstore(0x00, 0x5abd992a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,bool,string)`. - mstore(0x00, 0x90fb06aa) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,address)`. - mstore(0x00, 0x15c127b5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,bool)`. - mstore(0x00, 0x5f743a7c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,uint256)`. - mstore(0x00, 0x0c9cd9c1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,uint256,string)`. - mstore(0x00, 0xddb06521) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,address)`. - mstore(0x00, 0x9cba8fff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,bool)`. - mstore(0x00, 0xcc32ab07) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,uint256)`. - mstore(0x00, 0x46826b5d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,address,string,string)`. - mstore(0x00, 0x3e128ca3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,address)`. - mstore(0x00, 0xa1ef4cbb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,bool)`. - mstore(0x00, 0x454d54a5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,uint256)`. - mstore(0x00, 0x078287f5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,address,string)`. - mstore(0x00, 0xade052c7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,address)`. - mstore(0x00, 0x69640b59) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,bool)`. - mstore(0x00, 0xb6f577a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,uint256)`. - mstore(0x00, 0x7464ce23) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,bool,string)`. - mstore(0x00, 0xdddb9561) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,address)`. - mstore(0x00, 0x88cb6041) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,bool)`. - mstore(0x00, 0x91a02e2a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,uint256)`. - mstore(0x00, 0xc6acc7a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,uint256,string)`. - mstore(0x00, 0xde03e774) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,address)`. - mstore(0x00, 0xef529018) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,bool)`. - mstore(0x00, 0xeb928d7f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,uint256)`. - mstore(0x00, 0x2c1d0746) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,bool,string,string)`. - mstore(0x00, 0x68c8b8bd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,address)`. - mstore(0x00, 0x56a5d1b1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,bool)`. - mstore(0x00, 0x15cac476) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,uint256)`. - mstore(0x00, 0x88f6e4b2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,address,string)`. - mstore(0x00, 0x6cde40b8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,address)`. - mstore(0x00, 0x9a816a83) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,bool)`. - mstore(0x00, 0xab085ae6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,uint256)`. - mstore(0x00, 0xeb7f6fd2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,bool,string)`. - mstore(0x00, 0xa5b4fc99) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,address)`. - mstore(0x00, 0xfa8185af) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,bool)`. - mstore(0x00, 0xc598d185) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - /// @solidity memory-safe-assembly - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,uint256)`. - mstore(0x00, 0x193fb800) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,uint256,string)`. - mstore(0x00, 0x59cfcbe3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,address)`. - mstore(0x00, 0x42d21db7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,bool)`. - mstore(0x00, 0x7af6ab25) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,uint256)`. - mstore(0x00, 0x5da297eb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,uint256,string,string)`. - mstore(0x00, 0x27d8afd2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,address)`. - mstore(0x00, 0x6168ed61) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,bool)`. - mstore(0x00, 0x90c30a56) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,uint256)`. - mstore(0x00, 0xe8d3018d) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,address,string)`. - mstore(0x00, 0x9c3adfa1) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,address)`. - mstore(0x00, 0xae2ec581) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,bool)`. - mstore(0x00, 0xba535d9c) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,uint256)`. - mstore(0x00, 0xcf009880) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,bool,string)`. - mstore(0x00, 0xd2d423cd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,address)`. - mstore(0x00, 0x3b2279b4) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,bool)`. - mstore(0x00, 0x691a8f74) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,uint256)`. - mstore(0x00, 0x82c25b74) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,uint256,string)`. - mstore(0x00, 0xb7b914ca) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,address)`. - mstore(0x00, 0xd583c602) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,bool)`. - mstore(0x00, 0xb3a6b6bd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,uint256)`. - mstore(0x00, 0xb028c9bd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(uint256,string,string,string)`. - mstore(0x00, 0x21ad0683) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,address)`. - mstore(0x00, 0xed8f28f6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,bool)`. - mstore(0x00, 0xb59dbd60) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,uint256)`. - mstore(0x00, 0x8ef3f399) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,address,string)`. - mstore(0x00, 0x800a1c67) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,address)`. - mstore(0x00, 0x223603bd) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,bool)`. - mstore(0x00, 0x79884c2b) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,uint256)`. - mstore(0x00, 0x3e9f866a) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,bool,string)`. - mstore(0x00, 0x0454c079) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,address)`. - mstore(0x00, 0x63fb8bc5) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,bool)`. - mstore(0x00, 0xfc4845f0) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,uint256)`. - mstore(0x00, 0xf8f51b1e) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,uint256,string)`. - mstore(0x00, 0x5a477632) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,address)`. - mstore(0x00, 0xaabc9a31) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,bool)`. - mstore(0x00, 0x5f15d28c) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,uint256)`. - mstore(0x00, 0x91d1112e) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,address,string,string)`. - mstore(0x00, 0x245986f2) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,address)`. - mstore(0x00, 0x33e9dd1d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,bool)`. - mstore(0x00, 0x958c28c6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,uint256)`. - mstore(0x00, 0x5d08bb05) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,address,string)`. - mstore(0x00, 0x2d8e33a4) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,address)`. - mstore(0x00, 0x7190a529) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,bool)`. - mstore(0x00, 0x895af8c5) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,uint256)`. - mstore(0x00, 0x8e3f78a9) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,bool,string)`. - mstore(0x00, 0x9d22d5dd) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,address)`. - mstore(0x00, 0x935e09bf) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,bool)`. - mstore(0x00, 0x8af7cf8a) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,uint256)`. - mstore(0x00, 0x64b5bb67) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,uint256,string)`. - mstore(0x00, 0x742d6ee7) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,address)`. - mstore(0x00, 0xe0625b29) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,bool)`. - mstore(0x00, 0x3f8a701d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,uint256)`. - mstore(0x00, 0x24f91465) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,bool,string,string)`. - mstore(0x00, 0xa826caeb) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,address)`. - mstore(0x00, 0x5ea2b7ae) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,bool)`. - mstore(0x00, 0x82112a42) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,uint256)`. - mstore(0x00, 0x4f04fdc6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,address,string)`. - mstore(0x00, 0x9ffb2f93) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,address)`. - mstore(0x00, 0xe0e95b98) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,bool)`. - mstore(0x00, 0x354c36d6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,uint256)`. - mstore(0x00, 0xe41b6f6f) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,bool,string)`. - mstore(0x00, 0xabf73a98) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,address)`. - mstore(0x00, 0xe21de278) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,bool)`. - mstore(0x00, 0x7626db92) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,uint256)`. - mstore(0x00, 0xa7a87853) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,uint256,string)`. - mstore(0x00, 0x854b3496) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,address)`. - mstore(0x00, 0x7c4632a4) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,bool)`. - mstore(0x00, 0x7d24491d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,uint256)`. - mstore(0x00, 0xc67ea9d1) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,uint256,string,string)`. - mstore(0x00, 0x5ab84e1f) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,address)`. - mstore(0x00, 0x439c7bef) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,bool)`. - mstore(0x00, 0x5ccd4e37) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,uint256)`. - mstore(0x00, 0x7cc3c607) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,address,string)`. - mstore(0x00, 0xeb1bff80) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,address)`. - mstore(0x00, 0xc371c7db) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,bool)`. - mstore(0x00, 0x40785869) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,uint256)`. - mstore(0x00, 0xd6aefad2) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,bool,string)`. - mstore(0x00, 0x5e84b0ea) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,address)`. - mstore(0x00, 0x1023f7b2) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,bool)`. - mstore(0x00, 0xc3a8a654) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,uint256)`. - mstore(0x00, 0xf45d7d2c) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,uint256,string)`. - mstore(0x00, 0x5d1a971a) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,address)`. - mstore(0x00, 0x6d572f44) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,bool)`. - mstore(0x00, 0x2c1754ed) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,uint256)`. - mstore(0x00, 0x8eafb02b) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - bytes32 m11; - bytes32 m12; - /// @solidity memory-safe-assembly - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - m11 := mload(0x160) - m12 := mload(0x180) - // Selector of `log(string,string,string,string)`. - mstore(0x00, 0xde68f20a) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, 0x140) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - writeString(0x160, p3) - } - _sendLogPayload(0x1c, 0x184); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - mstore(0x160, m11) - mstore(0x180, m12) - } - } -} diff --git a/grouperBot/lib/forge-std/test/CommonBase.t.sol b/grouperBot/lib/forge-std/test/CommonBase.t.sol deleted file mode 100644 index 4a6eb34..0000000 --- a/grouperBot/lib/forge-std/test/CommonBase.t.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {CommonBase} from "../src/Base.sol"; -import {StdConstants} from "../src/StdConstants.sol"; -import {Test} from "../src/Test.sol"; - -contract CommonBaseTest is Test { - function testVmAddressValue() public pure { - assertEq(VM_ADDRESS, address(StdConstants.VM)); - } - - function testConsoleValue() public pure { - assertEq(CONSOLE, StdConstants.CONSOLE); - } - - function testCreate2FactoryValue() public pure { - assertEq(CREATE2_FACTORY, StdConstants.CREATE2_FACTORY); - } - - function testDefaultSenderValue() public pure { - assertEq(DEFAULT_SENDER, StdConstants.DEFAULT_SENDER); - } - - function testDefaultTestContractValue() public pure { - assertEq(DEFAULT_TEST_CONTRACT, StdConstants.DEFAULT_TEST_CONTRACT); - } - - function testMulticall3AddressValue() public pure { - assertEq(MULTICALL3_ADDRESS, address(StdConstants.MULTICALL3_ADDRESS)); - } - - function testSecp256k1OrderValue() public pure { - assertEq(SECP256K1_ORDER, StdConstants.SECP256K1_ORDER); - } - - function testUint256MaxValue() public pure { - assertEq(UINT256_MAX, type(uint256).max); - } - - function testVmValue() public pure { - assertEq(address(vm), address(StdConstants.VM)); - } -} diff --git a/grouperBot/lib/forge-std/test/Config.t.sol b/grouperBot/lib/forge-std/test/Config.t.sol deleted file mode 100644 index 8e2342c..0000000 --- a/grouperBot/lib/forge-std/test/Config.t.sol +++ /dev/null @@ -1,352 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {Test} from "../src/Test.sol"; -import {Config} from "../src/Config.sol"; -import {StdConfig} from "../src/StdConfig.sol"; - -contract ConfigTest is Test, Config { - function setUp() public { - vm.setEnv("MAINNET_RPC", "https://eth.llamarpc.com"); - vm.setEnv("WETH_MAINNET", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"); - vm.setEnv("OPTIMISM_RPC", "https://mainnet.optimism.io"); - vm.setEnv("WETH_OPTIMISM", "0x4200000000000000000000000000000000000006"); - } - - function test_loadConfig() public { - // Deploy the config contract with the test fixture. - _loadConfig("./test/fixtures/config.toml", false); - - // -- MAINNET -------------------------------------------------------------- - - // Read and assert RPC URL for Mainnet (chain ID 1) - assertEq(config.getRpcUrl(1), "https://eth.llamarpc.com"); - - // Read and assert boolean values - assertTrue(config.get(1, "is_live").toBool()); - bool[] memory bool_array = config.get(1, "bool_array").toBoolArray(); - assertTrue(bool_array[0]); - assertFalse(bool_array[1]); - - // Read and assert address values - assertEq(config.get(1, "weth").toAddress(), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); - address[] memory address_array = config.get(1, "deps").toAddressArray(); - assertEq(address_array[0], 0x0000000000000000000000000000000000000000); - assertEq(address_array[1], 0x1111111111111111111111111111111111111111); - - // Read and assert bytes32 values - assertEq(config.get(1, "word").toBytes32(), bytes32(uint256(1234))); - bytes32[] memory bytes32_array = config.get(1, "word_array").toBytes32Array(); - assertEq(bytes32_array[0], bytes32(uint256(5678))); - assertEq(bytes32_array[1], bytes32(uint256(9999))); - - // Read and assert uint values - assertEq(config.get(1, "number").toUint256(), 1234); - uint256[] memory uint_array = config.get(1, "number_array").toUint256Array(); - assertEq(uint_array[0], 5678); - assertEq(uint_array[1], 9999); - - // Read and assert int values - assertEq(config.get(1, "signed_number").toInt256(), -1234); - int256[] memory int_array = config.get(1, "signed_number_array").toInt256Array(); - assertEq(int_array[0], -5678); - assertEq(int_array[1], 9999); - - // Read and assert bytes values - assertEq(config.get(1, "b").toBytes(), hex"abcd"); - bytes[] memory bytes_array = config.get(1, "b_array").toBytesArray(); - assertEq(bytes_array[0], hex"dead"); - assertEq(bytes_array[1], hex"beef"); - - // Read and assert string values - assertEq(config.get(1, "str").toString(), "foo"); - string[] memory string_array = config.get(1, "str_array").toStringArray(); - assertEq(string_array[0], "bar"); - assertEq(string_array[1], "baz"); - - // -- OPTIMISM ------------------------------------------------------------ - - // Read and assert RPC URL for Optimism (chain ID 10) - assertEq(config.getRpcUrl(10), "https://mainnet.optimism.io"); - - // Read and assert boolean values - assertFalse(config.get(10, "is_live").toBool()); - bool_array = config.get(10, "bool_array").toBoolArray(); - assertFalse(bool_array[0]); - assertTrue(bool_array[1]); - - // Read and assert address values - assertEq(config.get(10, "weth").toAddress(), 0x4200000000000000000000000000000000000006); - address_array = config.get(10, "deps").toAddressArray(); - assertEq(address_array[0], 0x2222222222222222222222222222222222222222); - assertEq(address_array[1], 0x3333333333333333333333333333333333333333); - - // Read and assert bytes32 values - assertEq(config.get(10, "word").toBytes32(), bytes32(uint256(9999))); - bytes32_array = config.get(10, "word_array").toBytes32Array(); - assertEq(bytes32_array[0], bytes32(uint256(1234))); - assertEq(bytes32_array[1], bytes32(uint256(5678))); - - // Read and assert uint values - assertEq(config.get(10, "number").toUint256(), 9999); - uint_array = config.get(10, "number_array").toUint256Array(); - assertEq(uint_array[0], 1234); - assertEq(uint_array[1], 5678); - - // Read and assert int values - assertEq(config.get(10, "signed_number").toInt256(), 9999); - int_array = config.get(10, "signed_number_array").toInt256Array(); - assertEq(int_array[0], -1234); - assertEq(int_array[1], -5678); - - // Read and assert bytes values - assertEq(config.get(10, "b").toBytes(), hex"dcba"); - bytes_array = config.get(10, "b_array").toBytesArray(); - assertEq(bytes_array[0], hex"c0ffee"); - assertEq(bytes_array[1], hex"babe"); - - // Read and assert string values - assertEq(config.get(10, "str").toString(), "alice"); - string_array = config.get(10, "str_array").toStringArray(); - assertEq(string_array[0], "bob"); - assertEq(string_array[1], "charlie"); - } - - function test_loadConfigAndForks() public { - _loadConfigAndForks("./test/fixtures/config.toml", false); - - // assert that the map of chain id and fork ids is created and that the chain ids actually match - assertEq(forkOf[1], 0); - vm.selectFork(forkOf[1]); - assertEq(vm.getChainId(), 1); - - assertEq(forkOf[10], 1); - vm.selectFork(forkOf[10]); - assertEq(vm.getChainId(), 10); - } - - function test_writeConfig() public { - // Create a temporary copy of the config file to avoid modifying the original. - string memory originalConfig = "./test/fixtures/config.toml"; - string memory testConfig = "./test/fixtures/config.t.toml"; - vm.copyFile(originalConfig, testConfig); - - // Deploy the config contract with the temporary fixture. - _loadConfig(testConfig, false); - - // Enable writing to file bypassing the context check. - vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); - - { - // Update a single boolean value and verify the change. - config.set(1, "is_live", false); - - assertFalse(config.get(1, "is_live").toBool()); - - string memory content = vm.readFile(testConfig); - assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live")); - - // Update a single address value and verify the change. - address new_addr = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; - config.set(1, "weth", new_addr); - - assertEq(config.get(1, "weth").toAddress(), new_addr); - - content = vm.readFile(testConfig); - assertEq(vm.parseTomlAddress(content, "$.mainnet.address.weth"), new_addr); - - // Update a uint array and verify the change. - uint256[] memory new_numbers = new uint256[](3); - new_numbers[0] = 1; - new_numbers[1] = 2; - new_numbers[2] = 3; - config.set(10, "number_array", new_numbers); - - uint256[] memory updated_numbers_mem = config.get(10, "number_array").toUint256Array(); - assertEq(updated_numbers_mem.length, 3); - assertEq(updated_numbers_mem[0], 1); - assertEq(updated_numbers_mem[1], 2); - assertEq(updated_numbers_mem[2], 3); - - content = vm.readFile(testConfig); - uint256[] memory updated_numbers_disk = vm.parseTomlUintArray(content, "$.optimism.uint.number_array"); - assertEq(updated_numbers_disk.length, 3); - assertEq(updated_numbers_disk[0], 1); - assertEq(updated_numbers_disk[1], 2); - assertEq(updated_numbers_disk[2], 3); - - // Update a string array and verify the change. - string[] memory new_strings = new string[](2); - new_strings[0] = "hello"; - new_strings[1] = "world"; - config.set(1, "str_array", new_strings); - - string[] memory updated_strings_mem = config.get(1, "str_array").toStringArray(); - assertEq(updated_strings_mem.length, 2); - assertEq(updated_strings_mem[0], "hello"); - assertEq(updated_strings_mem[1], "world"); - - content = vm.readFile(testConfig); - string[] memory updated_strings_disk = vm.parseTomlStringArray(content, "$.mainnet.string.str_array"); - assertEq(updated_strings_disk.length, 2); - assertEq(updated_strings_disk[0], "hello"); - assertEq(updated_strings_disk[1], "world"); - - // Create a new uint variable and verify the change. - config.set(1, "new_uint", uint256(42)); - - assertEq(config.get(1, "new_uint").toUint256(), 42); - - content = vm.readFile(testConfig); - assertEq(vm.parseTomlUint(content, "$.mainnet.uint.new_uint"), 42); - - // Create a new int variable and verify the change. - config.set(1, "new_int", int256(-42)); - - assertEq(config.get(1, "new_int").toInt256(), -42); - - content = vm.readFile(testConfig); - assertEq(vm.parseTomlInt(content, "$.mainnet.int.new_int"), -42); - - // Create a new int array and verify the change. - int256[] memory new_ints = new int256[](2); - new_ints[0] = -100; - new_ints[1] = 200; - config.set(10, "new_ints", new_ints); - - int256[] memory updated_ints_mem = config.get(10, "new_ints").toInt256Array(); - assertEq(updated_ints_mem.length, 2); - assertEq(updated_ints_mem[0], -100); - assertEq(updated_ints_mem[1], 200); - - content = vm.readFile(testConfig); - int256[] memory updated_ints_disk = vm.parseTomlIntArray(content, "$.optimism.int.new_ints"); - assertEq(updated_ints_disk.length, 2); - assertEq(updated_ints_disk[0], -100); - assertEq(updated_ints_disk[1], 200); - - // Create a new bytes32 array and verify the change. - bytes32[] memory new_words = new bytes32[](2); - new_words[0] = bytes32(uint256(0xDEAD)); - new_words[1] = bytes32(uint256(0xBEEF)); - config.set(10, "new_words", new_words); - - bytes32[] memory updated_words_mem = config.get(10, "new_words").toBytes32Array(); - assertEq(updated_words_mem.length, 2); - assertEq(updated_words_mem[0], new_words[0]); - assertEq(updated_words_mem[1], new_words[1]); - - content = vm.readFile(testConfig); - bytes32[] memory updated_words_disk = vm.parseTomlBytes32Array(content, "$.optimism.bytes32.new_words"); - assertEq(updated_words_disk.length, 2); - assertEq(vm.toString(updated_words_disk[0]), vm.toString(new_words[0])); - assertEq(vm.toString(updated_words_disk[1]), vm.toString(new_words[1])); - } - - // Clean up the temporary file. - vm.removeFile(testConfig); - } - - function test_writeUpdatesBackToFile() public { - // Create a temporary copy of the config file to avoid modifying the original. - string memory originalConfig = "./test/fixtures/config.toml"; - string memory testConfig = "./test/fixtures/write_config.t.toml"; - vm.copyFile(originalConfig, testConfig); - - // Deploy the config contract with `writeToFile = false` (disabled). - _loadConfig(testConfig, false); - - // Update a single boolean value and verify the file is NOT changed. - config.set(1, "is_live", false); - string memory content = vm.readFile(testConfig); - assertTrue(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated yet"); - - // Enable writing to file bypassing the context check. - vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); - - // Update the value again and verify the file IS changed. - config.set(1, "is_live", false); - content = vm.readFile(testConfig); - assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should be updated now"); - - // Disable writing to file. - config.writeUpdatesBackToFile(false); - - // Update the value again and verify the file is NOT changed. - config.set(1, "is_live", true); - content = vm.readFile(testConfig); - assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated again"); - - // Clean up the temporary file. - vm.removeFile(testConfig); - } - - function testRevert_WriteToFileInForbiddenCtxt() public { - // Cannot initialize enabling writing to file unless we are in SCRIPT mode. - vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector); - _loadConfig("./test/fixtures/config.toml", true); - - // Initialize with `writeToFile = false`. - _loadConfig("./test/fixtures/config.toml", false); - - // Cannot enable writing to file unless we are in SCRIPT mode. - vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector); - config.writeUpdatesBackToFile(true); - } - - function testRevert_InvalidChainKey() public { - // Create a fixture with an invalid chain key - string memory invalidChainConfig = "./test/fixtures/config_invalid_chain.toml"; - vm.writeFile( - invalidChainConfig, - string.concat( - "[mainnet]\n", - "endpoint_url = \"https://eth.llamarpc.com\"\n", - "\n", - "[mainnet.uint]\n", - "valid_number = 123\n", - "\n", - "# Invalid chain key (not a number and not a valid alias)\n", - "[invalid_chain]\n", - "endpoint_url = \"https://invalid.com\"\n", - "\n", - "[invalid_chain_9999.uint]\n", - "some_value = 456\n" - ) - ); - - vm.expectRevert(abi.encodeWithSelector(StdConfig.InvalidChainKey.selector, "invalid_chain")); - new StdConfig(invalidChainConfig, false); - vm.removeFile(invalidChainConfig); - } - - function testRevert_ChainNotInitialized() public { - _loadConfig("./test/fixtures/config.toml", false); - - // Enable writing to file bypassing the context check. - vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); - - // Try to write a value for a non-existent chain ID - vm.expectRevert(abi.encodeWithSelector(StdConfig.ChainNotInitialized.selector, uint256(999999))); - config.set(999999, "some_key", uint256(123)); - } - - function testRevert_UnableToParseVariable() public { - // Create a temporary fixture with an unparsable variable - string memory badParseConfig = "./test/fixtures/config_bad_parse.toml"; - vm.writeFile( - badParseConfig, - string.concat( - "[mainnet]\n", - "endpoint_url = \"https://eth.llamarpc.com\"\n", - "\n", - "[mainnet.uint]\n", - "bad_value = \"not_a_number\"\n" - ) - ); - - vm.expectRevert(abi.encodeWithSelector(StdConfig.UnableToParseVariable.selector, "bad_value")); - new StdConfig(badParseConfig, false); - vm.removeFile(badParseConfig); - } -} diff --git a/grouperBot/lib/forge-std/test/LibVariable.t.sol b/grouperBot/lib/forge-std/test/LibVariable.t.sol deleted file mode 100644 index 2fc00a9..0000000 --- a/grouperBot/lib/forge-std/test/LibVariable.t.sol +++ /dev/null @@ -1,434 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import {Test} from "../src/Test.sol"; -import {Variable, Type, TypeKind, LibVariable} from "../src/LibVariable.sol"; - -contract LibVariableTest is Test { - using LibVariable for Type; - using LibVariable for TypeKind; - - LibVariableHelper internal helper; - - bytes internal expectedErr; - Variable internal uninitVar; - Variable internal boolVar; - Variable internal addressVar; - Variable internal bytes32Var; - Variable internal uintVar; - Variable internal intVar; - Variable internal stringVar; - Variable internal bytesVar; - Variable internal boolArrayVar; - Variable internal addressArrayVar; - Variable internal bytes32ArrayVar; - Variable internal uintArrayVar; - Variable internal intArrayVar; - Variable internal stringArrayVar; - Variable internal bytesArrayVar; - - function setUp() public { - helper = new LibVariableHelper(); - - // UNINITIALIZED - uninitVar = Variable(Type(TypeKind.None, false), ""); - - // SINGLE VALUES - boolVar = Variable(Type(TypeKind.Bool, false), abi.encode(true)); - addressVar = Variable(Type(TypeKind.Address, false), abi.encode(address(0xdeadbeef))); - bytes32Var = Variable(Type(TypeKind.Bytes32, false), abi.encode(bytes32(uint256(42)))); - uintVar = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(123))); - intVar = Variable(Type(TypeKind.Int256, false), abi.encode(int256(-123))); - stringVar = Variable(Type(TypeKind.String, false), abi.encode("hello world")); - bytesVar = Variable(Type(TypeKind.Bytes, false), abi.encode(hex"c0ffee")); - - // ARRAY VALUES - bool[] memory bools = new bool[](2); - bools[0] = true; - bools[1] = false; - boolArrayVar = Variable(Type(TypeKind.Bool, true), abi.encode(bools)); - - address[] memory addrs = new address[](2); - addrs[0] = address(0x1); - addrs[1] = address(0x2); - addressArrayVar = Variable(Type(TypeKind.Address, true), abi.encode(addrs)); - - bytes32[] memory b32s = new bytes32[](2); - b32s[0] = bytes32(uint256(1)); - b32s[1] = bytes32(uint256(2)); - bytes32ArrayVar = Variable(Type(TypeKind.Bytes32, true), abi.encode(b32s)); - - uint256[] memory uints = new uint256[](2); - uints[0] = 1; - uints[1] = 2; - uintArrayVar = Variable(Type(TypeKind.Uint256, true), abi.encode(uints)); - - int256[] memory ints = new int256[](2); - ints[0] = -1; - ints[1] = 2; - intArrayVar = Variable(Type(TypeKind.Int256, true), abi.encode(ints)); - - string[] memory strings = new string[](2); - strings[0] = "one"; - strings[1] = "two"; - stringArrayVar = Variable(Type(TypeKind.String, true), abi.encode(strings)); - - bytes[] memory b = new bytes[](2); - b[0] = hex"01"; - b[1] = hex"02"; - bytesArrayVar = Variable(Type(TypeKind.Bytes, true), abi.encode(b)); - } - - // -- SUCCESS CASES -------------------------------------------------------- - - function test_TypeHelpers() public view { - // TypeKind.toString() - assertEq(TypeKind.None.toString(), "none"); - assertEq(TypeKind.Bool.toString(), "bool"); - assertEq(TypeKind.Address.toString(), "address"); - assertEq(TypeKind.Bytes32.toString(), "bytes32"); - assertEq(TypeKind.Uint256.toString(), "uint256"); - assertEq(TypeKind.Int256.toString(), "int256"); - assertEq(TypeKind.String.toString(), "string"); - assertEq(TypeKind.Bytes.toString(), "bytes"); - - // TypeKind.toTomlKey() - assertEq(TypeKind.Uint256.toTomlKey(), "uint"); - assertEq(TypeKind.Int256.toTomlKey(), "int"); - assertEq(TypeKind.Bytes32.toTomlKey(), "bytes32"); - - // Type.toString() - assertEq(boolVar.ty.toString(), "bool"); - assertEq(boolArrayVar.ty.toString(), "bool[]"); - assertEq(uintVar.ty.toString(), "uint256"); - assertEq(uintArrayVar.ty.toString(), "uint256[]"); - assertEq(uninitVar.ty.toString(), "none"); - - // Type.isEqual() - assertTrue(boolVar.ty.isEqual(Type(TypeKind.Bool, false))); - assertFalse(boolVar.ty.isEqual(Type(TypeKind.Bool, true))); - assertFalse(boolVar.ty.isEqual(Type(TypeKind.Address, false))); - - // Type.assertEq() - boolVar.ty.assertEq(Type(TypeKind.Bool, false)); - uintArrayVar.ty.assertEq(Type(TypeKind.Uint256, true)); - } - - function test_Coercion() public view { - // Single values - assertTrue(helper.toBool(boolVar)); - assertEq(helper.toAddress(addressVar), address(0xdeadbeef)); - assertEq(helper.toBytes32(bytes32Var), bytes32(uint256(42))); - assertEq(helper.toUint256(uintVar), 123); - assertEq(helper.toInt256(intVar), -123); - assertEq(helper.toString(stringVar), "hello world"); - assertEq(helper.toBytes(bytesVar), hex"c0ffee"); - - // Bool array - bool[] memory bools = helper.toBoolArray(boolArrayVar); - assertEq(bools.length, 2); - assertTrue(bools[0]); - assertFalse(bools[1]); - - // Address array - address[] memory addrs = helper.toAddressArray(addressArrayVar); - assertEq(addrs.length, 2); - assertEq(addrs[0], address(0x1)); - assertEq(addrs[1], address(0x2)); - - // String array - string[] memory strings = helper.toStringArray(stringArrayVar); - assertEq(strings.length, 2); - assertEq(strings[0], "one"); - assertEq(strings[1], "two"); - } - - function test_Downcasting() public view { - // Uint downcasting - Variable memory v_uint_small = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(100))); - assertEq(helper.toUint128(v_uint_small), 100); - assertEq(helper.toUint64(v_uint_small), 100); - assertEq(helper.toUint32(v_uint_small), 100); - assertEq(helper.toUint16(v_uint_small), 100); - assertEq(helper.toUint8(v_uint_small), 100); - - // Uint array downcasting - uint256[] memory small_uints = new uint256[](2); - small_uints[0] = 10; - small_uints[1] = 20; - Variable memory v_uint_array_small = Variable(Type(TypeKind.Uint256, true), abi.encode(small_uints)); - uint8[] memory u8_array = helper.toUint8Array(v_uint_array_small); - assertEq(u8_array[0], 10); - assertEq(u8_array[1], 20); - - // Int downcasting - Variable memory v_int_small_pos = Variable(Type(TypeKind.Int256, false), abi.encode(int256(100))); - Variable memory v_int_small_neg = Variable(Type(TypeKind.Int256, false), abi.encode(int256(-100))); - assertEq(helper.toInt128(v_int_small_pos), 100); - assertEq(helper.toInt64(v_int_small_neg), -100); - assertEq(helper.toInt32(v_int_small_pos), 100); - assertEq(helper.toInt16(v_int_small_neg), -100); - assertEq(helper.toInt8(v_int_small_pos), 100); - - // Int array downcasting - int256[] memory small_ints = new int256[](2); - small_ints[0] = -10; - small_ints[1] = 20; - Variable memory intArraySmall = Variable(Type(TypeKind.Int256, true), abi.encode(small_ints)); - int8[] memory i8_array = helper.toInt8Array(intArraySmall); - assertEq(i8_array[0], -10); - assertEq(i8_array[1], 20); - } - - // -- REVERT CASES --------------------------------------------------------- - - function testRevert_NotInitialized() public { - vm.expectRevert(LibVariable.NotInitialized.selector); - helper.toBool(uninitVar); - - vm.expectRevert(LibVariable.NotInitialized.selector); - helper.toAddressArray(uninitVar); - } - - function testRevert_assertExists() public { - vm.expectRevert(LibVariable.NotInitialized.selector); - helper.assertExists(uninitVar); - } - - function testRevert_TypeMismatch() public { - // Single values - vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256", "bool")); - helper.toUint256(boolVar); - - vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "address", "string")); - helper.toAddress(stringVar); - - // Arrays - vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256[]", "bool[]")); - helper.toUint256Array(boolArrayVar); - - vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "address[]", "string[]")); - helper.toAddressArray(stringArrayVar); - - // Single value to array - vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "bool[]", "bool")); - helper.toBoolArray(boolVar); - - // Array to single value - vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "bool", "bool[]")); - helper.toBool(boolArrayVar); - - // assertEq reverts - vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256", "bool")); - helper.assertEq(boolVar.ty, Type(TypeKind.Uint256, false)); - } - - function testRevert_UnsafeCast() public { - // uint overflow - Variable memory uintLarge = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(type(uint128).max) + 1)); - expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'uint128'"); - vm.expectRevert(expectedErr); - helper.toUint128(uintLarge); - - // int overflow - Variable memory intLarge = Variable(Type(TypeKind.Int256, false), abi.encode(int256(type(int128).max) + 1)); - expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'int128'"); - - vm.expectRevert(expectedErr); - helper.toInt128(intLarge); - - // int underflow - Variable memory intSmall = Variable(Type(TypeKind.Int256, false), abi.encode(int256(type(int128).min) - 1)); - expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'int128'"); - - vm.expectRevert(expectedErr); - helper.toInt128(intSmall); - - // uint array overflow - uint256[] memory uintArray = new uint256[](2); - uintArray[0] = 10; - uintArray[1] = uint256(type(uint64).max) + 1; - Variable memory uintArrayLarge = Variable(Type(TypeKind.Uint256, true), abi.encode(uintArray)); - expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'uint64'"); - - vm.expectRevert(expectedErr); - helper.toUint64Array(uintArrayLarge); - - // int array overflow - int256[] memory intArray = new int256[](2); - intArray[0] = 10; - intArray[1] = int256(type(int64).max) + 1; - Variable memory intArrayLarge = Variable(Type(TypeKind.Int256, true), abi.encode(intArray)); - expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'int64'"); - - vm.expectRevert(expectedErr); - helper.toInt64Array(intArrayLarge); - - // int array underflow - intArray[0] = 10; - intArray[1] = int256(type(int64).min) - 1; - Variable memory intArraySmall = Variable(Type(TypeKind.Int256, true), abi.encode(intArray)); - expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'int64'"); - - vm.expectRevert(expectedErr); - helper.toInt64Array(intArraySmall); - } -} - -/// @dev We must use an external helper contract to ensure proper call depth for `vm.expectRevert`, -/// as direct library calls are inlined by the compiler, causing call depth issues. -contract LibVariableHelper { - using LibVariable for Type; - using LibVariable for TypeKind; - - // Assertions - function assertExists(Variable memory v) external pure { - v.assertExists(); - } - - function assertEq(Type memory t1, Type memory t2) external pure { - t1.assertEq(t2); - } - - // Single Value Coercion - function toBool(Variable memory v) external pure returns (bool) { - return v.toBool(); - } - - function toAddress(Variable memory v) external pure returns (address) { - return v.toAddress(); - } - - function toBytes32(Variable memory v) external pure returns (bytes32) { - return v.toBytes32(); - } - - function toUint256(Variable memory v) external pure returns (uint256) { - return v.toUint256(); - } - - function toInt256(Variable memory v) external pure returns (int256) { - return v.toInt256(); - } - - function toString(Variable memory v) external pure returns (string memory) { - return v.toString(); - } - - function toBytes(Variable memory v) external pure returns (bytes memory) { - return v.toBytes(); - } - - // Array Coercion - function toBoolArray(Variable memory v) external pure returns (bool[] memory) { - return v.toBoolArray(); - } - - function toAddressArray(Variable memory v) external pure returns (address[] memory) { - return v.toAddressArray(); - } - - function toBytes32Array(Variable memory v) external pure returns (bytes32[] memory) { - return v.toBytes32Array(); - } - - function toUint256Array(Variable memory v) external pure returns (uint256[] memory) { - return v.toUint256Array(); - } - - function toInt256Array(Variable memory v) external pure returns (int256[] memory) { - return v.toInt256Array(); - } - - function toStringArray(Variable memory v) external pure returns (string[] memory) { - return v.toStringArray(); - } - - function toBytesArray(Variable memory v) external pure returns (bytes[] memory) { - return v.toBytesArray(); - } - - // Uint Downcasting - function toUint128(Variable memory v) external pure returns (uint128) { - return v.toUint128(); - } - - function toUint64(Variable memory v) external pure returns (uint64) { - return v.toUint64(); - } - - function toUint32(Variable memory v) external pure returns (uint32) { - return v.toUint32(); - } - - function toUint16(Variable memory v) external pure returns (uint16) { - return v.toUint16(); - } - - function toUint8(Variable memory v) external pure returns (uint8) { - return v.toUint8(); - } - - // Int Downcasting - function toInt128(Variable memory v) external pure returns (int128) { - return v.toInt128(); - } - - function toInt64(Variable memory v) external pure returns (int64) { - return v.toInt64(); - } - - function toInt32(Variable memory v) external pure returns (int32) { - return v.toInt32(); - } - - function toInt16(Variable memory v) external pure returns (int16) { - return v.toInt16(); - } - - function toInt8(Variable memory v) external pure returns (int8) { - return v.toInt8(); - } - - // Uint Array Downcasting - function toUint128Array(Variable memory v) external pure returns (uint128[] memory) { - return v.toUint128Array(); - } - - function toUint64Array(Variable memory v) external pure returns (uint64[] memory) { - return v.toUint64Array(); - } - - function toUint32Array(Variable memory v) external pure returns (uint32[] memory) { - return v.toUint32Array(); - } - - function toUint16Array(Variable memory v) external pure returns (uint16[] memory) { - return v.toUint16Array(); - } - - function toUint8Array(Variable memory v) external pure returns (uint8[] memory) { - return v.toUint8Array(); - } - - // Int Array Downcasting - function toInt128Array(Variable memory v) external pure returns (int128[] memory) { - return v.toInt128Array(); - } - - function toInt64Array(Variable memory v) external pure returns (int64[] memory) { - return v.toInt64Array(); - } - - function toInt32Array(Variable memory v) external pure returns (int32[] memory) { - return v.toInt32Array(); - } - - function toInt16Array(Variable memory v) external pure returns (int16[] memory) { - return v.toInt16Array(); - } - - function toInt8Array(Variable memory v) external pure returns (int8[] memory) { - return v.toInt8Array(); - } -} diff --git a/grouperBot/lib/forge-std/test/StdAssertions.t.sol b/grouperBot/lib/forge-std/test/StdAssertions.t.sol deleted file mode 100644 index acc0c1e..0000000 --- a/grouperBot/lib/forge-std/test/StdAssertions.t.sol +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {StdAssertions} from "../src/StdAssertions.sol"; -import {Vm} from "../src/Vm.sol"; - -interface VmInternal is Vm { - function _expectCheatcodeRevert(bytes memory message) external; -} - -contract StdAssertionsTest is StdAssertions { - string constant errorMessage = "User provided message"; - uint256 constant maxDecimals = 77; - - bool constant SHOULD_REVERT = true; - bool constant SHOULD_RETURN = false; - - bool constant STRICT_REVERT_DATA = true; - bool constant NON_STRICT_REVERT_DATA = false; - - VmInternal constant vm = VmInternal(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function testFuzz_AssertEqCall_Return_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnData, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); - - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } - - function testFuzz_RevertWhenCalled_AssertEqCall_Return_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); - - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); - - vm._expectCheatcodeRevert( - bytes( - string.concat( - "Call return data does not match: ", vm.toString(returnDataA), " != ", vm.toString(returnDataB) - ) - ) - ); - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } - - function testFuzz_AssertEqCall_Revert_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA); - } - - function testFuzz_RevertWhenCalled_AssertEqCall_Revert_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); - - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - vm._expectCheatcodeRevert( - bytes( - string.concat( - "Call revert data does not match: ", vm.toString(revertDataA), " != ", vm.toString(revertDataB) - ) - ) - ); - assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA); - } - - function testFuzz_RevertWhenCalled_AssertEqCall_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); - - vm.expectRevert(bytes("assertion failed")); - this.assertEqCallExternal(targetA, callDataA, targetB, callDataB, strictRevertData); - - vm.expectRevert(bytes("assertion failed")); - this.assertEqCallExternal(targetB, callDataB, targetA, callDataA, strictRevertData); - } - - // Helper function to test outcome of assertEqCall via `expect` cheatcodes - function assertEqCallExternal( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData - ) public { - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } -} - -contract TestMockCall { - bytes returnData; - bool shouldRevert; - - constructor(bytes memory returnData_, bool shouldRevert_) { - returnData = returnData_; - shouldRevert = shouldRevert_; - } - - fallback() external payable { - bytes memory returnData_ = returnData; - - if (shouldRevert) { - assembly { - revert(add(returnData_, 0x20), mload(returnData_)) - } - } else { - assembly { - return(add(returnData_, 0x20), mload(returnData_)) - } - } - } -} diff --git a/grouperBot/lib/forge-std/test/StdChains.t.sol b/grouperBot/lib/forge-std/test/StdChains.t.sol deleted file mode 100644 index 9522b37..0000000 --- a/grouperBot/lib/forge-std/test/StdChains.t.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {Test} from "../src/Test.sol"; - -contract StdChainsMock is Test { - function exposed_getChain(string memory chainAlias) public returns (Chain memory) { - return getChain(chainAlias); - } - - function exposed_getChain(uint256 chainId) public returns (Chain memory) { - return getChain(chainId); - } - - function exposed_setChain(string memory chainAlias, ChainData memory chainData) public { - setChain(chainAlias, chainData); - } - - function exposed_setFallbackToDefaultRpcUrls(bool useDefault) public { - setFallbackToDefaultRpcUrls(useDefault); - } -} - -contract StdChainsTest is Test { - function test_ChainRpcInitialization() public { - // RPCs specified in `foundry.toml` should be updated. - assertEq(getChain(1).rpcUrl, "https://eth.merkle.io"); - assertEq(getChain("optimism_sepolia").rpcUrl, "https://sepolia.optimism.io/"); - assertEq(getChain("arbitrum_one_sepolia").rpcUrl, "https://sepolia-rollup.arbitrum.io/rpc/"); - - // Environment variables should be the next fallback - assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); - assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); - - // Cannot override RPCs defined in `foundry.toml` - vm.setEnv("MAINNET_RPC_URL", "myoverride2"); - assertEq(getChain("mainnet").rpcUrl, "https://eth.merkle.io"); - - // Other RPCs should remain unchanged. - assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); - assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); - } - - // Named with a leading underscore to clarify this is not intended to be run as a normal test, - // and is intended to be used in the below `test_Rpcs` test. - function _testRpc(string memory rpcAlias) internal { - string memory rpcUrl = getChain(rpcAlias).rpcUrl; - vm.createSelectFork(rpcUrl); - } - - // Ensure we can connect to the default RPC URL for each chain. - // Currently commented out since this is slow and public RPCs are flaky, often resulting in failing CI. - // function test_Rpcs() public { - // _testRpc("mainnet"); - // _testRpc("sepolia"); - // _testRpc("holesky"); - // _testRpc("optimism"); - // _testRpc("optimism_sepolia"); - // _testRpc("arbitrum_one"); - // _testRpc("arbitrum_one_sepolia"); - // _testRpc("arbitrum_nova"); - // _testRpc("polygon"); - // _testRpc("polygon_amoy"); - // _testRpc("avalanche"); - // _testRpc("avalanche_fuji"); - // _testRpc("bnb_smart_chain"); - // _testRpc("bnb_smart_chain_testnet"); - // _testRpc("gnosis_chain"); - // _testRpc("moonbeam"); - // _testRpc("moonriver"); - // _testRpc("moonbase"); - // _testRpc("base_sepolia"); - // _testRpc("base"); - // _testRpc("blast_sepolia"); - // _testRpc("blast"); - // _testRpc("fantom_opera"); - // _testRpc("fantom_opera_testnet"); - // _testRpc("fraxtal"); - // _testRpc("fraxtal_testnet"); - // _testRpc("berachain_bartio_testnet"); - // _testRpc("flare"); - // _testRpc("flare_coston2"); - // } - - function test_RevertIf_ChainNotFound() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); - stdChainsMock.exposed_getChain("does_not_exist"); - } - - function test_RevertIf_SetChain_ChainIdExist_FirstTest() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); - stdChainsMock.exposed_setChain("anvil2", ChainData("Anvil", 31337, "URL")); - } - - function test_RevertIf_ChainBubbleUp() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - stdChainsMock.exposed_setChain("needs_undefined_env_var", ChainData("", 123456789, "")); - // Forge environment variable error. - vm.expectRevert(); - stdChainsMock.exposed_getChain("needs_undefined_env_var"); - } - - function test_RevertIf_SetChain_ChainIdExists_SecondTest() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - stdChainsMock.exposed_setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - - vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); - - stdChainsMock.exposed_setChain("another_custom_chain", ChainData("", 123456789, "")); - } - - function test_SetChain() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - Chain memory customChain = getChain("custom_chain"); - assertEq(customChain.name, "Custom Chain"); - assertEq(customChain.chainId, 123456789); - assertEq(customChain.chainAlias, "custom_chain"); - assertEq(customChain.rpcUrl, "https://custom.chain/"); - Chain memory chainById = getChain(123456789); - assertEq(chainById.name, customChain.name); - assertEq(chainById.chainId, customChain.chainId); - assertEq(chainById.chainAlias, customChain.chainAlias); - assertEq(chainById.rpcUrl, customChain.rpcUrl); - customChain.name = "Another Custom Chain"; - customChain.chainId = 987654321; - setChain("another_custom_chain", customChain); - Chain memory anotherCustomChain = getChain("another_custom_chain"); - assertEq(anotherCustomChain.name, "Another Custom Chain"); - assertEq(anotherCustomChain.chainId, 987654321); - assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); - assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); - // Verify the first chain data was not overwritten - chainById = getChain(123456789); - assertEq(chainById.name, "Custom Chain"); - assertEq(chainById.chainId, 123456789); - } - - function test_RevertIf_SetEmptyAlias() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); - stdChainsMock.exposed_setChain("", ChainData("", 123456789, "")); - } - - function test_RevertIf_SetNoChainId0() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); - stdChainsMock.exposed_setChain("alias", ChainData("", 0, "")); - } - - function test_RevertIf_GetNoChainId0() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); - stdChainsMock.exposed_getChain(0); - } - - function test_RevertIf_GetNoEmptyAlias() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); - stdChainsMock.exposed_getChain(""); - } - - function test_RevertIf_ChainNotInitialized() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); - stdChainsMock.exposed_getChain("no_such_alias"); - } - - function test_RevertIf_ChainAliasNotFound() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); - - stdChainsMock.exposed_getChain(321); - } - - function test_SetChain_ExistingOne() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - assertEq(getChain(123456789).chainId, 123456789); - - setChain("custom_chain", ChainData("Modified Chain", 9999999999999999999, "https://modified.chain/")); - vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); - stdChainsMock.exposed_getChain(123456789); - - Chain memory modifiedChain = getChain(9999999999999999999); - assertEq(modifiedChain.name, "Modified Chain"); - assertEq(modifiedChain.chainId, 9999999999999999999); - assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); - } - - function test_RevertIf_DontUseDefaultRpcUrl() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - // Should error if default RPCs flag is set to false. - stdChainsMock.exposed_setFallbackToDefaultRpcUrls(false); - vm.expectRevert(); - stdChainsMock.exposed_getChain(31337); - vm.expectRevert(); - stdChainsMock.exposed_getChain("sepolia"); - } -} diff --git a/grouperBot/lib/forge-std/test/StdCheats.t.sol b/grouperBot/lib/forge-std/test/StdCheats.t.sol deleted file mode 100644 index 57dbcc2..0000000 --- a/grouperBot/lib/forge-std/test/StdCheats.t.sol +++ /dev/null @@ -1,639 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {StdCheats} from "../src/StdCheats.sol"; -import {Test} from "../src/Test.sol"; -import {stdJson} from "../src/StdJson.sol"; -import {stdToml} from "../src/StdToml.sol"; -import {IERC20} from "../src/interfaces/IERC20.sol"; - -contract StdCheatsTest is Test { - Bar test; - - using stdJson for string; - - function setUp() public { - test = new Bar(); - } - - function test_Skip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function test_Rewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function test_Hoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function test_HoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function test_HoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function test_StartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function test_StartHoaxOrigin() public { - startHoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - test.origin{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function test_ChangePrankMsgSender() public { - vm.startPrank(address(1337)); - test.bar(address(1337)); - changePrank(address(0xdead)); - test.bar(address(0xdead)); - changePrank(address(1337)); - test.bar(address(1337)); - vm.stopPrank(); - } - - function test_ChangePrankMsgSenderAndTxOrigin() public { - vm.startPrank(address(1337), address(1338)); - test.origin(address(1337), address(1338)); - changePrank(address(0xdead), address(0xbeef)); - test.origin(address(0xdead), address(0xbeef)); - changePrank(address(1337), address(1338)); - test.origin(address(1337), address(1338)); - vm.stopPrank(); - } - - function test_MakeAccountEquivalence() public { - Account memory account = makeAccount("1337"); - (address addr, uint256 key) = makeAddrAndKey("1337"); - assertEq(account.addr, addr); - assertEq(account.key, key); - } - - function test_MakeAddrEquivalence() public { - (address addr,) = makeAddrAndKey("1337"); - assertEq(makeAddr("1337"), addr); - } - - function test_MakeAddrSigning() public { - (address addr, uint256 key) = makeAddrAndKey("1337"); - bytes32 hash = keccak256("some_message"); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); - assertEq(ecrecover(hash, v, r, s), addr); - } - - function test_Deal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function test_DealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function test_DealTokenAdjustTotalSupply() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18, true); - assertEq(barToken.balanceOf(address(this)), 10000e18); - assertEq(barToken.totalSupply(), 20000e18); - deal(bar, address(this), 0, true); - assertEq(barToken.balanceOf(address(this)), 0); - assertEq(barToken.totalSupply(), 10000e18); - } - - function test_DealERC1155Token() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, false); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - } - - function test_DealERC1155TokenAdjustTotalSupply() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, true); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - assertEq(barToken.totalSupply(0), 20000e18); - dealERC1155(bar, address(this), 0, 0, true); - assertEq(barToken.balanceOf(address(this), 0), 0); - assertEq(barToken.totalSupply(0), 10000e18); - } - - function test_DealERC721Token() public { - BarERC721 barToken = new BarERC721(); - address bar = address(barToken); - dealERC721(bar, address(2), 1); - assertEq(barToken.balanceOf(address(2)), 1); - assertEq(barToken.balanceOf(address(1)), 0); - dealERC721(bar, address(1), 2); - assertEq(barToken.balanceOf(address(1)), 1); - assertEq(barToken.balanceOf(bar), 1); - } - - function test_DeployCode() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function test_DestroyAccount() public { - // deploy something to destroy it - BarERC721 barToken = new BarERC721(); - address bar = address(barToken); - vm.setNonce(bar, 10); - deal(bar, 100); - - uint256 prevThisBalance = address(this).balance; - uint256 size; - assembly { - size := extcodesize(bar) - } - - assertGt(size, 0); - assertEq(bar.balance, 100); - assertEq(vm.getNonce(bar), 10); - - destroyAccount(bar, address(this)); - assembly { - size := extcodesize(bar) - } - assertEq(address(this).balance, prevThisBalance + 100); - assertEq(vm.getNonce(bar), 0); - assertEq(size, 0); - assertEq(bar.balance, 0); - } - - function test_DeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar"); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function test_DeployCodeVal() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - function test_DeployCodeValNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - // We need this so we can call "this.deployCode" rather than "deployCode" directly - function deployCodeHelper(string memory what) external { - deployCode(what); - } - - function test_RevertIf_DeployCodeFail() public { - vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); - this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); - } - - function getCode(address who) internal view returns (bytes memory o_code) { - /// @solidity memory-safe-assembly - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(who) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(who, add(o_code, 0x20), 0, size) - } - } - - function test_DeriveRememberKey() public { - string memory mnemonic = "test test test test test test test test test test test junk"; - - (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); - assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); - } - - function test_BytesToUint() public pure { - assertEq(3, bytesToUint_test(hex"03")); - assertEq(2, bytesToUint_test(hex"02")); - assertEq(255, bytesToUint_test(hex"ff")); - assertEq(29625, bytesToUint_test(hex"73b9")); - } - - function test_ParseJsonTxDetail() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - string memory json = vm.readFile(path); - bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); - RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); - Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); - assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); - assertEq( - txDetail.data, - hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" - ); - assertEq(txDetail.nonce, 3); - assertEq(txDetail.txType, 2); - assertEq(txDetail.gas, 29625); - assertEq(txDetail.value, 0); - } - - function test_ReadEIP1559Transaction() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 0; - Tx1559 memory transaction = readTx1559(path, index); - transaction; - } - - function test_ReadEIP1559Transactions() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Tx1559[] memory transactions = readTx1559s(path); - transactions; - } - - function test_ReadReceipt() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 5; - Receipt memory receipt = readReceipt(path, index); - assertEq( - receipt.logsBloom, - hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" - ); - } - - function test_ReadReceipts() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Receipt[] memory receipts = readReceipts(path); - receipts; - } - - function test_GasMeteringModifier() public { - uint256 gas_start_normal = gasleft(); - addInLoop(); - uint256 gas_used_normal = gas_start_normal - gasleft(); - - uint256 gas_start_single = gasleft(); - addInLoopNoGas(); - uint256 gas_used_single = gas_start_single - gasleft(); - - uint256 gas_start_double = gasleft(); - addInLoopNoGasNoGas(); - uint256 gas_used_double = gas_start_double - gasleft(); - - assertTrue(gas_used_double + gas_used_single < gas_used_normal); - } - - function addInLoop() internal pure returns (uint256) { - uint256 b; - for (uint256 i; i < 10000; i++) { - b += i; - } - return b; - } - - function addInLoopNoGas() internal noGasMetering returns (uint256) { - return addInLoop(); - } - - function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { - return addInLoopNoGas(); - } - - function bytesToUint_test(bytes memory b) private pure returns (uint256) { - uint256 number; - for (uint256 i = 0; i < b.length; i++) { - number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); - } - return number; - } - - function testFuzz_AssumeAddressIsNot(address addr) external { - // skip over Payable and NonPayable enums - for (uint8 i = 2; i < uint8(type(AddressType).max); i++) { - assumeAddressIsNot(addr, AddressType(i)); - } - assertTrue(addr != address(0)); - assertTrue(addr < address(1) || addr > address(9)); - assertTrue(addr != address(vm) || addr != 0x000000000000000000636F6e736F6c652e6c6f67); - } - - function test_AssumePayable() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - - // all should revert since these addresses are not payable - - // VM address - vm.expectRevert(); - stdCheatsMock.exposed_assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - // Console address - vm.expectRevert(); - stdCheatsMock.exposed_assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); - - // Create2Deployer - vm.expectRevert(); - stdCheatsMock.exposed_assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); - - // all should pass since these addresses are payable - - // vitalik.eth - stdCheatsMock.exposed_assumePayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); - - // mock payable contract - MockContractPayable cp = new MockContractPayable(); - stdCheatsMock.exposed_assumePayable(address(cp)); - } - - function test_AssumeNotPayable() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - - // all should pass since these addresses are not payable - - // VM address - stdCheatsMock.exposed_assumeNotPayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - // Console address - stdCheatsMock.exposed_assumeNotPayable(0x000000000000000000636F6e736F6c652e6c6f67); - - // Create2Deployer - stdCheatsMock.exposed_assumeNotPayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); - - // all should revert since these addresses are payable - - // vitalik.eth - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotPayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); - - // mock payable contract - MockContractPayable cp = new MockContractPayable(); - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotPayable(address(cp)); - } - - function testFuzz_AssumeNotPrecompile(address addr) external { - assumeNotPrecompile(addr, getChain("optimism_sepolia").chainId); - assertTrue( - addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) - || addr > address(0x4200000000000000000000000000000000000800) - ); - } - - function testFuzz_AssumeNotForgeAddress(address addr) external pure { - assumeNotForgeAddress(addr); - assertTrue( - addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } - - function test_RevertIf_CannotDeployCodeTo() external { - vm.expectRevert("StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); - this._revertDeployCodeTo(); - } - - function _revertDeployCodeTo() external { - deployCodeTo("StdCheats.t.sol:RevertingContract", address(0)); - } - - function test_DeployCodeTo() external { - address arbitraryAddress = makeAddr("arbitraryAddress"); - - deployCodeTo( - "StdCheats.t.sol:MockContractWithConstructorArgs", - abi.encode(uint256(6), true, bytes20(arbitraryAddress)), - 1 ether, - arbitraryAddress - ); - - MockContractWithConstructorArgs ct = MockContractWithConstructorArgs(arbitraryAddress); - - assertEq(arbitraryAddress.balance, 1 ether); - assertEq(ct.x(), 6); - assertTrue(ct.y()); - assertEq(ct.z(), bytes20(arbitraryAddress)); - } -} - -contract StdCheatsMock is StdCheats { - function exposed_assumePayable(address addr) external { - assumePayable(addr); - } - - function exposed_assumeNotPayable(address addr) external { - assumeNotPayable(addr); - } - - // We deploy a mock version so we can properly test expected reverts. - function exposed_assumeNotBlacklisted(address token, address addr) external view { - return assumeNotBlacklisted(token, addr); - } -} - -contract StdCheatsForkTest is Test { - address internal constant USDC_BLACKLISTED_USER = 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD; - address internal constant USDT_BLACKLISTED_USER = 0x8f8a8F4B54a2aAC7799d7bc81368aC27b852822A; - - MockUSDT public USDT; - MockUSDC public USDC; - - function setUp() public { - USDT = new MockUSDT(); - USDC = new MockUSDC(); - - USDC.setBlacklisted(USDC_BLACKLISTED_USER, true); - USDT.setBlacklisted(USDT_BLACKLISTED_USER, true); - } - - function test_RevertIf_CannotAssumeNoBlacklisted_EOA() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - address eoa = vm.addr({privateKey: 1}); - vm.expectRevert("StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); - stdCheatsMock.exposed_assumeNotBlacklisted(eoa, address(0)); - } - - function testFuzz_AssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external view { - assumeNotBlacklisted(address(USDC), addr); - assumeNotBlacklisted(address(USDT), addr); - assertTrue(true); - } - - function test_RevertIf_AssumeNoBlacklisted_USDC() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotBlacklisted(address(USDC), USDC_BLACKLISTED_USER); - } - - function testFuzz_AssumeNotBlacklisted_USDC(address addr) external view { - assumeNotBlacklisted(address(USDC), addr); - assertFalse(USDCLike(USDC).isBlacklisted(addr)); - } - - function test_RevertIf_AssumeNoBlacklisted_USDT() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotBlacklisted(address(USDT), USDT_BLACKLISTED_USER); - } - - function testFuzz_AssumeNotBlacklisted_USDT(address addr) external view { - assumeNotBlacklisted(address(USDT), addr); - assertFalse(USDTLike(USDT).isBlackListed(addr)); - } -} - -/// @dev https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#readProxyContract -interface USDCLike { - function isBlacklisted(address) external view returns (bool); -} - -/// @dev https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract -interface USDTLike { - function isBlackListed(address) external view returns (bool); -} - -contract MockUSDT is USDTLike { - mapping(address => bool) private blacklist; - - function isBlackListed(address addr) external view returns (bool) { - return blacklist[addr]; - } - - function setBlacklisted(address addr, bool value) external { - blacklist[addr] = value; - } -} - -contract MockUSDC is USDCLike { - mapping(address => bool) private blacklist; - - function isBlacklisted(address addr) external view returns (bool) { - return blacklist[addr]; - } - - function setBlacklisted(address addr, bool value) external { - blacklist[addr] = value; - } -} - -contract Bar { - constructor() payable { - /// `DEAL` STDCHEAT - totalSupply = 10000e18; - balanceOf[address(this)] = totalSupply; - } - - /// `HOAX` and `CHANGEPRANK` STDCHEATS - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } - - function origin(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedSender, "!prank"); - } - - function origin(address expectedSender, address expectedOrigin) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedOrigin, "!prank"); - } - - /// `DEAL` STDCHEAT - mapping(address => uint256) public balanceOf; - uint256 public totalSupply; -} - -contract BarERC1155 { - constructor() payable { - /// `DEALERC1155` STDCHEAT - _totalSupply[0] = 10000e18; - _balances[0][address(this)] = _totalSupply[0]; - } - - function balanceOf(address account, uint256 id) public view virtual returns (uint256) { - return _balances[id][account]; - } - - function totalSupply(uint256 id) public view virtual returns (uint256) { - return _totalSupply[id]; - } - - /// `DEALERC1155` STDCHEAT - mapping(uint256 => mapping(address => uint256)) private _balances; - mapping(uint256 => uint256) private _totalSupply; -} - -contract BarERC721 { - constructor() payable { - /// `DEALERC721` STDCHEAT - _owners[1] = address(1); - _balances[address(1)] = 1; - _owners[2] = address(this); - _owners[3] = address(this); - _balances[address(this)] = 2; - } - - function balanceOf(address owner) public view virtual returns (uint256) { - return _balances[owner]; - } - - function ownerOf(uint256 tokenId) public view virtual returns (address) { - address owner = _owners[tokenId]; - return owner; - } - - mapping(uint256 => address) private _owners; - mapping(address => uint256) private _balances; -} - -contract RevertingContract { - constructor() { - revert(); - } -} - -contract MockContractWithConstructorArgs { - uint256 public immutable x; - bool public y; - bytes20 public z; - - constructor(uint256 _x, bool _y, bytes20 _z) payable { - x = _x; - y = _y; - z = _z; - } -} - -contract MockContractPayable { - receive() external payable {} -} diff --git a/grouperBot/lib/forge-std/test/StdConstants.t.sol b/grouperBot/lib/forge-std/test/StdConstants.t.sol deleted file mode 100644 index 7a00530..0000000 --- a/grouperBot/lib/forge-std/test/StdConstants.t.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {StdConstants} from "../src/StdConstants.sol"; -import {Test} from "../src/Test.sol"; - -contract StdConstantsTest is Test { - function testVm() public view { - assertEq(StdConstants.VM.getBlockNumber(), 1); - } - - function testVmDerivation() public pure { - assertEq(address(StdConstants.VM), address(uint160(uint256(keccak256("hevm cheat code"))))); - } - - function testConsoleDerivation() public pure { - assertEq(StdConstants.CONSOLE, address(uint160(uint88(bytes11("console.log"))))); - } - - function testDefaultSender() public view { - assertEq(StdConstants.DEFAULT_SENDER, msg.sender); - } - - function testDefaultSenderDerivation() public pure { - assertEq(StdConstants.DEFAULT_SENDER, address(uint160(uint256(keccak256("foundry default caller"))))); - } - - function testDefaultTestContract() public { - assertEq(StdConstants.DEFAULT_TEST_CONTRACT, address(new Dummy())); - } - - function testDefaultTestContractDerivation() public view { - assertEq(address(this), StdConstants.VM.computeCreateAddress(StdConstants.DEFAULT_SENDER, 1)); - assertEq(StdConstants.DEFAULT_TEST_CONTRACT, StdConstants.VM.computeCreateAddress(address(this), 1)); - } -} - -contract Dummy {} diff --git a/grouperBot/lib/forge-std/test/StdError.t.sol b/grouperBot/lib/forge-std/test/StdError.t.sol deleted file mode 100644 index 29803d5..0000000 --- a/grouperBot/lib/forge-std/test/StdError.t.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import {stdError} from "../src/StdError.sol"; -import {Test} from "../src/Test.sol"; - -contract StdErrorsTest is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function test_RevertIf_AssertionError() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function test_RevertIf_ArithmeticError() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function test_RevertIf_DivisionError() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function test_RevertIf_ModError() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function test_RevertIf_EnumConversionError() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function test_RevertIf_EncodeStgError() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function test_RevertIf_PopError() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function test_RevertIf_IndexOOBError() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function test_RevertIf_MemOverflowError() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function test_RevertIf_InternError() public { - vm.expectRevert(stdError.zeroVarError); - test.intern(); - } -} - -contract ErrorsTest { - enum T { - T1 - } - - uint256[] public someArr; - bytes someBytes; - - function assertionError() public pure { - assert(false); - } - - function arithmeticError(uint256 a) public pure { - a -= 100; - } - - function divError(uint256 a) public pure { - 100 / a; - } - - function modError(uint256 a) public pure { - 100 % a; - } - - function enumConversion(uint256 a) public pure { - T(a); - } - - function encodeStgError() public { - /// @solidity memory-safe-assembly - assembly { - sstore(someBytes.slot, 1) - } - keccak256(someBytes); - } - - function pop() public { - someArr.pop(); - } - - function indexOOBError(uint256 a) public pure { - uint256[] memory t = new uint256[](0); - t[a]; - } - - function mem() public pure { - uint256 l = 2 ** 256 / 32; - new uint256[](l); - } - - function intern() public returns (uint256) { - function(uint256) internal returns (uint256) x; - x(2); - return 7; - } -} diff --git a/grouperBot/lib/forge-std/test/StdJson.t.sol b/grouperBot/lib/forge-std/test/StdJson.t.sol deleted file mode 100644 index 6bedfcc..0000000 --- a/grouperBot/lib/forge-std/test/StdJson.t.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {Test, stdJson} from "../src/Test.sol"; - -contract StdJsonTest is Test { - using stdJson for string; - - string root; - string path; - - function setUp() public { - root = vm.projectRoot(); - path = string.concat(root, "/test/fixtures/test.json"); - } - - struct SimpleJson { - uint256 a; - string b; - } - - struct NestedJson { - uint256 a; - string b; - SimpleJson c; - } - - function test_readJson() public view { - string memory json = vm.readFile(path); - assertEq(json.readUint(".a"), 123); - } - - function test_writeJson() public { - string memory json = "json"; - json.serialize("a", uint256(123)); - string memory semiFinal = json.serialize("b", string("test")); - string memory finalJson = json.serialize("c", semiFinal); - finalJson.write(path); - - string memory json_ = vm.readFile(path); - bytes memory data = json_.parseRaw("$"); - NestedJson memory decodedData = abi.decode(data, (NestedJson)); - - assertEq(decodedData.a, 123); - assertEq(decodedData.b, "test"); - assertEq(decodedData.c.a, 123); - assertEq(decodedData.c.b, "test"); - } -} diff --git a/grouperBot/lib/forge-std/test/StdMath.t.sol b/grouperBot/lib/forge-std/test/StdMath.t.sol deleted file mode 100644 index d1269a0..0000000 --- a/grouperBot/lib/forge-std/test/StdMath.t.sol +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import {stdMath} from "../src/StdMath.sol"; -import {Test, stdError} from "../src/Test.sol"; - -contract StdMathMock is Test { - function exposed_percentDelta(uint256 a, uint256 b) public pure returns (uint256) { - return stdMath.percentDelta(a, b); - } - - function exposed_percentDelta(int256 a, int256 b) public pure returns (uint256) { - return stdMath.percentDelta(a, b); - } -} - -contract StdMathTest is Test { - function test_GetAbs() external pure { - assertEq(stdMath.abs(-50), 50); - assertEq(stdMath.abs(50), 50); - assertEq(stdMath.abs(-1337), 1337); - assertEq(stdMath.abs(0), 0); - - assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); - assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); - } - - function testFuzz_GetAbs(int256 a) external pure { - uint256 manualAbs = getAbs(a); - - uint256 abs = stdMath.abs(a); - - assertEq(abs, manualAbs); - } - - function test_GetDelta_Uint() external pure { - assertEq(stdMath.delta(uint256(0), uint256(0)), 0); - assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); - assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); - assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); - assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); - - assertEq(stdMath.delta(0, uint256(0)), 0); - assertEq(stdMath.delta(1337, uint256(0)), 1337); - assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); - assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); - assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); - - assertEq(stdMath.delta(1337, uint256(1337)), 0); - assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); - assertEq(stdMath.delta(5000, uint256(1250)), 3750); - } - - function testFuzz_GetDelta_Uint(uint256 a, uint256 b) external pure { - uint256 manualDelta = a > b ? a - b : b - a; - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function test_GetDelta_Int() external pure { - assertEq(stdMath.delta(int256(0), int256(0)), 0); - assertEq(stdMath.delta(int256(0), int256(1337)), 1337); - assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); - assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); - assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); - - assertEq(stdMath.delta(0, int256(0)), 0); - assertEq(stdMath.delta(1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); - assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); - assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); - - assertEq(stdMath.delta(-0, int256(0)), 0); - assertEq(stdMath.delta(-1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(int256(0), -0), 0); - assertEq(stdMath.delta(int256(0), -1337), 1337); - assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(1337, int256(1337)), 0); - assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); - assertEq(stdMath.delta(5000, int256(1250)), 3750); - } - - function testFuzz_GetDelta_Int(int256 a, int256 b) external pure { - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function test_GetPercentDelta_Uint() external { - StdMathMock stdMathMock = new StdMathMock(); - - assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); - assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); - assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); - assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMathMock.exposed_percentDelta(uint256(1), 0); - } - - function testFuzz_GetPercentDelta_Uint(uint192 a, uint192 b) external pure { - vm.assume(b != 0); - uint256 manualDelta = a > b ? a - b : b - a; - - uint256 manualPercentDelta = manualDelta * 1e18 / b; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - function test_GetPercentDelta_Int() external { - // We deploy a mock version so we can properly test the revert. - StdMathMock stdMathMock = new StdMathMock(); - - assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); - assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, int256(1337)), 0); - assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); - assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); - - assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, int256(2500)), 0); - assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMathMock.exposed_percentDelta(int256(1), 0); - } - - function testFuzz_GetPercentDelta_Int(int192 a, int192 b) external pure { - vm.assume(b != 0); - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / absB; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - /*////////////////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////////////////*/ - - function getAbs(int256 a) private pure returns (uint256) { - if (a < 0) { - return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); - } - - return uint256(a); - } -} diff --git a/grouperBot/lib/forge-std/test/StdStorage.t.sol b/grouperBot/lib/forge-std/test/StdStorage.t.sol deleted file mode 100644 index 46604f8..0000000 --- a/grouperBot/lib/forge-std/test/StdStorage.t.sol +++ /dev/null @@ -1,488 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {stdStorage, StdStorage} from "../src/StdStorage.sol"; -import {Test} from "../src/Test.sol"; - -contract StdStorageTest is Test { - using stdStorage for StdStorage; - - StorageTest internal test; - - function setUp() public { - test = new StorageTest(); - } - - function test_StorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function test_StorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function test_StorageExtraSload() public { - assertEq(16, stdstore.target(address(test)).sig(test.extra_sload.selector).find()); - } - - function test_StorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function test_StorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function test_StorageCheckedWriteSignedIntegerHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write_int(-100); - assertEq(int256(uint256(test.hidden())), -100); - } - - function test_StorageCheckedWriteSignedIntegerObvious() public { - stdstore.target(address(test)).sig(test.tG.selector).checked_write_int(-100); - assertEq(test.tG(), -100); - } - - function test_StorageMapStructA() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); - } - - function test_StorageMapStructB() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); - } - - function test_StorageDeepMap() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( - address(this) - ).find(); - assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); - } - - function test_StorageCheckedWriteDeepMap() public { - stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) - .checked_write(100); - assertEq(100, test.deep_map(address(this), address(this))); - } - - function test_StorageDeepMapStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(0).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), - bytes32(slot) - ); - } - - function test_StorageDeepMapStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(1).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), - bytes32(slot) - ); - } - - function test_StorageCheckedWriteDeepMapStructA() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(100, a); - assertEq(0, b); - } - - function test_StorageCheckedWriteDeepMapStructB() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(0, a); - assertEq(100, b); - } - - function test_StorageCheckedWriteMapStructA() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 100); - assertEq(b, 0); - } - - function test_StorageCheckedWriteMapStructB() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 0); - assertEq(b, 100); - } - - function test_StorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function test_StorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function test_StorageCheckedWriteStructA() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 100); - assertEq(b, 1337); - } - - function test_StorageCheckedWriteStructB() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 1337); - assertEq(b, 100); - } - - function test_StorageMapAddrFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); - assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); - } - - function test_StorageMapAddrRoot() public { - (uint256 slot, bytes32 key) = - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).parent(); - assertEq(address(uint160(uint256(key))), address(this)); - assertEq(uint256(1), slot); - slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).root(); - assertEq(uint256(1), slot); - } - - function test_StorageMapUintFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); - assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); - } - - function test_StorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function test_StorageCheckedWriteMapAddr() public { - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); - assertEq(100, test.map_addr(address(this))); - } - - function test_StorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFuzz_StorageCheckedWriteMapPacked(address addr, uint128 value) public { - stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_lower.selector).with_key(addr) - .checked_write(value); - assertEq(test.read_struct_lower(addr), value); - - stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_upper.selector).with_key(addr) - .checked_write(value); - assertEq(test.read_struct_upper(addr), value); - } - - function test_StorageCheckedWriteMapPackedFullSuccess() public { - uint256 full = test.map_packed(address(1337)); - // keep upper 128, set lower 128 to 1337 - full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; - stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( - full - ); - assertEq(1337, test.read_struct_lower(address(1337))); - } - - function test_RevertStorageConst() public { - StorageTestTarget target = new StorageTestTarget(test); - - vm.expectRevert("stdStorage find(StdStorage): No storage use detected for target."); - target.expectRevertStorageConst(); - } - - function testFuzz_StorageNativePack(uint248 val1, uint248 val2, bool boolVal1, bool boolVal2) public { - stdstore.enable_packed_slots().target(address(test)).sig(test.tA.selector).checked_write(val1); - stdstore.enable_packed_slots().target(address(test)).sig(test.tB.selector).checked_write(boolVal1); - stdstore.enable_packed_slots().target(address(test)).sig(test.tC.selector).checked_write(boolVal2); - stdstore.enable_packed_slots().target(address(test)).sig(test.tD.selector).checked_write(val2); - - assertEq(test.tA(), val1); - assertEq(test.tB(), boolVal1); - assertEq(test.tC(), boolVal2); - assertEq(test.tD(), val2); - } - - function test_StorageReadBytes32() public { - bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); - assertEq(val, hex"1337"); - } - - function test_StorageReadBool_False() public { - bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); - assertEq(val, false); - } - - function test_StorageReadBool_True() public { - bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); - assertEq(val, true); - } - - function test_RevertIf_ReadingNonBoolValue() public { - vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - this.readNonBoolValue(); - } - - function readNonBoolValue() public { - stdstore.target(address(test)).sig(test.tE.selector).read_bool(); - } - - function test_StorageReadAddress() public { - address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); - assertEq(val, address(1337)); - } - - function test_StorageReadUint() public { - uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); - assertEq(val, 1); - } - - function test_StorageReadInt() public { - int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); - assertEq(val, type(int256).min); - } - - function testFuzz_Packed(uint256 val, uint8 elemToGet) public { - // This function tries an assortment of packed slots, shifts meaning number of elements - // that are packed. Shiftsizes are the size of each element, i.e. 8 means a data type that is 8 bits, 16 == 16 bits, etc. - // Combined, these determine how a slot is packed. Making it random is too hard to avoid global rejection limit - // and make it performant. - - // change the number of shifts - for (uint256 i = 1; i < 5; i++) { - uint256 shifts = i; - - elemToGet = uint8(bound(elemToGet, 0, shifts - 1)); - - uint256[] memory shiftSizes = new uint256[](shifts); - for (uint256 j; j < shifts; j++) { - shiftSizes[j] = 8 * (j + 1); - } - - test.setRandomPacking(val); - - uint256 leftBits; - uint256 rightBits; - for (uint256 j; j < shiftSizes.length; j++) { - if (j < elemToGet) { - leftBits += shiftSizes[j]; - } else if (elemToGet != j) { - rightBits += shiftSizes[j]; - } - } - - // we may have some right bits unaccounted for - leftBits += 256 - (leftBits + shiftSizes[elemToGet] + rightBits); - // clear left bits, then clear right bits and realign - uint256 expectedValToRead = (val << leftBits) >> (leftBits + rightBits); - - uint256 readVal = stdstore.target(address(test)).enable_packed_slots().sig( - "getRandomPacked(uint8,uint8[],uint8)" - ).with_calldata(abi.encode(shifts, shiftSizes, elemToGet)).read_uint(); - - assertEq(readVal, expectedValToRead); - } - } - - function testFuzz_Packed2(uint256 nvars, uint256 seed) public { - // Number of random variables to generate. - nvars = bound(nvars, 1, 20); - - // This will decrease as we generate values in the below loop. - uint256 bitsRemaining = 256; - - // Generate a random value and size for each variable. - uint256[] memory vals = new uint256[](nvars); - uint256[] memory sizes = new uint256[](nvars); - uint256[] memory offsets = new uint256[](nvars); - - for (uint256 i = 0; i < nvars; i++) { - // Generate a random value and size. - offsets[i] = i == 0 ? 0 : offsets[i - 1] + sizes[i - 1]; - - uint256 nvarsRemaining = nvars - i; - uint256 maxVarSize = bitsRemaining - nvarsRemaining + 1; - sizes[i] = bound(uint256(keccak256(abi.encodePacked(seed, i + 256))), 1, maxVarSize); - bitsRemaining -= sizes[i]; - - uint256 maxVal; - uint256 varSize = sizes[i]; - assembly { - // mask = (1 << varSize) - 1 - maxVal := sub(shl(varSize, 1), 1) - } - vals[i] = bound(uint256(keccak256(abi.encodePacked(seed, i))), 0, maxVal); - } - - // Pack all values into the slot. - for (uint256 i = 0; i < nvars; i++) { - stdstore.enable_packed_slots().target(address(test)).sig("getRandomPacked(uint256,uint256)").with_key( - sizes[i] - ).with_key(offsets[i]).checked_write(vals[i]); - } - - // Verify the read data matches. - for (uint256 i = 0; i < nvars; i++) { - uint256 readVal = stdstore.enable_packed_slots().target(address(test)).sig( - "getRandomPacked(uint256,uint256)" - ).with_key(sizes[i]).with_key(offsets[i]).read_uint(); - - uint256 retVal = test.getRandomPacked(sizes[i], offsets[i]); - - assertEq(readVal, vals[i]); - assertEq(retVal, vals[i]); - } - } - - function testEdgeCaseArray() public { - stdstore.target(address(test)).sig("edgeCaseArray(uint256)").with_key(uint256(0)).checked_write(1); - assertEq(test.edgeCaseArray(0), 1); - } -} - -contract StorageTestTarget { - using stdStorage for StdStorage; - - StdStorage internal stdstore; - StorageTest internal test; - - constructor(StorageTest test_) { - test = test_; - } - - function expectRevertStorageConst() public { - stdstore.target(address(test)).sig("const()").find(); - } -} - -contract StorageTest { - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - mapping(uint256 => uint256) public map_uint; - mapping(address => uint256) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basic; - - uint248 public tA; - bool public tB; - - bool public tC = false; - uint248 public tD = 1; - - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - mapping(address => bool) public map_bool; - - bytes32 public tE = hex"1337"; - address public tF = address(1337); - int256 public tG = type(int256).min; - bool public tH = true; - bytes32 private tI = ~bytes32(hex"1337"); - - uint256 randomPacking; - - // Array with length matching values of elements. - uint256[] public edgeCaseArray = [3, 3, 3]; - - constructor() { - basic = UnpackedStruct({a: 1337, b: 1337}); - - uint256 two = (1 << 128) | 1; - map_packed[msg.sender] = two; - map_packed[address(uint160(1337))] = 1 << 128; - } - - function read_struct_upper(address who) public view returns (uint256) { - return map_packed[who] >> 128; - } - - function read_struct_lower(address who) public view returns (uint256) { - return map_packed[who] & ((1 << 128) - 1); - } - - function hidden() public view returns (bytes32 t) { - bytes32 slot = keccak256("my.random.var"); - /// @solidity memory-safe-assembly - assembly { - t := sload(slot) - } - } - - function const() public pure returns (bytes32 t) { - t = bytes32(hex"1337"); - } - - function extra_sload() public view returns (bytes32 t) { - // trigger read on slot `tE`, and make a staticcall to make sure compiler doesn't optimize this SLOAD away - assembly { - pop(staticcall(gas(), sload(tE.slot), 0, 0, 0, 0)) - } - t = tI; - } - - function setRandomPacking(uint256 val) public { - randomPacking = val; - } - - function _getMask(uint256 size) internal pure returns (uint256 mask) { - assembly { - // mask = (1 << size) - 1 - mask := sub(shl(size, 1), 1) - } - } - - function setRandomPacking(uint256 val, uint256 size, uint256 offset) public { - // Generate mask based on the size of the value - uint256 mask = _getMask(size); - // Zero out all bits for the word we're about to set - uint256 cleanedWord = randomPacking & ~(mask << offset); - // Place val in the correct spot of the cleaned word - randomPacking = cleanedWord | val << offset; - } - - function getRandomPacked(uint256 size, uint256 offset) public view returns (uint256) { - // Generate mask based on the size of the value - uint256 mask = _getMask(size); - // Shift to place the bits in the correct position, and use mask to zero out remaining bits - return (randomPacking >> offset) & mask; - } - - function getRandomPacked(uint8 shifts, uint8[] memory shiftSizes, uint8 elem) public view returns (uint256) { - require(elem < shifts, "!elem"); - uint256 leftBits; - uint256 rightBits; - - for (uint256 i; i < shiftSizes.length; i++) { - if (i < elem) { - leftBits += shiftSizes[i]; - } else if (elem != i) { - rightBits += shiftSizes[i]; - } - } - - // we may have some right bits unaccounted for - leftBits += 256 - (leftBits + shiftSizes[elem] + rightBits); - - // clear left bits, then clear right bits and realign - return (randomPacking << leftBits) >> (leftBits + rightBits); - } -} diff --git a/grouperBot/lib/forge-std/test/StdStyle.t.sol b/grouperBot/lib/forge-std/test/StdStyle.t.sol deleted file mode 100644 index 974e756..0000000 --- a/grouperBot/lib/forge-std/test/StdStyle.t.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {Test, console2, StdStyle} from "../src/Test.sol"; - -contract StdStyleTest is Test { - function test_StyleColor() public pure { - console2.log(StdStyle.red("StdStyle.red String Test")); - console2.log(StdStyle.red(uint256(10e18))); - console2.log(StdStyle.red(int256(-10e18))); - console2.log(StdStyle.red(true)); - console2.log(StdStyle.red(address(0))); - console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); - console2.log(StdStyle.green("StdStyle.green String Test")); - console2.log(StdStyle.green(uint256(10e18))); - console2.log(StdStyle.green(int256(-10e18))); - console2.log(StdStyle.green(true)); - console2.log(StdStyle.green(address(0))); - console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); - console2.log(StdStyle.yellow("StdStyle.yellow String Test")); - console2.log(StdStyle.yellow(uint256(10e18))); - console2.log(StdStyle.yellow(int256(-10e18))); - console2.log(StdStyle.yellow(true)); - console2.log(StdStyle.yellow(address(0))); - console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); - console2.log(StdStyle.blue("StdStyle.blue String Test")); - console2.log(StdStyle.blue(uint256(10e18))); - console2.log(StdStyle.blue(int256(-10e18))); - console2.log(StdStyle.blue(true)); - console2.log(StdStyle.blue(address(0))); - console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); - console2.log(StdStyle.magenta("StdStyle.magenta String Test")); - console2.log(StdStyle.magenta(uint256(10e18))); - console2.log(StdStyle.magenta(int256(-10e18))); - console2.log(StdStyle.magenta(true)); - console2.log(StdStyle.magenta(address(0))); - console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); - console2.log(StdStyle.cyan("StdStyle.cyan String Test")); - console2.log(StdStyle.cyan(uint256(10e18))); - console2.log(StdStyle.cyan(int256(-10e18))); - console2.log(StdStyle.cyan(true)); - console2.log(StdStyle.cyan(address(0))); - console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); - } - - function test_StyleFontWeight() public pure { - console2.log(StdStyle.bold("StdStyle.bold String Test")); - console2.log(StdStyle.bold(uint256(10e18))); - console2.log(StdStyle.bold(int256(-10e18))); - console2.log(StdStyle.bold(address(0))); - console2.log(StdStyle.bold(true)); - console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); - console2.log(StdStyle.dim("StdStyle.dim String Test")); - console2.log(StdStyle.dim(uint256(10e18))); - console2.log(StdStyle.dim(int256(-10e18))); - console2.log(StdStyle.dim(address(0))); - console2.log(StdStyle.dim(true)); - console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); - console2.log(StdStyle.italic("StdStyle.italic String Test")); - console2.log(StdStyle.italic(uint256(10e18))); - console2.log(StdStyle.italic(int256(-10e18))); - console2.log(StdStyle.italic(address(0))); - console2.log(StdStyle.italic(true)); - console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); - console2.log(StdStyle.underline("StdStyle.underline String Test")); - console2.log(StdStyle.underline(uint256(10e18))); - console2.log(StdStyle.underline(int256(-10e18))); - console2.log(StdStyle.underline(address(0))); - console2.log(StdStyle.underline(true)); - console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); - console2.log(StdStyle.inverse("StdStyle.inverse String Test")); - console2.log(StdStyle.inverse(uint256(10e18))); - console2.log(StdStyle.inverse(int256(-10e18))); - console2.log(StdStyle.inverse(address(0))); - console2.log(StdStyle.inverse(true)); - console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); - } - - function test_StyleCombined() public pure { - console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); - console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); - console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); - console2.log(StdStyle.blue(StdStyle.underline(address(0)))); - console2.log(StdStyle.magenta(StdStyle.inverse(true))); - } - - function test_StyleCustom() public pure { - console2.log(h1("Custom Style 1")); - console2.log(h2("Custom Style 2")); - } - - function h1(string memory a) private pure returns (string memory) { - return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); - } - - function h2(string memory a) private pure returns (string memory) { - return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); - } -} diff --git a/grouperBot/lib/forge-std/test/StdToml.t.sol b/grouperBot/lib/forge-std/test/StdToml.t.sol deleted file mode 100644 index 5a45f4f..0000000 --- a/grouperBot/lib/forge-std/test/StdToml.t.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {Test, stdToml} from "../src/Test.sol"; - -contract StdTomlTest is Test { - using stdToml for string; - - string root; - string path; - - function setUp() public { - root = vm.projectRoot(); - path = string.concat(root, "/test/fixtures/test.toml"); - } - - struct SimpleToml { - uint256 a; - string b; - } - - struct NestedToml { - uint256 a; - string b; - SimpleToml c; - } - - function test_readToml() public view { - string memory json = vm.readFile(path); - assertEq(json.readUint(".a"), 123); - } - - function test_writeToml() public { - string memory json = "json"; - json.serialize("a", uint256(123)); - string memory semiFinal = json.serialize("b", string("test")); - string memory finalJson = json.serialize("c", semiFinal); - finalJson.write(path); - - string memory toml = vm.readFile(path); - bytes memory data = toml.parseRaw("$"); - NestedToml memory decodedData = abi.decode(data, (NestedToml)); - - assertEq(decodedData.a, 123); - assertEq(decodedData.b, "test"); - assertEq(decodedData.c.a, 123); - assertEq(decodedData.c.b, "test"); - } -} diff --git a/grouperBot/lib/forge-std/test/StdUtils.t.sol b/grouperBot/lib/forge-std/test/StdUtils.t.sol deleted file mode 100644 index aee801b..0000000 --- a/grouperBot/lib/forge-std/test/StdUtils.t.sol +++ /dev/null @@ -1,342 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import {Test, StdUtils} from "../src/Test.sol"; - -contract StdUtilsMock is StdUtils { - // We deploy a mock version so we can properly test expected reverts. - function exposed_getTokenBalances(address token, address[] memory addresses) - external - returns (uint256[] memory balances) - { - return getTokenBalances(token, addresses); - } - - function exposed_bound(int256 num, int256 min, int256 max) external pure returns (int256) { - return bound(num, min, max); - } - - function exposed_bound(uint256 num, uint256 min, uint256 max) external pure returns (uint256) { - return bound(num, min, max); - } - - function exposed_bytesToUint(bytes memory b) external pure returns (uint256) { - return bytesToUint(b); - } -} - -contract StdUtilsTest is Test { - /*////////////////////////////////////////////////////////////////////////// - BOUND UINT - //////////////////////////////////////////////////////////////////////////*/ - - function test_Bound() public pure { - assertEq(bound(uint256(5), 0, 4), 0); - assertEq(bound(uint256(0), 69, 69), 69); - assertEq(bound(uint256(0), 68, 69), 68); - assertEq(bound(uint256(10), 150, 190), 174); - assertEq(bound(uint256(300), 2800, 3200), 3107); - assertEq(bound(uint256(9999), 1337, 6666), 4669); - } - - function test_Bound_WithinRange() public pure { - assertEq(bound(uint256(51), 50, 150), 51); - assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); - assertEq(bound(uint256(149), 50, 150), 149); - assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); - } - - function test_Bound_EdgeCoverage() public pure { - assertEq(bound(uint256(0), 50, 150), 50); - assertEq(bound(uint256(1), 50, 150), 51); - assertEq(bound(uint256(2), 50, 150), 52); - assertEq(bound(uint256(3), 50, 150), 53); - assertEq(bound(type(uint256).max, 50, 150), 150); - assertEq(bound(type(uint256).max - 1, 50, 150), 149); - assertEq(bound(type(uint256).max - 2, 50, 150), 148); - assertEq(bound(type(uint256).max - 3, 50, 150), 147); - } - - function testFuzz_Bound_DistributionIsEven(uint256 min, uint256 size) public pure { - size = size % 100 + 1; - min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); - uint256 max = min + size - 1; - uint256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + i, min, max); - assertEq(result, min + (i - 1) % size); - // x < min - result = bound(min - i, min, max); - assertEq(result, max - (i - 1) % size); - } - } - - function testFuzz_Bound(uint256 num, uint256 min, uint256 max) public pure { - if (min > max) (min, max) = (max, min); - - uint256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function test_BoundUint256Max() public pure { - assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); - assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); - } - - function test_RevertIf_BoundMaxLessThanMin() public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - stdUtils.exposed_bound(uint256(5), 100, 10); - } - - function testFuzz_RevertIf_BoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - stdUtils.exposed_bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BOUND INT - //////////////////////////////////////////////////////////////////////////*/ - - function test_BoundInt() public pure { - assertEq(bound(-3, 0, 4), 2); - assertEq(bound(0, -69, -69), -69); - assertEq(bound(0, -69, -68), -68); - assertEq(bound(-10, 150, 190), 154); - assertEq(bound(-300, 2800, 3200), 2908); - assertEq(bound(9999, -1337, 6666), 1995); - } - - function test_BoundInt_WithinRange() public pure { - assertEq(bound(51, -50, 150), 51); - assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); - assertEq(bound(149, -50, 150), 149); - assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); - } - - function test_BoundInt_EdgeCoverage() public pure { - assertEq(bound(type(int256).min, -50, 150), -50); - assertEq(bound(type(int256).min + 1, -50, 150), -49); - assertEq(bound(type(int256).min + 2, -50, 150), -48); - assertEq(bound(type(int256).min + 3, -50, 150), -47); - assertEq(bound(type(int256).min, 10, 150), 10); - assertEq(bound(type(int256).min + 1, 10, 150), 11); - assertEq(bound(type(int256).min + 2, 10, 150), 12); - assertEq(bound(type(int256).min + 3, 10, 150), 13); - - assertEq(bound(type(int256).max, -50, 150), 150); - assertEq(bound(type(int256).max - 1, -50, 150), 149); - assertEq(bound(type(int256).max - 2, -50, 150), 148); - assertEq(bound(type(int256).max - 3, -50, 150), 147); - assertEq(bound(type(int256).max, -50, -10), -10); - assertEq(bound(type(int256).max - 1, -50, -10), -11); - assertEq(bound(type(int256).max - 2, -50, -10), -12); - assertEq(bound(type(int256).max - 3, -50, -10), -13); - } - - function testFuzz_BoundInt_DistributionIsEven(int256 min, uint256 size) public pure { - size = size % 100 + 1; - min = bound(min, -int256(size / 2), int256(size - size / 2)); - int256 max = min + int256(size) - 1; - int256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + int256(i), min, max); - assertEq(result, min + int256((i - 1) % size)); - // x < min - result = bound(min - int256(i), min, max); - assertEq(result, max - int256((i - 1) % size)); - } - } - - function testFuzz_BoundInt(int256 num, int256 min, int256 max) public pure { - if (min > max) (min, max) = (max, min); - - int256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function test_BoundIntInt256Max() public pure { - assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); - assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); - } - - function test_BoundIntInt256Min() public pure { - assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); - assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); - } - - function test_RevertIf_BoundIntMaxLessThanMin() public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - stdUtils.exposed_bound(-5, 100, 10); - } - - function testFuzz_RevertIf_BoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - stdUtils.exposed_bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BOUND PRIVATE KEY - //////////////////////////////////////////////////////////////////////////*/ - - function test_BoundPrivateKey() public pure { - assertEq(boundPrivateKey(0), 1); - assertEq(boundPrivateKey(1), 1); - assertEq(boundPrivateKey(300), 300); - assertEq(boundPrivateKey(9999), 9999); - assertEq(boundPrivateKey(SECP256K1_ORDER - 1), SECP256K1_ORDER - 1); - assertEq(boundPrivateKey(SECP256K1_ORDER), 1); - assertEq(boundPrivateKey(SECP256K1_ORDER + 1), 2); - assertEq(boundPrivateKey(UINT256_MAX), UINT256_MAX & SECP256K1_ORDER - 1); // x&y is equivalent to x-x%y - } - - /*////////////////////////////////////////////////////////////////////////// - BYTES TO UINT - //////////////////////////////////////////////////////////////////////////*/ - - function test_BytesToUint() external pure { - bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - bytes memory two = hex"02"; - bytes memory millionEther = hex"d3c21bcecceda1000000"; - - assertEq(bytesToUint(maxUint), type(uint256).max); - assertEq(bytesToUint(two), 2); - assertEq(bytesToUint(millionEther), 1_000_000 ether); - } - - function test_RevertIf_BytesLengthExceeds32() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - stdUtils.exposed_bytesToUint(thirty3Bytes); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function test_ComputeCreateAddress() external pure { - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - uint256 nonce = 14; - address createAddress = computeCreateAddress(deployer, nonce); - assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE2 ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function test_ComputeCreate2Address() external pure { - bytes32 salt = bytes32(uint256(31415)); - bytes32 initcodeHash = keccak256(abi.encode(0x6080)); - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - address create2Address = computeCreate2Address(salt, initcodeHash, deployer); - assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); - } - - function test_ComputeCreate2AddressWithDefaultDeployer() external pure { - bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; - bytes32 initcodeHash = hashInitCode(hex"6080", ""); - assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); - address create2Address = computeCreate2Address(salt, initcodeHash); - assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); - } -} - -contract StdUtilsForkTest is Test { - /*////////////////////////////////////////////////////////////////////////// - GET TOKEN BALANCES - //////////////////////////////////////////////////////////////////////////*/ - - address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; - address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; - address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; - address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; - - address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; - address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; - address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; - - function setUp() public { - // All tests of the `getTokenBalances` method are fork tests using live contracts. - vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); - } - - function test_RevertIf_CannotGetTokenBalances_NonTokenContract() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, - // so the `balanceOf` call should revert. - address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - - vm.expectRevert("Multicall3: call failed"); - stdUtils.exposed_getTokenBalances(token, addresses); - } - - function test_RevertIf_CannotGetTokenBalances_EOA() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - address eoa = vm.addr({privateKey: 1}); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - stdUtils.exposed_getTokenBalances(eoa, addresses); - } - - function test_GetTokenBalances_Empty() external { - address[] memory addresses = new address[](0); - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances.length, 0); - } - - function test_GetTokenBalances_USDC() external { - address[] memory addresses = new address[](2); - addresses[0] = USDC_HOLDER_0; - addresses[1] = USDC_HOLDER_1; - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances[0], 159_000_000_000_000); - assertEq(balances[1], 131_350_000_000_000); - } - - function test_GetTokenBalances_SHIB() external { - address[] memory addresses = new address[](3); - addresses[0] = SHIB_HOLDER_0; - addresses[1] = SHIB_HOLDER_1; - addresses[2] = SHIB_HOLDER_2; - uint256[] memory balances = getTokenBalances(SHIB, addresses); - assertEq(balances[0], 3_323_256_285_484.42e18); - assertEq(balances[1], 1_271_702_771_149.99999928e18); - assertEq(balances[2], 606_357_106_247e18); - } -} diff --git a/grouperBot/lib/forge-std/test/Vm.t.sol b/grouperBot/lib/forge-std/test/Vm.t.sol deleted file mode 100644 index 1b99e3d..0000000 --- a/grouperBot/lib/forge-std/test/Vm.t.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import {Test} from "../src/Test.sol"; -import {Vm, VmSafe} from "../src/Vm.sol"; - -// These tests ensure that functions are never accidentally removed from a Vm interface, or -// inadvertently moved between Vm and VmSafe. These tests must be updated each time a function is -// added to or removed from Vm or VmSafe. -contract VmTest is Test { - function test_VmInterfaceId() public pure { - assertEq(type(Vm).interfaceId, bytes4(0xe835828d), "Vm"); - } - - function test_VmSafeInterfaceId() public pure { - assertEq(type(VmSafe).interfaceId, bytes4(0xe02727c3), "VmSafe"); - } -} diff --git a/grouperBot/lib/forge-std/test/compilation/CompilationScript.sol b/grouperBot/lib/forge-std/test/compilation/CompilationScript.sol deleted file mode 100644 index d3d88a0..0000000 --- a/grouperBot/lib/forge-std/test/compilation/CompilationScript.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {Script} from "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScript is Script {} diff --git a/grouperBot/lib/forge-std/test/compilation/CompilationScriptBase.sol b/grouperBot/lib/forge-std/test/compilation/CompilationScriptBase.sol deleted file mode 100644 index 65b5bed..0000000 --- a/grouperBot/lib/forge-std/test/compilation/CompilationScriptBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {ScriptBase} from "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScriptBase is ScriptBase {} diff --git a/grouperBot/lib/forge-std/test/compilation/CompilationTest.sol b/grouperBot/lib/forge-std/test/compilation/CompilationTest.sol deleted file mode 100644 index 2a9dec5..0000000 --- a/grouperBot/lib/forge-std/test/compilation/CompilationTest.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {Test} from "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTest is Test {} diff --git a/grouperBot/lib/forge-std/test/compilation/CompilationTestBase.sol b/grouperBot/lib/forge-std/test/compilation/CompilationTestBase.sol deleted file mode 100644 index 32b3fc5..0000000 --- a/grouperBot/lib/forge-std/test/compilation/CompilationTestBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {TestBase} from "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTestBase is TestBase {} diff --git a/grouperBot/lib/forge-std/test/fixtures/broadcast.log.json b/grouperBot/lib/forge-std/test/fixtures/broadcast.log.json deleted file mode 100644 index 0a0200b..0000000 --- a/grouperBot/lib/forge-std/test/fixtures/broadcast.log.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "transactions": [ - { - "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", - "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0x73b9", - "value": "0x0", - "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", - "nonce": "0x3", - "accessList": [] - } - }, - { - "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "inc():(uint256)", - "arguments": [], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0xdcb2", - "value": "0x0", - "data": "0x371303c0", - "nonce": "0x4", - "accessList": [] - } - }, - { - "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "function": "t(uint256):(uint256)", - "arguments": ["1"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "gas": "0x8599", - "value": "0x0", - "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", - "nonce": "0x5", - "accessList": [] - } - } - ], - "receipts": [ - { - "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", - "transactionIndex": "0x0", - "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", - "blockNumber": "0x1", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x13f3a", - "gasUsed": "0x13f3a", - "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", - "transactionIndex": "0x0", - "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", - "blockNumber": "0x2", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x45d80", - "gasUsed": "0x45d80", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", - "transactionIndex": "0x0", - "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", - "blockNumber": "0x3", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "cumulativeGasUsed": "0x45feb", - "gasUsed": "0x45feb", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "transactionIndex": "0x0", - "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", - "blockNumber": "0x4", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0x5905", - "gasUsed": "0x5905", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "transactionIndex": "0x0", - "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", - "blockNumber": "0x5", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0xa9c4", - "gasUsed": "0xa9c4", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x0", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "cumulativeGasUsed": "0x66c5", - "gasUsed": "0x66c5", - "contractAddress": null, - "logs": [ - { - "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "topics": [ - "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x1", - "logIndex": "0x0", - "transactionLogIndex": "0x0", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", - "transactionIndex": "0x0", - "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", - "blockNumber": "0x7", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x0000000000000000000000000000000000001337", - "cumulativeGasUsed": "0x5208", - "gasUsed": "0x5208", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - } - ], - "libraries": [ - "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" - ], - "pending": [], - "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", - "returns": {}, - "timestamp": 1655140035 -} diff --git a/grouperBot/lib/forge-std/test/fixtures/config.toml b/grouperBot/lib/forge-std/test/fixtures/config.toml deleted file mode 100644 index e6dcccc..0000000 --- a/grouperBot/lib/forge-std/test/fixtures/config.toml +++ /dev/null @@ -1,81 +0,0 @@ -# ------------------------------------------------ -# EXAMPLE DEPLOYMENT CONFIG -# ------------------------------------------------ - -# -- MAINNET ------------------------------------- - -[mainnet] -endpoint_url = "${MAINNET_RPC}" - -[mainnet.bool] -is_live = true -bool_array = [true, false] - -[mainnet.address] -weth = "${WETH_MAINNET}" -deps = [ - "0x0000000000000000000000000000000000000000", - "0x1111111111111111111111111111111111111111", -] - -[mainnet.uint] -number = 1234 -number_array = [5678, 9999] - -[mainnet.int] -signed_number = -1234 -signed_number_array = [-5678, 9999] - -[mainnet.bytes32] -word = "0x00000000000000000000000000000000000000000000000000000000000004d2" # 1234 -word_array = [ - "0x000000000000000000000000000000000000000000000000000000000000162e", # 5678 - "0x000000000000000000000000000000000000000000000000000000000000270f", # 9999 -] - -[mainnet.bytes] -b = "0xabcd" -b_array = ["0xdead", "0xbeef"] - -[mainnet.string] -str = "foo" -str_array = ["bar", "baz"] - -# -- OPTIMISM ------------------------------------ - -[optimism] -endpoint_url = "${OPTIMISM_RPC}" - -[optimism.bool] -is_live = false -bool_array = [false, true] - -[optimism.address] -weth = "${WETH_OPTIMISM}" -deps = [ - "0x2222222222222222222222222222222222222222", - "0x3333333333333333333333333333333333333333", -] - -[optimism.uint] -number = 9999 -number_array = [1234, 5678] - -[optimism.int] -signed_number = 9999 -signed_number_array = [-1234, -5678] - -[optimism.bytes32] -word = "0x000000000000000000000000000000000000000000000000000000000000270f" # 9999 -word_array = [ - "0x00000000000000000000000000000000000000000000000000000000000004d2", # 1234 - "0x000000000000000000000000000000000000000000000000000000000000162e", # 5678 -] - -[optimism.bytes] -b = "0xdcba" -b_array = ["0xc0ffee", "0xbabe"] - -[optimism.string] -str = "alice" -str_array = ["bob", "charlie"] diff --git a/grouperBot/lib/forge-std/test/fixtures/test.json b/grouperBot/lib/forge-std/test/fixtures/test.json deleted file mode 100644 index caebf6d..0000000 --- a/grouperBot/lib/forge-std/test/fixtures/test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "a": 123, - "b": "test", - "c": { - "a": 123, - "b": "test" - } -} \ No newline at end of file diff --git a/grouperBot/lib/forge-std/test/fixtures/test.toml b/grouperBot/lib/forge-std/test/fixtures/test.toml deleted file mode 100644 index 60692bc..0000000 --- a/grouperBot/lib/forge-std/test/fixtures/test.toml +++ /dev/null @@ -1,6 +0,0 @@ -a = 123 -b = "test" - -[c] -a = 123 -b = "test" diff --git a/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/bug-or-vulnerability-report.md b/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/bug-or-vulnerability-report.md deleted file mode 100644 index 37921d1..0000000 --- a/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/bug-or-vulnerability-report.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Bug or vulnerability report -about: Report a bug or a vulnerability -title: '' -labels: '' -assignees: '' - ---- - - - - - - - - - - - - diff --git a/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/everything-else.md b/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/everything-else.md deleted file mode 100644 index 0cc47e1..0000000 --- a/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/everything-else.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Everything else -about: Refactors, cleanups, optimization, etc. -title: '' -labels: '' -assignees: '' - ---- - - - - - - - - diff --git a/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/feature-request.md b/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/feature-request.md deleted file mode 100644 index dfb0655..0000000 --- a/grouperBot/lib/solady/.github/ISSUE_TEMPLATE/feature-request.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: Feature request -about: Propose a new feature -title: '' -labels: '' -assignees: '' - ---- - - - diff --git a/grouperBot/lib/solady/.github/pull_request_template.md b/grouperBot/lib/solady/.github/pull_request_template.md deleted file mode 100644 index 87976a3..0000000 --- a/grouperBot/lib/solady/.github/pull_request_template.md +++ /dev/null @@ -1,23 +0,0 @@ -## Description - -Describe the changes made in your pull request here. - -## Checklist - -Ensure you completed **all of the steps** below before submitting your pull request: - -- [ ] Ran `forge fmt`? -- [ ] Ran `forge test`? - -_Pull requests with an incomplete checklist will be thrown out._ - - - - - - - - - - - diff --git a/grouperBot/lib/solady/.github/workflows/ci-all-via-ir.yml b/grouperBot/lib/solady/.github/workflows/ci-all-via-ir.yml deleted file mode 100644 index 4bf8a06..0000000 --- a/grouperBot/lib/solady/.github/workflows/ci-all-via-ir.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: ci-all-via-ir - -on: - workflow_dispatch: - -jobs: - tests: - name: Forge Testing all via-ir - runs-on: ubuntu-latest - - strategy: - matrix: - profile: [via-ir-0,via-ir-1,via-ir-2,via-ir-3] - - steps: - - uses: actions/checkout@v5 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: stable - - - name: Install Dependencies - run: forge install - - - name: Run Tests with ${{ matrix.profile }} - run: > - ( [ "${{ matrix.profile }}" = "via-ir-0" ] && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.4 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.5 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.6 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.7 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.8 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.9 --via-ir - ) || - ( [ "${{ matrix.profile }}" = "via-ir-1" ] && - forge test --use 0.8.13 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.12 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.11 --via-ir && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.10 --via-ir - ) || - ( [ "${{ matrix.profile }}" = "via-ir-2" ] && - forge test --use 0.8.14 --via-ir && - forge test --use 0.8.15 --via-ir && - forge test --use 0.8.16 --via-ir && - forge test --use 0.8.17 --via-ir - ) || - ( [ "${{ matrix.profile }}" = "via-ir-3" ] && - forge test --use 0.8.30 --via-ir && - forge test --use 0.8.29 --via-ir && - forge test --use 0.8.28 --via-ir && - forge test --use 0.8.27 --via-ir && - forge test --use 0.8.26 --via-ir && - forge test --use 0.8.25 --via-ir && - forge test --use 0.8.24 --via-ir && - forge test --use 0.8.23 --via-ir && - forge test --use 0.8.22 --via-ir && - forge test --use 0.8.21 --via-ir && - forge test --use 0.8.20 --via-ir && - forge test --use 0.8.19 --via-ir && - forge test --use 0.8.18 --via-ir - ) \ No newline at end of file diff --git a/grouperBot/lib/solady/.github/workflows/ci-invariant-intense.yml b/grouperBot/lib/solady/.github/workflows/ci-invariant-intense.yml deleted file mode 100644 index c46c31e..0000000 --- a/grouperBot/lib/solady/.github/workflows/ci-invariant-intense.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: ci-invariant-intense - -on: - workflow_dispatch: - -jobs: - tests: - name: Forge Testing invariant intense - runs-on: ubuntu-latest - - strategy: - matrix: - profile: [invariant-intense-0,invariant-intense-1,invariant-intense-2,invariant-intense-3] - - steps: - - uses: actions/checkout@v5 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: stable - - - name: Install Dependencies - run: forge install - - - name: Run Tests with ${{ matrix.profile }} - run: FOUNDRY_INVARIANT_RUNS=500 FOUNDRY_INVARIANT_DEPTH=500 forge test diff --git a/grouperBot/lib/solady/.github/workflows/ci-super-intense.yml b/grouperBot/lib/solady/.github/workflows/ci-super-intense.yml deleted file mode 100644 index 7c38b5f..0000000 --- a/grouperBot/lib/solady/.github/workflows/ci-super-intense.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: ci-super-intense - -on: - workflow_dispatch: - -jobs: - tests: - name: Forge Testing super intense - runs-on: ubuntu-latest - - strategy: - matrix: - profile: [super-intense-0,super-intense-1] - - steps: - - uses: actions/checkout@v5 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: stable - - - name: Install Dependencies - run: forge install - - - name: Run Tests with ${{ matrix.profile }} - run: > - ( [ "${{ matrix.profile }}" = "super-intense-0" ] && - forge test --fuzz-runs 20000 - ) || - ( [ "${{ matrix.profile }}" = "super-intense-1" ] && - forge test --fuzz-runs 200000 - ) diff --git a/grouperBot/lib/solady/.github/workflows/ci-wake.yml b/grouperBot/lib/solady/.github/workflows/ci-wake.yml deleted file mode 100644 index 5257c31..0000000 --- a/grouperBot/lib/solady/.github/workflows/ci-wake.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: ci - Wake - -on: - workflow_dispatch: - -jobs: - tests: - name: Wake Testing - runs-on: ubuntu-latest - - strategy: - matrix: - profile: [via-ir-off, via-ir-on] - - steps: - - uses: actions/checkout@v5 - - - name: Setup Wake - uses: Ackee-Blockchain/wake-setup-action@0.1.0 - - - name: Install Dependencies - run: forge install - - - name: Move Wake test files - run: mv ext/wake tests && mv tests/wake.toml . - - - name: Generate pytypes with via-ir-on - if: ${{ matrix.profile }} == 'via-ir-on' - run: wake init pytypes --via-ir - - - name: Generate pytypes with via-ir-off - if: ${{ matrix.profile }} == 'via-ir-off' - run: wake init pytypes --no-via-ir - - - name: Run tests - run: wake test diff --git a/grouperBot/lib/solady/.github/workflows/ci.yml b/grouperBot/lib/solady/.github/workflows/ci.yml deleted file mode 100644 index ab7ab1f..0000000 --- a/grouperBot/lib/solady/.github/workflows/ci.yml +++ /dev/null @@ -1,174 +0,0 @@ -name: ci -'on': - pull_request: - branches: [main] - paths: - - '**.sol' - - '**.yml' - push: - branches: [main] - paths: - - '**.sol' - - '**.yml' -jobs: - tests-stable: - name: Forge Testing - runs-on: ubuntu-latest - strategy: - matrix: - profile: [post-cancun,post-cancun-via-ir,solc-past-versions-0,solc-past-versions-1,via-ir,min-solc,min-solc-via-ir,intense] - steps: - - uses: actions/checkout@v5 - - name: Install Foundry Stable - uses: foundry-rs/foundry-toolchain@v1 - with: - version: stable - - name: Install Dependencies - run: forge install - - name: Run Tests with ${{ matrix.profile }} - run: > - ( [ "${{ matrix.profile }}" = "post-cancun" ] && - FOUNDRY_PROFILE=post_cancun forge test --use 0.8.30 && - FOUNDRY_PROFILE=zksync forge test --use 0.8.30 - ) || - ( [ "${{ matrix.profile }}" = "post-cancun-via-ir" ] && - FOUNDRY_PROFILE=post_cancun forge test --use 0.8.30 --via-ir && - FOUNDRY_PROFILE=zksync forge test --use 0.8.30 --via-ir - ) || - ( [ "${{ matrix.profile }}" = "solc-past-versions-0" ] && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.5 --fuzz-runs 16 && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.6 --fuzz-runs 16 && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.7 --fuzz-runs 16 && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.8 --fuzz-runs 16 && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.9 --fuzz-runs 16 && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.10 --fuzz-runs 16 && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.11 --fuzz-runs 16 && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.12 --fuzz-runs 16 - ) || - ( [ "${{ matrix.profile }}" = "solc-past-versions-1" ] && - forge test --use 0.8.13 --fuzz-runs 16 && - forge test --use 0.8.14 --fuzz-runs 16 && - forge test --use 0.8.15 --fuzz-runs 16 && - forge test --use 0.8.16 --fuzz-runs 16 && - forge test --use 0.8.17 --fuzz-runs 16 && - forge test --use 0.8.18 --fuzz-runs 16 && - forge test --use 0.8.19 --fuzz-runs 16 && - forge test --use 0.8.20 --fuzz-runs 16 && - forge test --use 0.8.21 --fuzz-runs 16 && - forge test --use 0.8.22 --fuzz-runs 16 && - forge test --use 0.8.23 --fuzz-runs 16 && - forge test --use 0.8.24 --fuzz-runs 16 && - forge test --use 0.8.25 --fuzz-runs 16 && - forge test --use 0.8.26 --fuzz-runs 16 && - forge test --use 0.8.27 --fuzz-runs 16 && - forge test --use 0.8.28 --fuzz-runs 16 && - forge test --use 0.8.29 --fuzz-runs 16 - - ) || - ( [ "${{ matrix.profile }}" = "via-ir" ] && - forge test --via-ir - ) || - ( [ "${{ matrix.profile }}" = "min-solc" ] && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.4 - ) || - ( [ "${{ matrix.profile }}" = "min-solc-via-ir" ] && - FOUNDRY_PROFILE=pre_global_structs forge test --use 0.8.4 --via-ir - ) || - ( [ "${{ matrix.profile }}" = "intense" ] && - forge test --fuzz-runs 5000 - ) - - # Disable for now until we can use `foundry.toml` setting to override the - # transaction gas limit. See: EIP-7825. - # - # tests-ithaca: - # name: Forge Ithaca Testing - # runs-on: ubuntu-latest - # strategy: - # matrix: - # profile: [post-cancun,post-cancun-via-ir] - # steps: - # - uses: actions/checkout@v5 - # - name: Install Foundry Nightly - # uses: foundry-rs/foundry-toolchain@v1 - # with: - # version: nightly - # - name: Install Dependencies - # run: forge install - # - name: Run Tests with ${{ matrix.profile }} - # run: | - # if [[ "${{ matrix.profile }}" == "post-cancun" ]]; then - # FOUNDRY_PROFILE=ithaca forge test --use 0.8.28 - # elif [[ "${{ matrix.profile }}" == "post-cancun-via-ir" ]]; then - # FOUNDRY_PROFILE=ithaca forge test --use 0.8.28 --via-ir - # fi - - codespell: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: - - ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v5 - - name: Run codespell - uses: codespell-project/actions-codespell@v2.0 - with: - check_filenames: true - ignore_words_list: usera - skip: ./.git,package-lock.json,./audits,EIP712Mock.sol - - gas-diff: - if: github.event_name == 'pull_request' - permissions: write-all - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: - - ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v5 - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: stable - - name: Install Dependencies - run: forge install - - name: Generate gas diff - uses: atarpara/foundry-snapshot-diff@v0.8 - id: gas_diff - - name: Add gas diff to sticky comment - uses: marocchino/sticky-pull-request-comment@v2 - with: - delete: ${{ !steps.gas_diff.outputs.markdown }} - message: ${{ steps.gas_diff.outputs.markdown }} - - prep-checker: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: - - ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v5 - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Install Dependencies - run: forge install - - name: Run prep scripts and forge fmt - run: > - ( node prep/all && - forge fmt - ) - - - name: Check for file changes - run: | - if [[ $(git status --porcelain) ]]; then - echo "Please run 'node prep/all.js' and commit the changes." - exit 1 - fi \ No newline at end of file diff --git a/grouperBot/lib/solady/.gitignore b/grouperBot/lib/solady/.gitignore deleted file mode 100644 index e769a8f..0000000 --- a/grouperBot/lib/solady/.gitignore +++ /dev/null @@ -1,44 +0,0 @@ -# NodeJS files -node_modules/ -coverage -coverage.json -typechain - -# Hardhat files -cache -artifacts - -cache/ -out/ - -# Ignore Environment Variables! -.env -.env.prod - -# Ignore all vscode settings -.vscode/ - -# Ignore all jetbrain settings -.idea/ - -# Ignore all notes -notes/ - -# Ignore flattened files -flattened.txt - -broadcast - -# Coverage -lcov.info - -# Woke testing -.wake -pytypes -__pycache__/ -*.py[cod] -.hypothesis/ -wake-coverage.cov - -# We will use the CI to check for the gas difference -.gas-snapshot diff --git a/grouperBot/lib/solady/LICENSE.txt b/grouperBot/lib/solady/LICENSE.txt deleted file mode 100644 index 28043ce..0000000 --- a/grouperBot/lib/solady/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022-2025 Solady. - -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/grouperBot/lib/solady/README.md b/grouperBot/lib/solady/README.md deleted file mode 100644 index 60e81e7..0000000 --- a/grouperBot/lib/solady/README.md +++ /dev/null @@ -1,182 +0,0 @@ -# solady - -[![NPM][npm-shield]][npm-url] -[![CI][ci-shield]][ci-url] -[![Solidity][solidity-shield]][solidity-ci-url] -[![Docs][docs-shield]][docs-url] - -Gas optimized Solidity snippets. - -I'm sooooooOooooooooOoooOoooooooooooooooo... - -## Installation - -To install with [**Foundry**](https://github.com/foundry-rs/foundry): - -```sh -forge install vectorized/solady -``` - -To install with [**Hardhat**](https://github.com/nomiclabs/hardhat): - -```sh -npm install solady -``` - -## Documentation - -https://vectorized.github.io/solady - -## Contracts - -The Solidity smart contracts are located in the `src` directory. - -```ml -accounts -├─ EIP7702Proxy — "Relay proxy for EIP7702 delegations" -├─ ERC1271 — "ERC1271 mixin with nested EIP-712 approach" -├─ ERC4337 — "Simple ERC4337 account implementation" -├─ ERC4337Factory — "Simple ERC4337 account factory implementation" -├─ ERC6551 — "Simple ERC6551 account implementation" -├─ ERC6551Proxy — "Relay proxy for upgradeable ERC6551 accounts" -├─ ERC7821 — "Minimal batch executor mixin" -├─ LibEIP7702 — "Library for EIP7702 operations" -├─ LibERC6551 — "Library for interacting with ERC6551 accounts" -├─ LibERC7579 — "Library for handling ERC7579 mode and execution data" -├─ Receiver — "Receiver mixin for ETH and safe-transferred ERC721 and ERC1155 tokens" -├─ Timelock — "Simple timelock" -auth -├─ EnumerableRoles — "Enumerable multiroles authorization mixin" -├─ Ownable — "Simple single owner authorization mixin" -├─ OwnableRoles — "Simple single owner and multiroles authorization mixin" -├─ TimedRoles — "Timed multiroles authorization mixin" -tokens -├─ ERC1155 — "Simple ERC1155 implementation" -├─ ERC20 — "Simple ERC20 + EIP-2612 implementation" -├─ ERC20Votes — "ERC20 with votes based on ERC5805 and ERC6372" -├─ ERC2981 — "Simple ERC2981 NFT Royalty Standard implementation" -├─ ERC4626 — "Simple ERC4626 tokenized Vault implementation" -├─ ERC6909 — "Simple EIP-6909 minimal multi-token implementation" -├─ ERC721 — "Simple ERC721 implementation with storage hitchhiking" -├─ WETH — "Simple Wrapped Ether implementation" -utils -├─ Base58 — "Library for Base58 encoding and decoding" -├─ Base64 — "Library for Base64 encoding and decoding" -├─ BlockHashLib — "Library for accessing block hashes way beyond the 256-block limit" -├─ CallContextChecker — "Call context checker mixin" -├─ CREATE3 — "Deterministic deployments agnostic to the initialization code" -├─ DateTimeLib — "Library for date time operations" -├─ DeploylessPredeployQueryer — "Deployless queryer for predeploys" -├─ DynamicArrayLib — "Library for memory arrays with automatic capacity resizing" -├─ DynamicBufferLib — "Library for buffers with automatic capacity resizing" -├─ ECDSA — "Library for verification of ECDSA signatures" -├─ EIP712 — "Contract for EIP-712 typed structured data hashing and signing" -├─ ERC1967Factory — "Factory for deploying and managing ERC1967 proxy contracts" -├─ ERC1967FactoryConstants — "The address and bytecode of the canonical ERC1967Factory" -├─ EfficientHashLib — "Library for efficiently performing keccak256 hashes" -├─ EnumerableMapLib — "Library for managing enumerable maps in storage" -├─ EnumerableSetLib — "Library for managing enumerable sets in storage" -├─ FixedPointMathLib — "Arithmetic library with operations for fixed-point numbers" -├─ GasBurnerLib — "Library for burning gas without reverting" -├─ Initializable — "Initializable mixin for the upgradeable contracts" -├─ JSONParserLib — "Library for parsing JSONs" -├─ LibBit — "Library for bit twiddling and boolean operations" -├─ LibBitmap — "Library for storage of packed booleans" -├─ LibClone — "Minimal proxy library" -├─ LibMap — "Library for storage of packed unsigned integers" -├─ LibPRNG — "Library for generating pseudorandom numbers" -├─ LibRLP — "Library for RLP encoding and CREATE address computation" -├─ LibSort — "Library for efficient sorting of memory arrays" -├─ LibStorage — "Library for basic storage operations" -├─ LibString — "Library for converting numbers into strings and other string operations" -├─ LibTransient — "Library for transient storage operations" -├─ LibZip — "Library for compressing and decompressing bytes" -├─ Lifebuoy — "Class that allows for rescue of ETH, ERC20, ERC721 tokens" -├─ MerkleProofLib — "Library for verification of Merkle proofs" -├─ MerkleTreeLib — "Library for generating Merkle trees" -├─ MetadataReaderLib — "Library for reading contract metadata robustly" -├─ MinHeapLib — "Library for managing a min-heap in storage or memory" -├─ Multicallable — "Contract that enables a single call to call multiple methods on itself" -├─ P256 — "Gas optimized P256 wrapper" -├─ RedBlackTreeLib — "Library for managing a red-black-tree in storage" -├─ ReentrancyGuard — "Reentrancy guard mixin" -├─ SSTORE2 — "Library for cheaper reads and writes to persistent storage" -├─ SafeCastLib — "Library for integer casting that reverts on overflow" -├─ SafeTransferLib — "Safe ERC20/ETH transfer lib that handles missing return values" -├─ SemVerLib — "Library for comparing SemVers" -├─ SignatureCheckerLib — "Library for verification of ECDSA and ERC1271 signatures" -├─ UUPSUpgradeable — "UUPS proxy mixin" -├─ UpgradeableBeacon — "Upgradeable beacon for ERC1967 beacon proxies" -├─ WebAuthn — "WebAuthn helper" -├─ legacy — "Legacy support" -└─ ext — "Utilities for external protocols" -``` - -## Directories - -```ml -src — "Solidity smart contracts" -test — "Foundry Forge tests" -js — "Accompanying JavaScript helper library" -ext — "Extra tests" -prep — "Preprocessing scripts" -audits — "Audit reports" -``` - -## Contributing - -This repository serves as a laboratory for cutting edge snippets that may be merged into [Solmate](https://github.com/transmissions11/solmate). - -Feel free to make a pull request. - -Do refer to the [contribution guidelines](https://github.com/Vectorized/solady/issues/19) for more details. - -## Safety - -This is **experimental software** and is provided on an "as is" and "as available" basis. - -We **do not give any warranties** and **will not be liable for any loss** incurred through any use of this codebase. - -While Solady has been heavily tested, there may be parts that may exhibit unexpected emergent behavior when used with other code, or may break in future Solidity versions. - -Please always include your own thorough tests when using Solady to make sure it works correctly with your code. - -## Upgradability - -Most contracts in Solady are compatible with both upgradeable and non-upgradeable (i.e. regular) contracts. - -Please call any required internal initialization methods accordingly. - -## EVM Compatibility - -Some parts of Solady may not be compatible with chains with partial EVM equivalence. - -Please always check and test for compatibility accordingly. - -If you are deploying on ZKsync stack (e.g. Abstract) with partial EVM equivalence: - -- Run `node prep/zksync-compat-analysis.js` to scan the files. -- For files that have incompatibilities (i.e. non-zero scores), look into the `ext/zksync` directories for substitutes. The substitutes may only have a subset of the original features. If there is no substitute, it means that the file is incompatible and infeasible to be implemented for ZKsync. - -## Acknowledgements - -This repository is inspired by or directly modified from many sources, primarily: - -- [Solmate](https://github.com/transmissions11/solmate) -- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) -- [ERC721A](https://github.com/chiru-labs/ERC721A) -- [Zolidity](https://github.com/z0r0z/zolidity) -- [🐍 Snekmate](https://github.com/pcaversaccio/snekmate) -- [Femplate](https://github.com/abigger87/femplate) - -[npm-shield]: https://img.shields.io/npm/v/solady.svg -[npm-url]: https://www.npmjs.com/package/solady - -[ci-shield]: https://img.shields.io/github/actions/workflow/status/vectorized/solady/ci.yml?branch=main&label=build -[ci-url]: https://github.com/vectorized/solady/actions/workflows/ci.yml - -[solidity-shield]: https://img.shields.io/badge/solidity-%3E=0.8.4%20%3C=0.8.30-aa6746 -[solidity-ci-url]: https://github.com/Vectorized/solady/actions/workflows/ci-all-via-ir.yml - -[docs-shield]: https://img.shields.io/badge/docs-%F0%9F%93%84-blue -[docs-url]: https://vectorized.github.io/solady diff --git a/grouperBot/lib/solady/audits/ackee-blockchain-solady-report.pdf b/grouperBot/lib/solady/audits/ackee-blockchain-solady-report.pdf deleted file mode 100644 index 04ac76c..0000000 Binary files a/grouperBot/lib/solady/audits/ackee-blockchain-solady-report.pdf and /dev/null differ diff --git a/grouperBot/lib/solady/audits/cantina-solady-report.pdf b/grouperBot/lib/solady/audits/cantina-solady-report.pdf deleted file mode 100644 index 3854df0..0000000 Binary files a/grouperBot/lib/solady/audits/cantina-solady-report.pdf and /dev/null differ diff --git a/grouperBot/lib/solady/audits/cantina-spearbit-coinbase-solady-report.pdf b/grouperBot/lib/solady/audits/cantina-spearbit-coinbase-solady-report.pdf deleted file mode 100644 index d850c30..0000000 Binary files a/grouperBot/lib/solady/audits/cantina-spearbit-coinbase-solady-report.pdf and /dev/null differ diff --git a/grouperBot/lib/solady/audits/shung-solady-erc721-audit.pdf b/grouperBot/lib/solady/audits/shung-solady-erc721-audit.pdf deleted file mode 100644 index 471a9ff..0000000 Binary files a/grouperBot/lib/solady/audits/shung-solady-erc721-audit.pdf and /dev/null differ diff --git a/grouperBot/lib/solady/audits/xuwinnie-solady-cbrt-proof.pdf b/grouperBot/lib/solady/audits/xuwinnie-solady-cbrt-proof.pdf deleted file mode 100644 index 1f05047..0000000 Binary files a/grouperBot/lib/solady/audits/xuwinnie-solady-cbrt-proof.pdf and /dev/null differ diff --git a/grouperBot/lib/solady/ext/wake/EIP712Mock.sol b/grouperBot/lib/solady/ext/wake/EIP712Mock.sol deleted file mode 100644 index b0a7916..0000000 --- a/grouperBot/lib/solady/ext/wake/EIP712Mock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -import "src/utils/EIP712.sol"; - -contract EIP712Mock is EIP712 { - string constant public NAME = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ipsum massa, ullamcorper in, auctor et, scelerisque sed, est. Maecenas libero. Phasellus et lorem id felis nonummy placerat. Vestibulum erat nulla, ullamcorper nec, rutrum non, nonummy ac, erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam commodo dui eget wisi. Duis viverra diam non justo. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Mauris elementum mauris vitae tortor. Ut tempus purus at lorem. Maecenas sollicitudin. Vivamus ac leo pretium faucibus. Vivamus luctus egestas leo. Proin in tellus sit amet nibh dignissim sagittis. Aliquam erat volutpat. Cras elementum. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Fusce wisi. Suspendisse sagittis ultrices augue. Aenean id metus id velit ullamcorper pulvinar. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. Cras elementum. Nunc auctor. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Nulla est. Aliquam ornare wisi eu metus. Et harum quidem rerum facilis est et expedita distinctio. Mauris metus. Phasellus faucibus molestie nisl. Mauris tincidunt sem sed arcu. Aenean placerat. Etiam neque. Nullam feugiat, turpis at pulvinar vulputate, erat libero tristique tellus, nec bibendum odio risus sit amet ante. Nullam dapibus fermentum ipsum. Mauris tincidunt sem sed arcu. Nam quis nulla. Nullam feugiat, turpis at pulvinar vulputate, erat libero tristique tellus, nec bibendum odio risus sit amet ante. Pellentesque sapien. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Vestibulum erat nulla, ullamcorper nec, rutrum non, nonummy ac, erat. Maecenas aliquet accumsan leo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nullam rhoncus aliquam metus. Praesent vitae arcu tempor neque lacinia pretium. Nulla pulvinar eleifend sem. Etiam bibendum elit eget erat. Aenean placerat. Mauris metus. Aenean fermentum risus id tortor. Suspendisse nisl. Fusce wisi. Fusce nibh. Sed vel lectus. Donec odio tempus molestie, porttitor ut, iaculis quis, sem. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Mauris elementum mauris vitae tortor. Duis sapien nunc, commodo et, interdum suscipit, sollicitudin et, dolor. Quisque tincidunt scelerisque libero. Vivamus luctus egestas leo. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Duis risus. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Suspendisse nisl. Cras elementum. Phasellus rhoncus. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. In enim a arcu imperdiet malesuada. In dapibus augue non sapien. "; - string constant public VERSION = "1.0.0"; - - function _domainNameAndVersion() internal pure override returns (string memory, string memory) { - return (NAME, VERSION); - } - - function hashTypedData(bytes32 structHash) external view returns(bytes32) { - return _hashTypedData(structHash); - } - -} \ No newline at end of file diff --git a/grouperBot/lib/solady/ext/wake/ERC1155Mock.sol b/grouperBot/lib/solady/ext/wake/ERC1155Mock.sol deleted file mode 100644 index bcc75ee..0000000 --- a/grouperBot/lib/solady/ext/wake/ERC1155Mock.sol +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: MIT -import "src/tokens/ERC1155.sol"; - -contract ERC1155Mock is ERC1155 { - event BeforeTokenTransfer(address from, address to, uint256[] ids, uint256[] amounts, bytes data); - - event AfterTokenTransfer(address from, address to, uint256[] ids, uint256[] amounts, bytes data); - - bool immutable private _enableHooks; - - constructor(bool enableHooks_) { - _enableHooks = enableHooks_; - } - - function _useBeforeTokenTransfer() internal view override returns (bool) { - return _enableHooks; - } - - function _useAfterTokenTransfer() internal view override returns (bool) { - return _enableHooks; - } - - function _beforeTokenTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal override { - emit BeforeTokenTransfer(from, to, ids, amounts, data); - } - - function _afterTokenTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal override { - emit AfterTokenTransfer(from, to, ids, amounts, data); - } - - function uri(uint256 id) public view override returns (string memory) {} - - function mint(address to, uint256 id, uint256 amount, bytes memory data) external { - _mint(to, id, amount, data); - } - - function batchMint( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) external { - _batchMint(to, ids, amounts, data); - } - - function burnUnchecked(address by, address from, uint256 id, uint256 amount) external { - _burn(by, from, id, amount); - } - - function burn(address from, uint256 id, uint256 amount) external { - _burn(msg.sender, from, id, amount); - } - - function batchBurnUnchecked(address by, address from, uint256[] memory ids, uint256[] memory amounts) external { - _batchBurn(by, from, ids, amounts); - } - - function batchBurn(address from, uint256[] memory ids, uint256[] memory amounts) external { - _batchBurn(msg.sender, from, ids, amounts); - } - - function setApprovalForAllUnchecked(address by, address operator, bool approved) external { - _setApprovalForAll(by, operator, approved); - } - - function safeTransferUnchecked( - address by, - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) external { - _safeTransfer(by, from, to, id, amount, data); - } - - function safeBatchTransferUnchecked( - address by, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) external { - _safeBatchTransfer(by, from, to, ids, amounts, data); - } -} - -contract ERC1155ReceiverMock { - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes calldata data - ) external pure returns(bytes4) { - require(keccak256(data) == keccak256(hex"00112233"), "ERC1155ReceiverMock: invalid payload received"); - return this.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata data - ) external pure returns(bytes4) { - require(keccak256(data) == keccak256(hex"00112233"), "ERC1155ReceiverMock: invalid payload received"); - return this.onERC1155BatchReceived.selector; - } -} - -contract ERC1155ReentrancyAttacker { - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes calldata data - ) external returns(bytes4) { - if (data.length == 0) - ERC1155Mock(msg.sender).mint(address(this), 1024, 1, hex"00112233"); - return this.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata data - ) external returns(bytes4) { - if (data.length == 0) - ERC1155Mock(msg.sender).mint(address(this), 1024, 1, hex"00112233"); - return this.onERC1155BatchReceived.selector; - } -} \ No newline at end of file diff --git a/grouperBot/lib/solady/ext/wake/ERC20Mock.sol b/grouperBot/lib/solady/ext/wake/ERC20Mock.sol deleted file mode 100644 index a4a2fae..0000000 --- a/grouperBot/lib/solady/ext/wake/ERC20Mock.sol +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/* -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣷⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠿⣿⣿⣿⣿⣿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣤⣴⣶⣾⣿⣷⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠻⢿⣿⣿⣿⣿⣷⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⢿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⣿⣿⡿⠿⠟⠛⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⣿⣿⣿⣆⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⡿⠟⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣧⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣶⣿⣿⣿⣿⣿⣿⣿⣶⣤⡀⠀⠙⠋⠀⠀⠀ -⠀⠀⠀⠀⠀⣠⣾⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣾⠟⢋⣥⣤⠀⣶⣶⣶⣦⣤⣌⣉⠛⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⣴⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠋⢁⣴⣿⣿⡿⠀⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀ -⠀⠀⠀⣼⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣶⣶⣾⣿⣿⣿⣿⣷⣶⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⠁⠀⠀⢹⣿⣿⣿⣿⣿⣿⢻⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠛⠋⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⣿⠿⠛⣛⣉⣉⣀⣀⡀⠀⠀⠀⠀⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⢸⣿⣿⡄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⡿⢋⣩⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣦⣀⣀⣴⣿⣿⣿⣿⣿⡿⢸⣿⢿⣷⡀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣡⣄⠀⠋⠁⠀⠈⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⡟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⡿⠀⠛⠃⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣧⡀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠛⠃⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠈⠁⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⢿⣿⣿⣿⣷⣦⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣶⣶⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⣿⠇⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⢠⣿⣿⣿⠟⠉⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⠀⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⢸⣿⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⣼⣿⡟⠁⣠⣦⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠉⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡆⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⠏⠀⣸⡏⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⣿⡏⠀⠀⣿⣿⡀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⢹⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣇⠀⠀⠀⠙⢿⣿⣿⡿⠟⠁⠀⣸⡿⠁⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⢸⣿⠁⠀⠀⢸⣿⣇⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⢀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣦⡀⠀⠀⠀⠈⠉⠀⠀⠀⣼⡿⠁⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠈⠁⠀⠀⠀⠀⢿⣿⡄⠀⠀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⠀⣼⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⣦⣄⣀⠀⠀⢀⡈⠙⠁⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣆⠀⠀⠀⠉⠛⠿⢿⣿⣿⠿⠛⠁⠀⠀⠀⣠⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠿⣿⣿⣷⣿⣯⣤⣶⠄⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣷⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠙⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⣤⣀⠀⠀⠀⠀⠀⠀⠀⠺⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢻⣿⣶⣤⣤⣤⣶⣷⣤⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⡿⠿⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠶⢤⣄⣀⣀⣤⠶⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀*/ - -import "src/tokens/ERC20.sol"; -import "src/utils/SafeTransferLib.sol"; - -interface IERC20 { - event Transfer(address indexed from, address indexed to, uint256 value); - event Approval(address indexed owner, address indexed spender, uint256 value); - function totalSupply() external view returns (uint256); - function balanceOf(address account) external view returns (uint256); - function transfer(address to, 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 from, address to, uint256 amount) external returns (bool); -} - -contract ERC20Mock is ERC20 { - string private $name; - string private $symbol; - uint8 private $decimals; - - constructor(string memory name_, string memory symbol_, uint8 decimals_) { - $name = name_; - $symbol = symbol_; - $decimals = decimals_; - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - function name() public view virtual override returns (string memory) { - return $name; - } - - function symbol() public view virtual override returns (string memory) { - return $symbol; - } - - function decimals() public view virtual override returns (uint8) { - return $decimals; - } - - function safeTransferETH(address to, uint256 value) public { - SafeTransferLib.safeTransferETH(to, value); - } - - function forceSafeTransferETH(address to, uint256 value) public { - SafeTransferLib.forceSafeTransferETH(to, value); - } - - function forceSafeTransferETHGas(address to, uint256 value, uint256 gas) public { - SafeTransferLib.forceSafeTransferETH(to, value, gas); - } - - function trySafeTransferETH(address to, uint256 value, uint256 gasStipend) public returns (bool) { - return SafeTransferLib.trySafeTransferETH(to, value, gasStipend); - } - - function safeTransferFrom(address token, address from, address to, uint256 value) public { - SafeTransferLib.safeTransferFrom(token, from, to, value); - } - - function safeTransferAllFrom(address token, address from, address to) public { - SafeTransferLib.safeTransferAllFrom(token, from, to); - } - - function safeTransfer(address token, address to, uint256 value) public { - SafeTransferLib.safeTransfer(token, to, value); - } - - function safeTransferAll(address token, address to) public { - SafeTransferLib.safeTransferAll(token, to); - } - - function safeApprove(address token, address spender, uint256 value) public { - SafeTransferLib.safeApprove(token, spender, value); - } - - function balanceOfoor(address token, address account) public view returns (uint256) { - return SafeTransferLib.balanceOf(token, account); - } -} diff --git a/grouperBot/lib/solady/ext/wake/ERC721Mock.sol b/grouperBot/lib/solady/ext/wake/ERC721Mock.sol deleted file mode 100644 index 88aa7f1..0000000 --- a/grouperBot/lib/solady/ext/wake/ERC721Mock.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -import "src/tokens/ERC721.sol"; -contract ERC721Mock is ERC721 { - - event BeforeTokenTransfer(address from, address to, uint256 id); - - event AfterTokenTransfer(address from, address to, uint256 id); - - uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; - /// @dev Returns the token collection name. - function name() public view override returns (string memory) { - return "Mock ERC721"; - } - /// @dev Returns the token collection symbol. - function symbol() public view override returns (string memory) { - return "MERC721"; - } - /// @dev Returns the Uniform Resource Identifier (URI) for token `id`. - function tokenURI(uint256 id) public view override returns (string memory) { - return "aaa"; - } - function getAux(address owner) public view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - result := shr(32, sload(keccak256(0x0c, 0x1c))) - } - } - function _beforeTokenTransfer( - address from, - address to, - uint256 id - ) internal override { - emit BeforeTokenTransfer(from, to, id); - } - - function _afterTokenTransfer( - address from, - address to, - uint256 id - ) internal override { - emit AfterTokenTransfer(from, to, id); - } - - function mint(address to, uint256 id) public { - _mint(to, id); - } - - function burnZero(uint256 id) public { - _burn(id); - } - - function burn(uint256 id) public { - _burn(msg.sender, id); - } - - function transfer(address from, address to, uint256 id) public { - _transfer(msg.sender, from, to, id); - } - - - function balanceOf(address owner) public view virtual override returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - // Revert if the `owner` is the zero address. - if iszero(owner) { - mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`. - revert(0x1c, 0x04) - } - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE) - } - } - function ownerOf(uint256 id) public view virtual override returns (address result) { - result = _ownerOf(id); - /// @solidity memory-safe-assembly - assembly { - if iszero(result) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - } - } -} \ No newline at end of file diff --git a/grouperBot/lib/solady/ext/wake/MerkleProofMock.sol b/grouperBot/lib/solady/ext/wake/MerkleProofMock.sol deleted file mode 100644 index 57c28a0..0000000 --- a/grouperBot/lib/solady/ext/wake/MerkleProofMock.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -import "src/utils/MerkleProofLib.sol"; - -contract MerkleProofMock { - function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) external pure returns (bool) { - return MerkleProofLib.verify(proof, root, leaf); - } - - function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) external pure returns (bool) { - return MerkleProofLib.verify(proof, root, leaf); - } - - function verifyMultiProof(bytes32[] memory proof, bytes32 root, bytes32[] memory leaves, bool[] memory flags) external pure returns (bool) { - return MerkleProofLib.verifyMultiProof(proof, root, leaves, flags); - } - - function verifyMultiProofCalldata(bytes32[] calldata proof, bytes32 root, bytes32[] calldata leaves, bool[] calldata flags) external pure returns (bool) { - return MerkleProofLib.verifyMultiProof(proof, root, leaves, flags); - } -} \ No newline at end of file diff --git a/grouperBot/lib/solady/ext/wake/NoETHMock.sol b/grouperBot/lib/solady/ext/wake/NoETHMock.sol deleted file mode 100644 index 7453f38..0000000 --- a/grouperBot/lib/solady/ext/wake/NoETHMock.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/* -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣷⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠿⣿⣿⣿⣿⣿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣤⣴⣶⣾⣿⣷⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠻⢿⣿⣿⣿⣿⣷⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⢿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⣿⣿⡿⠿⠟⠛⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⣿⣿⣿⣆⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⡿⠟⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣧⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣶⣿⣿⣿⣿⣿⣿⣿⣶⣤⡀⠀⠙⠋⠀⠀⠀ -⠀⠀⠀⠀⠀⣠⣾⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣾⠟⢋⣥⣤⠀⣶⣶⣶⣦⣤⣌⣉⠛⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⣴⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠋⢁⣴⣿⣿⡿⠀⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀ -⠀⠀⠀⣼⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣶⣶⣾⣿⣿⣿⣿⣷⣶⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⠁⠀⠀⢹⣿⣿⣿⣿⣿⣿⢻⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠛⠋⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⣿⠿⠛⣛⣉⣉⣀⣀⡀⠀⠀⠀⠀⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⢸⣿⣿⡄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⡿⢋⣩⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣦⣀⣀⣴⣿⣿⣿⣿⣿⡿⢸⣿⢿⣷⡀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣡⣄⠀⠋⠁⠀⠈⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⡟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⡿⠀⠛⠃⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣧⡀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠛⠃⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠈⠁⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⢿⣿⣿⣿⣷⣦⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣶⣶⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⣿⠇⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⢠⣿⣿⣿⠟⠉⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⠀⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⢸⣿⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⣼⣿⡟⠁⣠⣦⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠉⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡆⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⠏⠀⣸⡏⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⣿⡏⠀⠀⣿⣿⡀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⢹⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣇⠀⠀⠀⠙⢿⣿⣿⡿⠟⠁⠀⣸⡿⠁⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⢸⣿⠁⠀⠀⢸⣿⣇⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⢀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣦⡀⠀⠀⠀⠈⠉⠀⠀⠀⣼⡿⠁⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠈⠁⠀⠀⠀⠀⢿⣿⡄⠀⠀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⠀⣼⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⣦⣄⣀⠀⠀⢀⡈⠙⠁⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣆⠀⠀⠀⠉⠛⠿⢿⣿⣿⠿⠛⠁⠀⠀⠀⣠⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠿⣿⣿⣷⣿⣯⣤⣶⠄⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣷⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠙⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⣤⣀⠀⠀⠀⠀⠀⠀⠀⠺⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢻⣿⣶⣤⣤⣤⣶⣷⣤⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⡿⠿⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠶⢤⣄⣀⣀⣤⠶⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀*/ - -contract NoETHMock { - receive() external payable { - revert("No ETH pls"); - } - fallback() external payable { - revert("No ETH pls"); - } -} diff --git a/grouperBot/lib/solady/ext/wake/SignatureCheckerMock.sol b/grouperBot/lib/solady/ext/wake/SignatureCheckerMock.sol deleted file mode 100644 index 9f6db20..0000000 --- a/grouperBot/lib/solady/ext/wake/SignatureCheckerMock.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -import "src/utils/SignatureCheckerLib.sol"; - -contract SignatureCheckerMock { - function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) external view returns (bool) { - return SignatureCheckerLib.isValidSignatureNow(signer, hash, signature); - } - - function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) external view returns (bool) { - return SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature); - } - - function isValidSignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) external view returns(bool) { - return SignatureCheckerLib.isValidSignatureNow(signer, hash, r, vs); - } - - function isValidSignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) external view returns(bool) { - return SignatureCheckerLib.isValidSignatureNow(signer, hash, v, r, s); - } - - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes memory signature) external view returns (bool) { - return SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, signature); - } - - function isValidERC1271SignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) external view returns (bool) { - return SignatureCheckerLib.isValidERC1271SignatureNowCalldata(signer, hash, signature); - } - - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) external view returns(bool) { - return SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, r, vs); - } - - function isValidERC1271SignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) external view returns(bool) { - return SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, v, r, s); - } -} - -contract ERC1271SignatureChecker { - bytes4 constant internal MAGICVALUE = 0x1626ba7e; - - function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) { - uint8 v; - bytes32 r; - bytes32 s; - - assembly { - r := mload(add(_signature, 0x20)) - s := mload(add(_signature, 0x40)) - v := byte(0, mload(add(_signature, 0x60))) - } - - if (tx.origin == ecrecover(_hash, v, r, s)) { - return MAGICVALUE; - } else { - return 0x0; - } - } -} \ No newline at end of file diff --git a/grouperBot/lib/solady/ext/wake/__init__.py b/grouperBot/lib/solady/ext/wake/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/grouperBot/lib/solady/ext/wake/test_eip712.py b/grouperBot/lib/solady/ext/wake/test_eip712.py deleted file mode 100644 index 35ccd4e..0000000 --- a/grouperBot/lib/solady/ext/wake/test_eip712.py +++ /dev/null @@ -1,82 +0,0 @@ -from dataclasses import dataclass, field - -from eth_account._utils.structured_data.hashing import hash_message -from wake.testing import * -from pytypes.src.utils.ERC1967Factory import ERC1967Factory -from pytypes.tests.EIP712Mock import EIP712Mock - - -@dataclass -class Person: - name: str - wallet: Address - - -@dataclass -class Mail: - from_: Person = field(metadata={"original_name": "from"}) - to: Person - contents: str - - -mail = Mail( - from_=Person("Cow", Address("0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826")), - to=Person("Bob", Address("0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB")), - contents="Hello, Bob!", -) - - -@default_chain.connect() -def test_eip712(): - signer = Account.new() - - eip712 = EIP712Mock.deploy() - assert eip712.eip712Domain() == ( - 0b01111.to_bytes(1, "big"), - eip712.NAME(), - eip712.VERSION(), - default_chain.chain_id, - eip712.address, - b"\x00" * 32, - [], - ) - - mail_hash = hash_message(signer._prepare_eip712_dict(mail, Eip712Domain(), False)) - - sign1 = signer.sign_hash(eip712.hashTypedData(mail_hash)) - sign2 = signer.sign_structured(mail, Eip712Domain( - name=eip712.NAME(), - version=eip712.VERSION(), - chainId=default_chain.chain_id, - verifyingContract=eip712.address, - )) - assert sign1 == sign2 - - -@default_chain.connect() -def test_eip712_proxy(): - signer = Account.new() - - proxy_factory = ERC1967Factory.deploy() - impl = EIP712Mock.deploy() - eip712 = EIP712Mock(proxy_factory.deploy_(impl, signer).return_value) - assert eip712.eip712Domain() == ( - 0b01111.to_bytes(1, "big"), - eip712.NAME(), - eip712.VERSION(), - default_chain.chain_id, - eip712.address, - b"\x00" * 32, - [], - ) - - mail_hash = hash_message(signer._prepare_eip712_dict(mail, Eip712Domain(), False)) - - sign1 = signer.sign_hash(eip712.hashTypedData(mail_hash)) - sign2 = signer.sign_structured(mail, Eip712Domain( - name=eip712.NAME(), - version=eip712.VERSION(), - chainId=default_chain.chain_id, - verifyingContract=eip712.address, - )) - assert sign1 == sign2 diff --git a/grouperBot/lib/solady/ext/wake/test_eip712_fuzz.py b/grouperBot/lib/solady/ext/wake/test_eip712_fuzz.py deleted file mode 100644 index b5efcb4..0000000 --- a/grouperBot/lib/solady/ext/wake/test_eip712_fuzz.py +++ /dev/null @@ -1,64 +0,0 @@ -from dataclasses import dataclass, field - -from eth_account._utils.structured_data.hashing import hash_message -from wake.testing import * -from wake.testing.fuzzing import * -from pytypes.src.utils.ERC1967Factory import ERC1967Factory -from pytypes.tests.EIP712Mock import EIP712Mock - - -@dataclass -class Person: - name: str - wallet: Address - - -@dataclass -class Mail: - from_: Person = field(metadata={"original_name": "from"}) - to: Person - contents: str - - -class Eip712FuzzTest(FuzzTest): - _proxy_factory: ERC1967Factory - _eip712: EIP712Mock - _eip712_proxy: EIP712Mock - _signer: Account - - def __init__(self): - self._proxy_factory = ERC1967Factory.deploy() - - def pre_sequence(self) -> None: - self._eip712 = EIP712Mock.deploy() - self._signer = Account.new() - self._eip712_proxy = EIP712Mock( - self._proxy_factory.deploy_(self._eip712, self._signer).return_value - ) - - @flow() - def sign_flow(self, mail: Mail) -> None: - mail_hash = hash_message(self._signer._prepare_eip712_dict(mail, Eip712Domain(), False)) - - sign1 = self._signer.sign_hash(self._eip712.hashTypedData(mail_hash)) - sign2 = self._signer.sign_structured(mail, Eip712Domain( - name=self._eip712.NAME(), - version=self._eip712.VERSION(), - chainId=default_chain.chain_id, - verifyingContract=self._eip712.address, - )) - assert sign1 == sign2 - - sign1 = self._signer.sign_hash(self._eip712_proxy.hashTypedData(mail_hash)) - sign2 = self._signer.sign_structured(mail, Eip712Domain( - name=self._eip712_proxy.NAME(), - version=self._eip712_proxy.VERSION(), - chainId=default_chain.chain_id, - verifyingContract=self._eip712_proxy.address, - )) - assert sign1 == sign2 - - -@default_chain.connect() -def test_eip712_fuzz(): - Eip712FuzzTest().run(10, 10) diff --git a/grouperBot/lib/solady/ext/wake/test_erc1155.py b/grouperBot/lib/solady/ext/wake/test_erc1155.py deleted file mode 100644 index 0b7522e..0000000 --- a/grouperBot/lib/solady/ext/wake/test_erc1155.py +++ /dev/null @@ -1,443 +0,0 @@ -from wake.testing import * -from pytypes.tests.ERC1155Mock import ERC1155Mock, ERC1155ReceiverMock - - -@default_chain.connect() -def test_erc1155_misc(): - a = default_chain.accounts[0] - - erc1155 = ERC1155Mock.deploy(False, from_=a) - - # ERC-165 - assert erc1155.supportsInterface(bytes.fromhex("01ffc9a7")) - # ERC-1155 - assert erc1155.supportsInterface(bytes.fromhex("d9b67a26")) - # ERC-1155 Metadata URI - assert erc1155.supportsInterface(bytes.fromhex("0e89341c")) - - assert not erc1155.supportsInterface(bytes.fromhex("deadbeef")) - - erc1155.mint(a, 0, 100, b"\x00\x11", from_=a) - erc1155.setApprovalForAll(a, False, from_=a) - assert not erc1155.isApprovedForAll(a, a) - erc1155.safeTransferFrom(a, a, 0, 100, b"\x00\x11", from_=a) - assert erc1155.balanceOf(a, 0) == 100 - - # check overflow when sending to self - erc1155.mint(a, 0, 2 ** 256 - 1 - 100, b"", from_=a) - erc1155.safeTransferFrom(a, a, 0, 2 ** 256 - 1, b"", from_=a) - assert erc1155.balanceOf(a, 0) == 2 ** 256 - 1 - - -@default_chain.connect() -def test_erc1155_events(): - assert keccak256("TransferSingle(address,address,address,uint256,uint256)".encode()) == bytes.fromhex("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62") - assert keccak256("TransferBatch(address,address,address,uint256[],uint256[])".encode()) == bytes.fromhex("4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb") - assert keccak256("ApprovalForAll(address,address,bool)".encode()) == bytes.fromhex("17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31") - - a = default_chain.accounts[0] - b = default_chain.accounts[1] - - erc1155 = ERC1155Mock.deploy(True, from_=a) - - tx = erc1155.mint(a, 0, 100, b"\x00\x11", from_=a) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(Address.ZERO, a.address, [0], [100], bytearray(b"\x00\x11")), - ERC1155Mock.TransferSingle(a.address, Address.ZERO, a.address, 0, 100), - ERC1155Mock.AfterTokenTransfer(Address.ZERO, a.address, [0], [100], bytearray(b"\x00\x11")), - ] - - tx = erc1155.burn(a, 0, 100, from_=a) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, Address.ZERO, [0], [100], bytearray(b"")), - ERC1155Mock.TransferSingle(a.address, a.address, Address.ZERO, 0, 100), - ERC1155Mock.AfterTokenTransfer(a.address, Address.ZERO, [0], [100], bytearray(b"")), - ] - - tx = erc1155.batchMint(a, [0, 1, 2], [100, 200, 300], b"\x11\x22", from_=a) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(Address.ZERO, a.address, [0, 1, 2], [100, 200, 300], bytearray(b"\x11\x22")), - ERC1155Mock.TransferBatch(a.address, Address.ZERO, a.address, [0, 1, 2], [100, 200, 300]), - ERC1155Mock.AfterTokenTransfer(Address.ZERO, a.address, [0, 1, 2], [100, 200, 300], bytearray(b"\x11\x22")), - ] - - tx = erc1155.batchBurn(a, [0, 1, 2], [100, 200, 300], from_=a) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, Address.ZERO, [0, 1, 2], [100, 200, 300], bytearray(b"")), - ERC1155Mock.TransferBatch(a.address, a.address, Address.ZERO, [0, 1, 2], [100, 200, 300]), - ERC1155Mock.AfterTokenTransfer(a.address, Address.ZERO, [0, 1, 2], [100, 200, 300], bytearray(b"")), - ] - - erc1155.mint(a, 0, 100, b"", from_=a) - tx = erc1155.safeTransferFrom(a, b, 0, 100, b"", from_=a) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, b.address, [0], [100], bytearray(b"")), - ERC1155Mock.TransferSingle(a.address, a.address, b.address, 0, 100), - ERC1155Mock.AfterTokenTransfer(a.address, b.address, [0], [100], bytearray(b"")), - ] - - tx = erc1155.safeTransferFrom(b, b, 0, 100, b"\x33", from_=b) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(b.address, b.address, [0], [100], bytearray(b"\x33")), - ERC1155Mock.TransferSingle(b.address, b.address, b.address, 0, 100), - ERC1155Mock.AfterTokenTransfer(b.address, b.address, [0], [100], bytearray(b"\x33")), - ] - - erc1155.setApprovalForAll(a, True, from_=b) - tx = erc1155.safeTransferFrom(b, a, 0, 100, b"", from_=a) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(b.address, a.address, [0], [100], bytearray(b"")), - ERC1155Mock.TransferSingle(a.address, b.address, a.address, 0, 100), - ERC1155Mock.AfterTokenTransfer(b.address, a.address, [0], [100], bytearray(b"")), - ] - erc1155.setApprovalForAll(a, False, from_=b) - - erc1155.setApprovalForAll(b, True, from_=a) - tx = erc1155.safeBatchTransferFrom(a, b, [0, 0, 0], [35, 30, 35], b"", from_=b) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, b.address, [0, 0, 0], [35, 30, 35], bytearray(b"")), - ERC1155Mock.TransferBatch(b.address, a.address, b.address, [0, 0, 0], [35, 30, 35]), - ERC1155Mock.AfterTokenTransfer(a.address, b.address, [0, 0, 0], [35, 30, 35], bytearray(b"")), - ] - erc1155.setApprovalForAll(b, False, from_=a) - - erc1155.setApprovalForAll(a, True, from_=b) - tx = erc1155.burn(b, 0, 100, from_=a) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(b.address, Address.ZERO, [0], [100], bytearray(b"")), - ERC1155Mock.TransferSingle(a.address, b.address, Address.ZERO, 0, 100), - ERC1155Mock.AfterTokenTransfer(b.address, Address.ZERO, [0], [100], bytearray(b"")), - ] - - assert erc1155.isApprovedForAll(a, b) == False - tx = erc1155.setApprovalForAll(b, False, from_=a) - assert tx.events == [ERC1155Mock.ApprovalForAll(a.address, b.address, False)] - assert erc1155.isApprovedForAll(a, b) == False - - tx = erc1155.setApprovalForAll(b, True, from_=a) - assert tx.events == [ERC1155Mock.ApprovalForAll(a.address, b.address, True)] - assert erc1155.isApprovedForAll(a, b) == True - - tx = erc1155.setApprovalForAll(b, True, from_=a) - assert tx.events == [ERC1155Mock.ApprovalForAll(a.address, b.address, True)] - assert erc1155.isApprovedForAll(a, b) == True - - tx = erc1155.setApprovalForAll(b, False, from_=a) - assert tx.events == [ERC1155Mock.ApprovalForAll(a.address, b.address, False)] - assert erc1155.isApprovedForAll(a, b) == False - - c = default_chain.accounts[2] - - tx = erc1155.setApprovalForAllUnchecked(a, b, True, from_=c) - assert tx.events == [ERC1155Mock.ApprovalForAll(a.address, b.address, True)] - tx = erc1155.setApprovalForAllUnchecked(a, b, True, from_=c) - assert tx.events == [ERC1155Mock.ApprovalForAll(a.address, b.address, True)] - tx = erc1155.setApprovalForAllUnchecked(a, b, False, from_=c) - assert tx.events == [ERC1155Mock.ApprovalForAll(a.address, b.address, False)] - - erc1155.batchMint(a, [0, 1, 2], [100, 200, 300], b"", from_=a) - tx = erc1155.burnUnchecked(Address.ZERO, a, 2, 100, from_=c) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, Address.ZERO, [2], [100], bytearray(b"")), - ERC1155Mock.TransferSingle(c.address, a.address, Address.ZERO, 2, 100), - ERC1155Mock.AfterTokenTransfer(a.address, Address.ZERO, [2], [100], bytearray(b"")), - ] - - tx = erc1155.batchBurnUnchecked(Address.ZERO, a, [0, 1, 2], [100, 100, 100], from_=c) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, Address.ZERO, [0, 1, 2], [100, 100, 100], bytearray(b"")), - ERC1155Mock.TransferBatch(c.address, a.address, Address.ZERO, [0, 1, 2], [100, 100, 100]), - ERC1155Mock.AfterTokenTransfer(a.address, Address.ZERO, [0, 1, 2], [100, 100, 100], bytearray(b"")), - ] - - tx = erc1155.safeTransferUnchecked(Address.ZERO, a, b, 1, 50, b"\x11", from_=c) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, b.address, [1], [50], bytearray(b"\x11")), - ERC1155Mock.TransferSingle(c.address, a.address, b.address, 1, 50), - ERC1155Mock.AfterTokenTransfer(a.address, b.address, [1], [50], bytearray(b"\x11")), - ] - - tx = erc1155.safeBatchTransferUnchecked(Address.ZERO, a, b, [0, 1, 2], [0, 50, 0], b"\x22", from_=c) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(a.address, b.address, [0, 1, 2], [0, 50, 0], bytearray(b"\x22")), - ERC1155Mock.TransferBatch(c.address, a.address, b.address, [0, 1, 2], [0, 50, 0]), - ERC1155Mock.AfterTokenTransfer(a.address, b.address, [0, 1, 2], [0, 50, 0], bytearray(b"\x22")), - ] - - -@default_chain.connect() -def test_erc1155_mint_burn(): - a = default_chain.accounts[0] - b = default_chain.accounts[1] - - erc1155 = ERC1155Mock.deploy(False, from_=a) - - assert erc1155.balanceOfBatch([], []) == [] - - erc1155.mint(b, 0, 100, b"", from_=a) - assert erc1155.balanceOf(b, 0) == 100 - - erc1155.burn(b, 0, 50, from_=b) - assert erc1155.balanceOf(b, 0) == 50 - - # b is not owner nor approved - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.NotOwnerNorApproved.selector)): - erc1155.burn(b, 0, 50, from_=a) - - # insufficient balance - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.burn(b, 0, 51, from_=b) - - erc1155.burn(b, 0, 50, from_=b) - assert erc1155.balanceOf(b, 0) == 0 - - # mint to zero address - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.mint(Address.ZERO, 0, 100, b"", from_=a) - - # balance overflow - erc1155.mint(b, 0, 2 ** 256 - 1, b"", from_=a) - assert erc1155.balanceOf(b, 0) == 2 ** 256 - 1 - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.mint(b, 0, 1, b"", from_=a) - erc1155.burn(b, 0, 2 ** 256 - 1, from_=b) - - # ids and amounts length mismatch - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.ArrayLengthsMismatch.selector)): - erc1155.batchMint(b, [0, 1], [100], b"", from_=a) - - # ids and amounts length mismatch - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.ArrayLengthsMismatch.selector)): - erc1155.batchBurn(b, [0, 1], [100], from_=a) - - # mint to zero address - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.batchMint(Address.ZERO, [0, 1], [100, 200], b"", from_=a) - - # balance overflow - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.batchMint(b, [0, 1, 0], [2 ** 256 - 1, 1, 1], b"", from_=a) - - # not owner nor approved - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.NotOwnerNorApproved.selector)): - erc1155.batchBurn(b, [0, 1, 0], [1, 1, 1], from_=a) - - # insufficient balance - erc1155.mint(b, 0, 100, b"", from_=a) - erc1155.mint(b, 1, 1, b"", from_=a) - assert erc1155.balanceOf(b, 0) == 100 - assert erc1155.balanceOf(b, 1) == 1 - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.batchBurn(b, [0, 1, 0], [70, 1, 31], from_=b) - erc1155.burn(b, 0, 100, from_=b) - erc1155.burn(b, 1, 1, from_=b) - assert erc1155.balanceOf(b, 0) == 0 - assert erc1155.balanceOf(b, 1) == 0 - - -@default_chain.connect() -def test_erc1155_transfers(): - a = default_chain.accounts[0] - b = default_chain.accounts[1] - - erc1155 = ERC1155Mock.deploy(False, from_=a) - - erc1155.mint(a, 0, 100, b"", from_=a) - erc1155.mint(a, 1, 100, b"", from_=a) - assert erc1155.balanceOf(a, 0) == 100 - assert erc1155.balanceOf(a, 1) == 100 - - erc1155.safeTransferFrom(a, b, 0, 50, b"", from_=a) - assert erc1155.balanceOf(a, 0) == 50 - assert erc1155.balanceOf(a, 1) == 100 - assert erc1155.balanceOf(b, 0) == 50 - assert erc1155.balanceOfBatch([a, a, b, a], [0, 1, 0, 2]) == [50, 100, 50, 0] - - erc1155.safeBatchTransferFrom(a, b, [], [], b"", from_=a) - assert erc1155.balanceOfBatch([a, a, b, a], [0, 1, 0, 2]) == [50, 100, 50, 0] - - # owners and ids length mismatch - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.ArrayLengthsMismatch.selector)): - assert erc1155.balanceOfBatch([a, a, b], [0, 1, 0, 2]) == [50, 100, 50, 0] - - # not owner nor approved - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.NotOwnerNorApproved.selector)): - erc1155.safeTransferFrom(a, b, 0, 50, b"", from_=b) - - # insufficient balance - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.safeTransferFrom(a, b, 0, 51, b"", from_=a) - - # transfer to zero address - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.safeTransferFrom(a, Address.ZERO, 0, 50, b"", from_=a) - - # transfer to self - erc1155.safeTransferFrom(a, a, 0, 50, b"", from_=a) - assert erc1155.balanceOf(a, 0) == 50 - - # balance overflow - erc1155.mint(a, 0, 2 ** 256 - 1 - 50, b"", from_=a) - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.safeTransferFrom(a, b, 0, 2 ** 256 - 1 - 49, b"", from_=a) - - # transfer to non-erc1155 receiver - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToNonERC1155ReceiverImplementer.selector)): - erc1155.safeTransferFrom(a, erc1155, 0, 50, b"", from_=a) - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToNonERC1155ReceiverImplementer.selector)): - erc1155.safeBatchTransferFrom(a, erc1155, [0], [50], b"", from_=a) - - # clear balances - c = default_chain.accounts[2] - assert erc1155.isApprovedForAll(a, c) is False - erc1155.batchBurnUnchecked(Address.ZERO, a, [0, 1], [2 ** 256 - 1, 100], from_=c) - erc1155.burnUnchecked(Address.ZERO, b, 0, 50, from_=c) - - erc1155.batchMint(a, [0, 1], [100, 100], b"", from_=a) - erc1155.safeBatchTransferFrom(a, b, [0, 1], [70, 30], b"", from_=a) - assert erc1155.balanceOfBatch([a, a, b, b], [0, 1, 0, 1]) == [30, 70, 70, 30] - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.ArrayLengthsMismatch.selector)): - erc1155.safeBatchTransferFrom(a, b, [0, 1], [30], b"", from_=a) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.safeBatchTransferFrom(a, Address.ZERO, [0, 1], [30, 30], b"", from_=a) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.NotOwnerNorApproved.selector)): - erc1155.safeBatchTransferFrom(a, b, [0, 1], [30, 30], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.safeBatchTransferFrom(a, b, [0, 1], [31, 30], b"", from_=a) - - erc1155.mint(a, 0, 2 ** 256 - 1 - 30, b"", from_=a) - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.safeBatchTransferFrom(a, b, [0, 1], [2 ** 256 - 1 - 29, 30], b"", from_=a) - - -@default_chain.connect() -def test_erc1155_contract_receiver(): - a = default_chain.accounts[0] - - erc1155 = ERC1155Mock.deploy(False, from_=a) - receiver = ERC1155ReceiverMock.deploy(from_=a) - - erc1155.mint(receiver, 0, 100, b"\x00\x11\x22\x33", from_=a) - assert erc1155.balanceOf(receiver, 0) == 100 - - with must_revert(Error("ERC1155ReceiverMock: invalid payload received")): - erc1155.mint(receiver, 0, 100, b"", from_=a) - - erc1155.mint(a, 1, 100, b"", from_=a) - erc1155.safeTransferFrom(a, receiver, 1, 50, b"\x00\x11\x22\x33", from_=a) - assert erc1155.balanceOfBatch([receiver, receiver], [0, 1]) == [100, 50] - - with must_revert(Error("ERC1155ReceiverMock: invalid payload received")): - erc1155.safeTransferFrom(a, receiver, 1, 50, b"\x00\x11\x22", from_=a) - - erc1155.safeBatchTransferFrom(a, receiver, [0, 1], [0, 50], b"\x00\x11\x22\x33", from_=a) - assert erc1155.balanceOfBatch([receiver, receiver], [0, 1]) == [100, 100] - - with must_revert(Error("ERC1155ReceiverMock: invalid payload received")): - erc1155.safeBatchTransferFrom(a, receiver, [0, 1], [0, 0], b"\x11\x22\x33", from_=a) - - erc1155.batchMint(receiver, [0, 1], [100, 100], b"\x00\x11\x22\x33", from_=a) - assert erc1155.balanceOfBatch([receiver, receiver], [0, 1]) == [200, 200] - - with must_revert(Error("ERC1155ReceiverMock: invalid payload received")): - erc1155.batchMint(receiver, [0, 1], [100, 100], b"", from_=a) - - -@default_chain.connect() -def test_erc1155_unchecked(): - a = default_chain.accounts[0] - b = default_chain.accounts[1] - c = default_chain.accounts[2] - default_chain.set_default_accounts(c) - - erc1155 = ERC1155Mock.deploy(False, from_=a) - - erc1155.mint(a, 0, 100, b"", from_=c) - assert erc1155.balanceOf(a, 0) == 100 - - erc1155.safeBatchTransferUnchecked(Address.ZERO, a, b, [0], [100], b"", from_=c) - assert erc1155.balanceOf(a, 0) == 0 - assert erc1155.balanceOf(b, 0) == 100 - - erc1155.setApprovalForAllUnchecked(b, a, True, from_=c) - erc1155.safeTransferUnchecked(a, b, a, 0, 100, b"", from_=c) - assert erc1155.balanceOf(a, 0) == 100 - assert erc1155.balanceOf(b, 0) == 0 - - erc1155.setApprovalForAllUnchecked(a, b, True, from_=c) - erc1155.burnUnchecked(b, a, 0, 100, from_=c) - assert erc1155.balanceOf(a, 0) == 0 - assert erc1155.balanceOf(b, 0) == 0 - - erc1155.batchMint(a, [0, 1], [100, 100], b"", from_=c) - erc1155.batchBurnUnchecked(b, a, [0, 1], [100, 100], from_=c) - assert erc1155.balanceOf(a, 0) == 0 - assert erc1155.balanceOf(a, 1) == 0 - - erc1155.setApprovalForAllUnchecked(a, b, False, from_=c) - erc1155.setApprovalForAllUnchecked(b, a, False, from_=c) - erc1155.mint(a, 0, 100, b"", from_=c) - assert erc1155.balanceOf(a, 0) == 100 - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.NotOwnerNorApproved.selector)): - erc1155.safeTransferUnchecked(b, a, b, 0, 100, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.NotOwnerNorApproved.selector)): - erc1155.safeBatchTransferUnchecked(b, a, b, [0], [100], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.safeTransferUnchecked(Address.ZERO, a, Address.ZERO, 0, 100, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.safeTransferUnchecked(a, a, Address.ZERO, 0, 100, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.safeBatchTransferUnchecked(Address.ZERO, a, Address.ZERO, [0], [100], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToZeroAddress.selector)): - erc1155.safeBatchTransferUnchecked(a, a, Address.ZERO, [0], [100], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.safeTransferUnchecked(Address.ZERO, a, b, 0, 101, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.safeTransferUnchecked(a, a, b, 0, 101, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.safeBatchTransferUnchecked(Address.ZERO, a, b, [0], [101], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.InsufficientBalance.selector)): - erc1155.safeBatchTransferUnchecked(a, a, b, [0], [101], b"", from_=c) - - erc1155.mint(b, 0, 2 ** 256 - 10, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.safeTransferUnchecked(Address.ZERO, a, b, 0, 100, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.safeTransferUnchecked(a, a, b, 0, 100, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.safeBatchTransferUnchecked(Address.ZERO, a, b, [0, 0], [9, 21], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.AccountBalanceOverflow.selector)): - erc1155.safeBatchTransferUnchecked(a, a, b, [0, 0], [9, 21], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.ArrayLengthsMismatch.selector)): - erc1155.safeBatchTransferUnchecked(Address.ZERO, a, b, [0], [100, 100], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToNonERC1155ReceiverImplementer.selector)): - erc1155.safeTransferUnchecked(Address.ZERO, a, erc1155, 0, 100, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToNonERC1155ReceiverImplementer.selector)): - erc1155.safeTransferUnchecked(a, a, erc1155, 0, 100, b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToNonERC1155ReceiverImplementer.selector)): - erc1155.safeBatchTransferUnchecked(Address.ZERO, a, erc1155, [0], [100], b"", from_=c) - - with must_revert(UnknownTransactionRevertedError(ERC1155Mock.TransferToNonERC1155ReceiverImplementer.selector)): - erc1155.safeBatchTransferUnchecked(a, a, erc1155, [0], [100], b"", from_=c) diff --git a/grouperBot/lib/solady/ext/wake/test_erc1155_fuzz.py b/grouperBot/lib/solady/ext/wake/test_erc1155_fuzz.py deleted file mode 100644 index e2c2bbd..0000000 --- a/grouperBot/lib/solady/ext/wake/test_erc1155_fuzz.py +++ /dev/null @@ -1,536 +0,0 @@ -import logging -from collections import defaultdict -import random -from typing import DefaultDict, Set - -from wake.testing import * -from wake.testing.fuzzing import * -from pytypes.tests.ERC1155Mock import ERC1155Mock - - -logger = logging.getLogger(__name__) -#logger.setLevel(logging.DEBUG) - - -class ERC1155FuzzTest(FuzzTest): - _erc1155: ERC1155Mock - _balances: DefaultDict[Account, DefaultDict[uint256, uint256]] - _approvals: DefaultDict[Account, Set[Account]] - _token_ids: List[uint256] - - def pre_sequence(self) -> None: - self._erc1155 = ERC1155Mock.deploy(True) - self._balances = defaultdict(lambda: defaultdict(lambda: 0)) - self._approvals = defaultdict(set) - self._token_ids = [random_int(0, 2 ** 256 - 1, edge_values_prob=0.25) for _ in range(10)] - - @flow() - def flow_mint(self, payload: bytearray) -> None: - a = random_account() - id = random.choice(self._token_ids) - amount = random_int(0, 2 ** 256 - 1, edge_values_prob=0.05) - - try: - tx = self._erc1155.mint(a, id, amount, payload) - assert self._balances[a][id] + amount < 2 ** 256 - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(Address.ZERO, a.address, [id], [amount], payload), - ERC1155Mock.TransferSingle(tx.from_.address, Address.ZERO, a.address, id, amount), - ERC1155Mock.AfterTokenTransfer(Address.ZERO, a.address, [id], [amount], payload), - ] - self._balances[a][id] += amount - - logger.debug(f"Minted {amount} of {id} to {a}") - except UnknownTransactionRevertedError as e: - assert e.data == ERC1155Mock.AccountBalanceOverflow.selector - assert self._balances[a][id] + amount >= 2 ** 256 - - logger.debug(f"Failed to mint {amount} of {id} to {a}") - - @flow() - def flow_batch_mint(self, payload: bytearray) -> None: - a = random_account() - ids = [random.choice(self._token_ids) for _ in range(random_int(0, 10, edge_values_prob=0.05))] - amounts = [random_int(0, 2 ** 256 - 1, edge_values_prob=0.05) for _ in range(len(ids))] - - try: - tx = self._erc1155.batchMint(a, ids, amounts, payload) - for id, amount in zip(ids, amounts): - assert self._balances[a][id] + amount < 2 ** 256 - self._balances[a][id] += amount - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(Address.ZERO, a.address, ids, amounts, payload), - ERC1155Mock.TransferBatch(tx.from_.address, Address.ZERO, a.address, ids, amounts), - ERC1155Mock.AfterTokenTransfer(Address.ZERO, a.address, ids, amounts, payload), - ] - - logger.debug(f"Minted {amounts} of {ids} to {a}") - except UnknownTransactionRevertedError as e: - assert e.data == ERC1155Mock.AccountBalanceOverflow.selector - amounts_by_ids = defaultdict(int) - for id, amount in zip(ids, amounts): - amounts_by_ids[id] += amount - assert any(self._balances[a][id] + amount >= 2 ** 256 for id, amount in amounts_by_ids.items()) - - logger.debug(f"Failed to mint {amounts} of {ids} to {a}") - - @flow() - def flow_burn(self) -> None: - owner = random_account() - - if random.random() < 0.8 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - else: - id = random.choice(self._token_ids) - - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), min_prob=0.05, max_prob=0.01) - - operator = random.choices( - default_chain.accounts, - [0.5 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] - )[0] - - try: - tx = self._erc1155.burn(owner, id, amount, from_=operator) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, Address.ZERO, [id], [amount], bytearray()), - ERC1155Mock.TransferSingle(operator.address, owner.address, Address.ZERO, id, amount), - ERC1155Mock.AfterTokenTransfer(owner.address, Address.ZERO, [id], [amount], bytearray()), - ] - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - - assert operator == owner or operator in self._approvals[owner] - - logger.debug(f"Burned {amount} of {id} from {owner}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - assert self._balances[owner][id] - amount < 0 - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to burn {amount} of {id} from {owner}") - - @flow() - def flow_burn_batch(self) -> None: - owner = random_account() - - ids = [] - amounts = [] - for _ in range(random_int(0, 10, edge_values_prob=0.05)): - if random.random() < 0.98 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - ids.append(id) - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), edge_values_prob=0.05) - amounts.append(amount) - else: - id = random.choice(self._token_ids) - ids.append(id) - amount = random_int(0, 2 ** 256 - 1, edge_values_prob=0.05) - amounts.append(amount) - - operator = random.choices( - default_chain.accounts, - [0.5 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] - )[0] - - try: - tx = self._erc1155.batchBurn(owner, ids, amounts, from_=operator) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, Address.ZERO, ids, amounts, bytearray()), - ERC1155Mock.TransferBatch(operator.address, owner.address, Address.ZERO, ids, amounts), - ERC1155Mock.AfterTokenTransfer(owner.address, Address.ZERO, ids, amounts, bytearray()), - ] - for id, amount in zip(ids, amounts): - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - - assert operator == owner or operator in self._approvals[owner] - - logger.debug(f"Burned {amounts} of {ids} from {owner}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - amounts_by_ids = defaultdict(int) - for id, amount in zip(ids, amounts): - amounts_by_ids[id] += amount - assert any(self._balances[owner][id] - amount < 0 for id, amount in amounts_by_ids.items()) - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to burn {amounts} of {ids} from {owner}") - - @flow() - def flow_burn_unchecked(self) -> None: - owner = random_account() - - if random.random() < 0.8 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - else: - id = random.choice(self._token_ids) - - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), min_prob=0.05, max_prob=0.01) - - operator = random.choices( - default_chain.accounts + (Account(0), ), - [0.25 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] + [0.25] - )[0] - executor = random_account() - - try: - tx = self._erc1155.burnUnchecked(operator, owner, id, amount, from_=executor) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, Address.ZERO, [id], [amount], bytearray()), - ERC1155Mock.TransferSingle(executor.address, owner.address, Address.ZERO, id, amount), - ERC1155Mock.AfterTokenTransfer(owner.address, Address.ZERO, [id], [amount], bytearray()), - ] - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - - assert operator == owner or operator == Account(0) or operator in self._approvals[owner] - - logger.debug(f"Burned {amount} of {id} from {owner}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - assert self._balances[owner][id] - amount < 0 - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator != Account(0) and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to burn {amount} of {id} from {owner}") - - @flow() - def flow_burn_batch_unchecked(self): - owner = random_account() - - ids = [] - amounts = [] - for _ in range(random_int(0, 10, edge_values_prob=0.05)): - if random.random() < 0.98 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - ids.append(id) - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), edge_values_prob=0.05) - amounts.append(amount) - else: - id = random.choice(self._token_ids) - ids.append(id) - amount = random_int(0, 2 ** 256 - 1, edge_values_prob=0.05) - amounts.append(amount) - - operator = random.choices( - default_chain.accounts + (Account(0), ), - [0.25 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] + [0.25] - )[0] - executor = random_account() - - try: - tx = self._erc1155.batchBurnUnchecked(operator, owner, ids, amounts, from_=executor) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, Address.ZERO, ids, amounts, bytearray()), - ERC1155Mock.TransferBatch(executor.address, owner.address, Address.ZERO, ids, amounts), - ERC1155Mock.AfterTokenTransfer(owner.address, Address.ZERO, ids, amounts, bytearray()), - ] - for id, amount in zip(ids, amounts): - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - - assert operator == owner or operator == Account(0) or operator in self._approvals[owner] - - logger.debug(f"Burned {amounts} of {ids} from {owner}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - amounts_by_ids = defaultdict(int) - for id, amount in zip(ids, amounts): - amounts_by_ids[id] += amount - assert any(self._balances[owner][id] - amount < 0 for id, amount in amounts_by_ids.items()) - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator != Account(0) and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to burn {amounts} of {ids} from {owner}") - - @flow() - def flow_change_approval(self) -> None: - a = random_account() - operator = random_account() - approval = operator in self._approvals[a] - - tx = self._erc1155.setApprovalForAll(operator, not approval, from_=a) - assert tx.events == [ - ERC1155Mock.ApprovalForAll(a.address, operator.address, not approval), - ] - - if approval: - self._approvals[a].remove(operator) - else: - self._approvals[a].add(operator) - - logger.debug(f"Changed approval of {operator} for {a} to {not approval}") - - @flow() - def flow_change_approval_unchecked(self) -> None: - owner = random_account() - operator = random_account() - executor = random_account() - approval = operator in self._approvals[owner] - - tx = self._erc1155.setApprovalForAllUnchecked(owner, operator, not approval, from_=executor) - assert tx.events == [ - ERC1155Mock.ApprovalForAll(owner.address, operator.address, not approval), - ] - - if approval: - self._approvals[owner].remove(operator) - else: - self._approvals[owner].add(operator) - - logger.debug(f"Changed approval of {operator} for {owner} to {not approval}") - - @flow() - def flow_safe_transfer(self, payload: bytearray): - owner = random_account() - recipient = random_account() - - if random.random() < 0.8 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - else: - id = random.choice(self._token_ids) - - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), min_prob=0.05, max_prob=0.01) - - operator = random.choices( - default_chain.accounts, - [0.5 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] - )[0] - - try: - tx = self._erc1155.safeTransferFrom(owner, recipient, id, amount, payload, from_=operator) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, recipient.address, [id], [amount], payload), - ERC1155Mock.TransferSingle(operator.address, owner.address, recipient.address, id, amount), - ERC1155Mock.AfterTokenTransfer(owner.address, recipient.address, [id], [amount], payload), - ] - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - assert self._balances[recipient][id] + amount <= 2 ** 256 - 1 - self._balances[recipient][id] += amount - - assert operator == owner or operator in self._approvals[owner] - - logger.debug(f"Transferred {amount} of {id} from {owner} to {recipient}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - assert self._balances[owner][id] - amount < 0 - elif e.data == ERC1155Mock.AccountBalanceOverflow.selector: - assert self._balances[recipient][id] + amount > 2 ** 256 - 1 - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to transfer {amount} of {id} from {owner} to {recipient}") - - @flow() - def flow_safe_batch_transfer(self, payload: bytearray) -> None: - owner = random_account() - ids = [] - amounts = [] - for _ in range(random_int(0, 10, edge_values_prob=0.05)): - if random.random() < 0.98 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - ids.append(id) - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), edge_values_prob=0.05) - amounts.append(amount) - else: - id = random.choice(self._token_ids) - ids.append(id) - amount = random_int(0, 2 ** 256 - 1, edge_values_prob=0.05) - amounts.append(amount) - - operator = random.choices( - default_chain.accounts, - [0.5 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] - )[0] - - try: - tx = self._erc1155.safeBatchTransferFrom(owner, owner, ids, amounts, payload, from_=operator) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, owner.address, ids, amounts, payload), - ERC1155Mock.TransferBatch(operator.address, owner.address, owner.address, ids, amounts), - ERC1155Mock.AfterTokenTransfer(owner.address, owner.address, ids, amounts, payload), - ] - for id, amount in zip(ids, amounts): - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - assert self._balances[owner][id] + amount <= 2 ** 256 - 1 - self._balances[owner][id] += amount - - assert operator == owner or operator in self._approvals[owner] - - logger.debug(f"Transferred {amounts} of {ids} from {owner} to {owner}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - amounts_by_ids = defaultdict(int) - for id, amount in zip(ids, amounts): - amounts_by_ids[id] += amount - assert any(self._balances[owner][id] - amount < 0 for id, amount in amounts_by_ids.items()) - elif e.data == ERC1155Mock.AccountBalanceOverflow.selector: - amounts_by_ids = defaultdict(int) - for id, amount in zip(ids, amounts): - amounts_by_ids[id] += amount - assert any(self._balances[owner][id] + amount > 2 ** 256 - 1 for id, amount in amounts_by_ids.items()) - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to transfer {amounts} of {ids} from {owner} to {owner}") - - @flow() - def flow_safe_transfer_unchecked(self, payload: bytearray) -> None: - owner = random_account() - recipient = random_account() - - if random.random() < 0.8 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - else: - id = random.choice(self._token_ids) - - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), min_prob=0.05, max_prob=0.01) - - operator = random.choices( - default_chain.accounts + (Account(0), ), - [0.25 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] + [0.25] - )[0] - executor = random_account() - - try: - tx = self._erc1155.safeTransferUnchecked(operator, owner, recipient, id, amount, payload, from_=executor) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, recipient.address, [id], [amount], payload), - ERC1155Mock.TransferSingle(executor.address, owner.address, recipient.address, id, amount), - ERC1155Mock.AfterTokenTransfer(owner.address, recipient.address, [id], [amount], payload), - ] - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - assert self._balances[recipient][id] + amount <= 2 ** 256 - 1 - self._balances[recipient][id] += amount - - assert operator == owner or operator == Account(0) or operator in self._approvals[owner] - - logger.debug(f"Transferred {amount} of {id} from {owner} to {recipient}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - assert self._balances[owner][id] - amount < 0 - elif e.data == ERC1155Mock.AccountBalanceOverflow.selector: - assert self._balances[recipient][id] + amount > 2 ** 256 - 1 - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator != Account(0) and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to transfer {amount} of {id} from {owner} to {recipient}") - - @flow() - def flow_safe_batch_transfer_unchecked(self, payload: bytearray) -> None: - owner = random_account() - ids = [] - amounts = [] - for _ in range(random_int(0, 10, edge_values_prob=0.05)): - if random.random() < 0.98 and sum(self._balances[owner].values()) > 0: - id = random.choice([k for k in self._balances[owner].keys() if self._balances[owner][k] > 0]) - ids.append(id) - if self._balances[owner][id] == 0: - amount = random.choice([0, 1]) - else: - amount = random_int(0, min(self._balances[owner][id] + 1, 2 ** 256 - 1), edge_values_prob=0.05) - amounts.append(amount) - else: - id = random.choice(self._token_ids) - ids.append(id) - amount = random_int(0, 2 ** 256 - 1, edge_values_prob=0.05) - amounts.append(amount) - - operator = random.choices( - default_chain.accounts + (Account(0), ), - [0.25 if a == owner else 0.5 / (len(default_chain.accounts) - 1) for a in default_chain.accounts] + [0.25] - )[0] - executor = random_account() - - try: - tx = self._erc1155.safeBatchTransferUnchecked(operator, owner, owner, ids, amounts, payload, from_=executor) - assert tx.events == [ - ERC1155Mock.BeforeTokenTransfer(owner.address, owner.address, ids, amounts, payload), - ERC1155Mock.TransferBatch(executor.address, owner.address, owner.address, ids, amounts), - ERC1155Mock.AfterTokenTransfer(owner.address, owner.address, ids, amounts, payload), - ] - for id, amount in zip(ids, amounts): - assert self._balances[owner][id] - amount >= 0 - self._balances[owner][id] -= amount - assert self._balances[owner][id] + amount <= 2 ** 256 - 1 - self._balances[owner][id] += amount - - assert operator == owner or operator == Account(0) or operator in self._approvals[owner] - - logger.debug(f"Transferred {amounts} of {ids} from {owner} to {owner}") - except UnknownTransactionRevertedError as e: - if e.data == ERC1155Mock.InsufficientBalance.selector: - amounts_by_ids = defaultdict(int) - for id, amount in zip(ids, amounts): - amounts_by_ids[id] += amount - assert any(self._balances[owner][id] - amount < 0 for id, amount in amounts_by_ids.items()) - elif e.data == ERC1155Mock.AccountBalanceOverflow.selector: - amounts_by_ids = defaultdict(int) - for id, amount in zip(ids, amounts): - amounts_by_ids[id] += amount - assert any(self._balances[owner][id] + amount > 2 ** 256 - 1 for id, amount in amounts_by_ids.items()) - elif e.data == ERC1155Mock.NotOwnerNorApproved.selector: - assert operator != owner and operator != Account(0) and operator not in self._approvals[owner] - else: - raise - - logger.debug(f"Failed to transfer {amounts} of {ids} from {owner} to {owner}") - - @invariant(period=20) - def invariant_balances(self) -> None: - for a, balances in self._balances.items(): - assert self._erc1155.balanceOfBatch([a] * len(balances), list(balances.keys())) == list(balances.values()) - for id, balance in balances.items(): - assert self._erc1155.balanceOf(a, id) == balance - - @invariant(period=20) - def invariant_approvals(self) -> None: - for a in default_chain.accounts: - for b in default_chain.accounts: - assert self._erc1155.isApprovedForAll(a, b) == (b in self._approvals[a]) - - -@default_chain.connect(accounts=20) -def test_erc1155_fuzz(): - ERC1155FuzzTest().run(1, 100) diff --git a/grouperBot/lib/solady/ext/wake/test_erc20.py b/grouperBot/lib/solady/ext/wake/test_erc20.py deleted file mode 100644 index 6af7f82..0000000 --- a/grouperBot/lib/solady/ext/wake/test_erc20.py +++ /dev/null @@ -1,226 +0,0 @@ -from wake.testing import * - -from pytypes.tests.ERC20Mock import ERC20Mock -from pytypes.tests.NoETHMock import NoETHMock -from pytypes.tests.weird.Approval import ApprovalRaceToken -from pytypes.tests.weird.ApprovalToZero import ApprovalToZeroToken -from pytypes.tests.weird.BlockList import BlockableToken -from pytypes.tests.weird.HighDecimals import HighDecimalToken -from pytypes.tests.weird.Bytes32Metadata import ERC20 as Bytes32MetadataToken -from pytypes.tests.weird.MissingReturns import MissingReturnToken -from pytypes.tests.weird.NoRevert import NoRevertToken -from pytypes.tests.weird.Pausable import PausableToken -from pytypes.tests.weird.Proxied import ProxiedToken, TokenProxy -from pytypes.tests.weird.Reentrant import ReentrantToken -from pytypes.tests.weird.ReturnsFalse import ReturnsFalseToken -from pytypes.tests.weird.TransferFee import TransferFeeToken -from pytypes.tests.weird.Uint96 import Uint96ERC20 -from pytypes.tests.weird.Upgradable import Proxy as UpgradableToken - -from pytypes.src.utils.SafeTransferLib import SafeTransferLib - - -@default_chain.connect() -def test_erc20(): - milady = default_chain.accounts[0] - accountoor = default_chain.accounts[1] - default_chain.set_default_accounts(milady) - - tokenoor = ERC20Mock.deploy("Mockoor", "MOCK", 18) - - tokenoor.mint(milady, 2**30) - assert tokenoor.balanceOf(milady) == 2**30 - - tokenoor.approve(accountoor, 2**30) - assert tokenoor.allowance(milady, accountoor) == 2**30 - - tokenoor.transferFrom(milady, accountoor, 2**30, from_=accountoor) - assert tokenoor.allowance(milady, accountoor) == 0 - - assert tokenoor.balanceOf(milady) == 0 - assert tokenoor.balanceOf(accountoor) == 2**30 - -@default_chain.connect() -def test_safe_transfer_eth(): - milady = default_chain.accounts[0] - accountoor = default_chain.accounts[1] - default_chain.set_default_accounts(milady) - - SafeTransferLib.deploy() - - tokenoor = ERC20Mock.deploy("Mockoor", "MOCK", 18) - tokenoor.balance = 5000 - accountoor.balance = 0 - - # should change balance - tokenoor.safeTransferETH(accountoor, 1000) - assert tokenoor.balance == 4000 - assert accountoor.balance == 1000 - - noeth = NoETHMock.deploy() - - # should revert - with must_revert(): - tokenoor.safeTransferETH(noeth, 1000) - - # should change balance - tokenoor.forceSafeTransferETH(noeth, 1000) - assert tokenoor.balance == 3000 - assert noeth.balance == 1000 - - # should force on bad gas stipend - tokenoor.forceSafeTransferETHGas(accountoor, 1000, 0) - assert tokenoor.balance == 2000 - assert accountoor.balance == 2000 - - # should change balance - tokenoor.trySafeTransferETH(accountoor, 1000, 0) - assert tokenoor.balance == 1000 - assert accountoor.balance == 3000 - - # should not revert - tokenoor.trySafeTransferETH(noeth, 1000, 0) - assert tokenoor.balance == 1000 - assert noeth.balance == 1000 - -@default_chain.connect() -def test_safe_transfer(): - milady = default_chain.accounts[0] - default_chain.set_default_accounts(milady) - - SafeTransferLib.deploy() - - tokenoor = ERC20Mock.deploy("Mockoor", "MOCK", 18) - tokenoor.mint(tokenoor, 2**30) - - tokenoor.safeTransfer(tokenoor, milady, 2**30) - assert tokenoor.balanceOf(milady) == 2**30 - assert tokenoor.balanceOf(tokenoor) == 0 - - tokenoor.approve(tokenoor, 2**30) - assert tokenoor.allowance(milady, tokenoor) == 2**30 - tokenoor.safeTransferFrom(tokenoor, milady, tokenoor, 2**30) - assert tokenoor.balanceOf(milady) == 0 - assert tokenoor.balanceOf(tokenoor) == 2**30 - - tokenoor.mint(tokenoor, 2**30) - tokenoor.safeTransferAll(tokenoor, milady) - assert tokenoor.balanceOf(milady) == 2**30 * 2 - assert tokenoor.balanceOf(tokenoor) == 0 - - # test safe balanceOf - assert tokenoor.balanceOfoor(milady, milady) == 0 - assert tokenoor.balanceOfoor(tokenoor, milady) == 2**30 * 2 - -def safe_transfer_weird(weird: Account): - milady = default_chain.accounts[0] - weird = ERC20Mock(weird) - - SafeTransferLib.deploy() - - tokenoor = ERC20Mock.deploy("Mockoor", "MOCK", 18) - - weird.mint(tokenoor, 2**30) - tokenoor.safeTransfer(weird, milady, 2**30) - assert weird.balanceOf(milady) == 2**30 - assert weird.balanceOf(tokenoor) == 0 - - weird.mint(tokenoor, 2**30) - tokenoor.safeTransferAll(weird, milady) - assert weird.balanceOf(milady) == 2**30 * 2 - assert weird.balanceOf(tokenoor) == 0 - - weird.mint(tokenoor, 2**30) - tokenoor.safeTransferFrom(weird, tokenoor, milady, 2**30) - assert weird.balanceOf(milady) == 2**30 * 3 - assert weird.balanceOf(tokenoor) == 0 - - weird.approve(tokenoor, 2**30) - assert weird.allowance(milady, tokenoor) == 2**30 - tokenoor.safeTransferFrom(weird, milady, tokenoor, 2**30) - assert weird.balanceOf(milady) == 2**30 * 2 - assert weird.balanceOf(tokenoor) == 2**30 - - # test safe balanceOf - assert tokenoor.balanceOfoor(milady, milady) == 0 - assert tokenoor.balanceOfoor(weird, milady) == 2**30 * 2 - -@default_chain.connect() -def test_safe_transfer_weird_1(): - weird = ApprovalRaceToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_2(): - weird = ApprovalToZeroToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_3(): - weird = BlockableToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_4(): - weird = HighDecimalToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_5(): - weird = Bytes32MetadataToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_6(): - weird = MissingReturnToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_7(): - weird = NoRevertToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_8(): - weird = PausableToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_9(): - impl = ProxiedToken.deploy(0) - weird_proxy = TokenProxy.deploy(impl) - weird = ProxiedToken(weird_proxy) - weird.setDelegator(weird_proxy, True) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_10(): - weird = ReturnsFalseToken.deploy(0) - with must_revert(): - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_11(): - weird = ReentrantToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_12(): - weird = TransferFeeToken.deploy(0,0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_13(): - weird = Uint96ERC20.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_safe_transfer_weird_14(): - weird = UpgradableToken.deploy(0) - safe_transfer_weird(weird) - -@default_chain.connect() -def test_mint_to_zero_address(): - tokenoor = ERC20Mock.deploy("Mockoor", "MOCK", 18) - tokenoor.mint(Address(0), 2**256-1) - assert tokenoor.balanceOf(Address(0)) == 2**256-1 diff --git a/grouperBot/lib/solady/ext/wake/test_erc721_fuzz.py b/grouperBot/lib/solady/ext/wake/test_erc721_fuzz.py deleted file mode 100644 index 691a027..0000000 --- a/grouperBot/lib/solady/ext/wake/test_erc721_fuzz.py +++ /dev/null @@ -1,364 +0,0 @@ -import random - -from wake.testing.fuzzing import * -from wake.testing import * - -from pytypes.tests.ERC721Mock import ERC721Mock - - -################################################################### -####################### PYTHON ERC721 MODEL ####################### -################################################################### -class ERC721: - # mapping owner -> token id - owners: dict[int, Address] - # mapping owner -> token count - balances: dict[Address, int] - # mapping token id -> approved address - approvals: dict[int, Address] - # mapping operator approval owner -> operator - operators: dict[Address, Address] - def __init__(self): - self.owners = {} - self.balances = {} - self.approvals = {} - self.operators = {} - - def balance_of(self, _owner: Address): - return self.balances[_owner] - - def owner_of(self, _token_id: uint): - return self.owners[_token_id] - - def safe_transfer_from(_from: Address, _to: Address, _token_id: uint, _data: bytes): - return - - def safe_transfer_from(_from: Address, _to: Address, _token_id: uint): - return - - def transfer_from(self,_by: Address, _from: Address, _to: Address, _token_id: uint): - self.transfer(_by, _from, _to, _token_id) - - def transfer(self, _by: Address, _from: Address, _to: Address, _token_id: uint): - if self.owners[_token_id] != _by and self.approvals[_token_id] != _by and self.operators[_from] != _by: - return - self.balances[_from] -= 1 - if _to in self.balances.keys(): - self.balances[_to] += 1 - else: - self.balances[_to] = 1 - - self.owners[_token_id] = _to - if _token_id in self.approvals.keys(): - del self.approvals[_token_id] - - def approve(self, _approved: Address, _token_id: uint): - if _approved == Address(0): - del self.approvals[_token_id] - self.approvals[_token_id] = _approved - - def set_approval_for_all(self, _operator: Address, _owner: Address): - self.operators[_owner] = _operator - - def get_approved(self, _token_id: uint): - return self.approvals[_token_id] - - def is_approve_for_all(self, _owner: Address, _operator: Address): - if self.operators[_owner]: - return True - return False - - def mint(self, _to: Address, _token_id: int): - self.owners[_token_id] = _to - if _to in self.balances.keys(): - self.balances[_to] += 1 - else: - self.balances[_to] = 1 - - def burn(self,_token_id: int): - if _token_id in self.owners.keys(): - self.balances[self.owner_of(_token_id)] -= 1 - del self.owners[_token_id] - if _token_id in self.approvals.keys(): - del self.approvals[_token_id] - - -################################################################### -########################### Fuzz Test ############################# -################################################################### - -class ERC721FuzzTest(FuzzTest): - _erc721: ERC721Mock - _py_erc721: ERC721 - _id_counter: int - _ids: List[int] - # We dont want to use random addresses in flows - # We want more interaction by addresses that are already managing something - _addresses: List[Address] - - def pre_sequence(self) -> None: - self._erc721 = ERC721Mock.deploy() - self._py_erc721 = ERC721() - self._addresses = [] - for i in range(20): - self._addresses.append(random_address()) - - ######################## MINT ######################## - @flow(weight=100) - def mint(self) -> None: - # Random data - to = random.choice(self._addresses) - token_id = random_int(0,(2**256)-1) - # Mint in contract - tx = self._erc721.mint(to, token_id) - # Check events - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(Address(0), to, token_id), - ERC721Mock.Transfer(Address(0), to, token_id), - ERC721Mock.AfterTokenTransfer(Address(0), to, token_id) - ] - # Mint in Py model - self._py_erc721.mint(to, token_id) - - ######################## BURNS ######################## - @flow(weight=50) - def burn_owner(self) -> None: - if self._py_erc721.owners: - # Random token with owner - token_id, owner = random.choice(list(self._py_erc721.owners.items())) - # Burn in contract, msg.sender == owner - tx = self._erc721.burn(token_id, from_=owner) - # Check events - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, Address(0), token_id), - ERC721Mock.Transfer(owner, Address(0), token_id), - ERC721Mock.AfterTokenTransfer(owner, Address(0), token_id) - ] - # Burn in Py model - self._py_erc721.burn(token_id) - - @flow(weight=40) - def burn_approved(self) -> None: - if self._py_erc721.approvals: - # Random token with owner - token_id, approved = random.choice(list(self._py_erc721.approvals.items())) - if token_id in self._py_erc721.owners.keys(): - owner = self._py_erc721.owners[token_id] - # Burn in contract, msg.sender == approved - tx = self._erc721.burn(token_id, from_=approved) - # Check events - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, Address(0), token_id), - ERC721Mock.Transfer(owner, Address(0), token_id), - ERC721Mock.AfterTokenTransfer(owner, Address(0), token_id) - ] - # Burn in Py model - self._py_erc721.burn(token_id) - - @flow(weight=40) - def burn_operator(self) -> None: - if self._py_erc721.operators: - owner, operator = random.choice(list(self._py_erc721.operators.items())) - if owner in self._py_erc721.owners.keys(): - token_id = self._py_erc721.owners[owner] - # Burn in contract, msg.sender == operator - tx = self._erc721.burn(token_id, from_=operator) - # Check events - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, Address(0), token_id), - ERC721Mock.Transfer(owner, Address(0), token_id), - ERC721Mock.AfterTokenTransfer(owner, Address(0), token_id) - ] - # Burn in Py model - self._py_erc721.burn(token_id) - - ######################## TRANSFER ######################## - @flow(weight=80) - def transfer_owner(self) -> None: - # from == by == owner - if self._py_erc721.owners: - token_id, owner = random.choice(list(self._py_erc721.owners.items())) - to = random.choice(self._addresses) - # Transfer in contract, msg.sender == owner - tx = self._erc721.transfer(owner, to, token_id, from_ = owner) - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, to, token_id), - ERC721Mock.Transfer(owner, to, token_id), - ERC721Mock.AfterTokenTransfer(owner, to, token_id) - ] - # Transfer in Py model - self._py_erc721.transfer(owner, owner, to, token_id) - - @flow(weight=60) - def transfer_approved(self) -> None: - # by == approved, from == owner - if self._py_erc721.approvals: - token_id, approved = random.choice(list(self._py_erc721.approvals.items())) - if token_id in self._py_erc721.owners.keys(): - owner = self._py_erc721.owners[token_id] - to = random.choice(self._addresses) - # Transfer in contract, msg.sender == approved - tx = self._erc721.transfer(owner, to, token_id, from_ = approved) - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, to, token_id), - ERC721Mock.Transfer(owner, to, token_id), - ERC721Mock.AfterTokenTransfer(owner, to, token_id) - ] - # Transfer in Py model - self._py_erc721.transfer(approved, owner, to, token_id) - - @flow(weight=60) - def transfer_operator(self) -> None: - # by == operator, from == owner - if self._py_erc721.operators: - owner, operator = random.choice(list(self._py_erc721.operators.items())) - if owner in self._py_erc721.owners.keys(): - token_id = self._py_erc721.owners[owner] - to = random.choice(self._addresses) - # Transfer in contract, msg.sender == operator - tx = self._erc721.transfer(owner, to, token_id, from_ = operator) - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, to, token_id), - ERC721Mock.Transfer(owner, to, token_id), - ERC721Mock.AfterTokenTransfer(owner, to, token_id) - ] - # Transfer in Py model - self._py_erc721.transfer(operator, owner, to, token_id) - - ###################### TRANSFERS FROM ###################### - @flow(weight=80) - def transfer_from_owner(self) -> None: - # from == by == owner - if self._py_erc721.owners: - token_id, owner = random.choice(list(self._py_erc721.owners.items())) - to = random.choice(self._addresses) - # Transfer in contract, msg.sender == owner - tx = self._erc721.transferFrom(owner, to, token_id, from_ = owner) - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, to, token_id), - ERC721Mock.Transfer(owner, to, token_id), - ERC721Mock.AfterTokenTransfer(owner, to, token_id) - ] - # Transfer in Py model - self._py_erc721.transfer_from(owner, owner, to, token_id) - - @flow(weight=60) - def transfer_from_approved(self) -> None: - # by == approved, from == owner - if self._py_erc721.approvals: - token_id, approved = random.choice(list(self._py_erc721.approvals.items())) - if token_id in self._py_erc721.owners.keys(): - owner = self._py_erc721.owners[token_id] - to = random.choice(self._addresses) - # Transfer in contract, msg.sender == approved - tx = self._erc721.transferFrom(owner, to, token_id, from_ = approved) - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, to, token_id), - ERC721Mock.Transfer(owner, to, token_id), - ERC721Mock.AfterTokenTransfer(owner, to, token_id) - ] - # Transfer in Py model - self._py_erc721.transfer_from(approved, owner, to, token_id) - - @flow(weight=60) - def transfer_from_operator(self) -> None: - # by == operator, from == owner - if self._py_erc721.operators: - owner, operator = random.choice(list(self._py_erc721.operators.items())) - if owner in self._py_erc721.owners.keys(): - token_id = self._py_erc721.owners[owner] - to = random.choice(self._addresses) - # Transfer in contract, msg.sender == operator - tx = self._erc721.transferFrom(owner, to, token_id, from_ = operator) - assert tx.events == [ - ERC721Mock.BeforeTokenTransfer(owner, to, token_id), - ERC721Mock.Transfer(owner, to, token_id), - ERC721Mock.AfterTokenTransfer(owner, to, token_id) - ] - # Transfer in Py model - self._py_erc721.transfer_from(operator, owner, to, token_id) - - ######################## APPROVALS ######################## - @flow(weight=50) - def approve_owner(self) -> None: - if self._py_erc721.owners: - token_id, owner = random.choice(list(self._py_erc721.owners.items())) - account = random.choice(self._addresses) - # Approve in contract - tx = self._erc721.approve(account, token_id, from_=owner) - # Check events - assert tx.events == [ - ERC721Mock.Approval(owner, account, token_id), - - ] - # Approve in Py model - self._py_erc721.approve(account, token_id) - - @flow(weight=40) - def dis_approve_owner(self) -> None: - if self._py_erc721.owners: - token_id, owner = random.choice(list(self._py_erc721.owners.items())) - if token_id in self._py_erc721.approvals.keys(): - # Delete approval in contract - tx = self._erc721.approve(Address(0), token_id, from_=owner) - # Check events - assert tx.events == [ - ERC721Mock.Approval(owner, Address(0), token_id), - ] - # Delete approval in Py model - self._py_erc721.approve(Address(0), token_id) - - @flow(weight=40) - def approve_operator(self) -> None: - if self._py_erc721.operators: - owner, operator = random.choice(list(self._py_erc721.operators.items())) - if owner in self._py_erc721.owners.keys(): - token_id = self._py_erc721.owners[owner] - account = random.choice(self._addresses) - # Approve in contract - tx = self._erc721.approve(account, token_id, from_=operator) - # Check events - assert tx.events == [ - ERC721Mock.Approval(owner, account, token_id), - ] - # Approve in Py model - self._py_erc721.approve(account, token_id) - - #################### APPROVE FOR ALL ######################## - @flow(weight=40) - def approve_for_all(self) -> None: - if self._py_erc721.owners: - _, owner = random.choice(list(self._py_erc721.owners.items())) - operator = random.choice(self._addresses) - # Set approve for all in contract - tx = self._erc721.setApprovalForAll(operator, True, from_=owner) - assert tx.events == [ - ERC721Mock.ApprovalForAll(owner, operator, True), - ] - # Set approve for all in Py model - self._py_erc721.set_approval_for_all(operator, owner) - - - @invariant(period=20) - def invariant_owners(self) -> None: - owners = self._py_erc721.owners.items() - for token_id, owner in owners: - assert self._erc721.ownerOf(token_id) == owner - - @invariant(period=20) - def invariant_balances(self) -> None: - balances = self._py_erc721.balances.items() - for owner, count in balances: - assert self._erc721.balanceOf(owner) == count - - @invariant(period=20) - def invariant_approvals(self) -> None: - approvals = self._py_erc721.approvals.items() - for token_id, approved in approvals: - assert self._erc721.getApproved(token_id) == approved - - -@default_chain.connect() -def test_eip712_fuzz(): - ERC721FuzzTest().run(30, 600) - diff --git a/grouperBot/lib/solady/ext/wake/test_merkle_proof.py b/grouperBot/lib/solady/ext/wake/test_merkle_proof.py deleted file mode 100644 index 2095ed4..0000000 --- a/grouperBot/lib/solady/ext/wake/test_merkle_proof.py +++ /dev/null @@ -1,51 +0,0 @@ -import random - -from wake.testing import * -from wake.testing.fuzzing import random_bytes, random_int -from pytypes.tests.MerkleProofMock import MerkleProofMock - -from .utils import MerkleTree - - -@default_chain.connect() -def test_merkle_proof(): - tree = MerkleTree() - for _ in range(100): - tree.add_leaf(random_bytes(0, 1_000)) - - merkle_proof_mock = MerkleProofMock.deploy() - - for i in range(100): - assert merkle_proof_mock.verify(tree.get_proof(i), tree.root, keccak256(tree.values[i])) - assert merkle_proof_mock.verifyCalldata(tree.get_proof(i), tree.root, keccak256(tree.values[i])) - - -@default_chain.connect() -def test_merkle_multiproof_single(): - tree = MerkleTree() - tree.add_leaf(random_bytes(0, 1_000)) - - merkle_proof_mock = MerkleProofMock.deploy() - assert merkle_proof_mock.verifyMultiProof([], tree.root, [keccak256(tree.values[0])], []) - assert merkle_proof_mock.verifyMultiProofCalldata([], tree.root, [keccak256(tree.values[0])], []) - - assert merkle_proof_mock.verifyMultiProof([keccak256(tree.values[0])], tree.root, [], []) - assert merkle_proof_mock.verifyMultiProofCalldata([keccak256(tree.values[0])], tree.root, [], []) - - -@default_chain.connect() -def test_merkle_multiproof(): - default_chain.set_default_accounts(default_chain.accounts[0]) - - tree = MerkleTree() - for _ in range(1_000): - tree.add_leaf(random_bytes(0, 1_000)) - - merkle_proof_mock = MerkleProofMock.deploy() - - for _ in range(100): - indexes = sorted(random.sample(range(len(tree.values)), random_int(1, 100))) - leaves = [tree.values[i] for i in indexes] - proof, flags = tree.get_multiproof(indexes) - assert merkle_proof_mock.verifyMultiProof(proof, tree.root, [keccak256(leaf) for leaf in leaves], flags) - assert merkle_proof_mock.verifyMultiProofCalldata(proof, tree.root, [keccak256(leaf) for leaf in leaves], flags) diff --git a/grouperBot/lib/solady/ext/wake/test_merkle_proof_fuzz.py b/grouperBot/lib/solady/ext/wake/test_merkle_proof_fuzz.py deleted file mode 100644 index 73a41a0..0000000 --- a/grouperBot/lib/solady/ext/wake/test_merkle_proof_fuzz.py +++ /dev/null @@ -1,123 +0,0 @@ -import random - -from wake.testing import * -from wake.testing.fuzzing import * -from pytypes.tests.MerkleProofMock import MerkleProofMock - -from .utils import MerkleTree - - -class MerkleProofFuzzTest(FuzzTest): - _merkle_proof: MerkleProofMock - _tree: MerkleTree - - def __init__(self): - self._merkle_proof = MerkleProofMock.deploy() - - def pre_sequence(self) -> None: - self._tree = MerkleTree() - for _ in range(random_int(1, 1_000)): - self._tree.add_leaf(random_bytes(0, 100)) - - @flow() - def flow_verify(self) -> None: - index = random_int(0, len(self._tree.values) - 1) - proof = self._tree.get_proof(index) - leaf = self._tree.values[index] - - assert self._merkle_proof.verify(proof, self._tree.root, keccak256(leaf)) - assert self._merkle_proof.verifyCalldata(proof, self._tree.root, keccak256(leaf)) - - @flow(weight=40) - def flow_verify_invalid_random(self, proof: List[bytes32], root: bytes32, leaf: bytes) -> None: - try: - index = self._tree.values.index(leaf) - assert self._tree.root == root - assert self._tree.get_proof(index) == proof - return - except Exception: - pass - - leaf_hash = keccak256(leaf) - assert not self._merkle_proof.verify(proof, root, leaf_hash) - assert not self._merkle_proof.verifyCalldata(proof, root, leaf_hash) - - @flow(weight=60) - def flow_verify_invalid_modified(self) -> None: - index = random_int(0, len(self._tree.values) - 1) - leaf = self._tree.values[index] - proof = self._tree.get_proof(index) - root = self._tree.root - - r = random_int(0, 2) - if r == 0: - leaf = random_bytes(32) - elif r == 1: - if len(proof) != 0: - proof[random_int(0, len(proof) - 1)] = random_bytes(32) - else: - proof.append(random_bytes(32)) - else: - root = random_bytes(32) - - assert not self._merkle_proof.verify(proof, root, keccak256(leaf)) - assert not self._merkle_proof.verifyCalldata(proof, root, keccak256(leaf)) - - @flow() - def flow_verify_multiproof(self) -> None: - indexes = sorted(random.sample(range(len(self._tree.values)), random_int(1, len(self._tree.values)))) - leaves = [self._tree.values[i] for i in indexes] - proof, flags = self._tree.get_multiproof(indexes) - - assert self._merkle_proof.verifyMultiProof(proof, self._tree.root, [keccak256(leaf) for leaf in leaves], flags) - assert self._merkle_proof.verifyMultiProofCalldata(proof, self._tree.root, [keccak256(leaf) for leaf in leaves], flags) - - @flow(weight=40) - def flow_verify_multiproof_invalid_random(self, proof: List[bytes32], root: bytes32, leaves: List[bytes], flags: List[bool]) -> None: - try: - indexes = sorted([self._tree.values.index(leaf) for leaf in leaves]) - assert self._tree.root == root - assert self._tree.get_multiproof(indexes) == (proof, flags) - return - except Exception: - pass - - leaf_hashes = [keccak256(leaf) for leaf in leaves] - assert not self._merkle_proof.verifyMultiProof(proof, root, leaf_hashes, flags) - assert not self._merkle_proof.verifyMultiProofCalldata(proof, root, leaf_hashes, flags) - - @flow(weight=60) - def flow_verify_multiproof_invalid_modified(self) -> None: - indexes = sorted(random.sample(range(len(self._tree.values)), random_int(1, len(self._tree.values)))) - leaves = [self._tree.values[i] for i in indexes] - proof, flags = self._tree.get_multiproof(indexes) - root = self._tree.root - - r = random_int(0, 3) - if r == 0: - if len(leaves) != 0: - leaves[random_int(0, len(leaves) - 1)] = random_bytes(32) - else: - leaves.append(random_bytes(32)) - elif r == 1: - if len(proof) != 0: - proof[random_int(0, len(proof) - 1)] = random_bytes(32) - else: - proof.append(random_bytes(32)) - elif r == 2: - if len(flags) != 0: - pos = random_int(0, len(flags) - 1) - flags[pos] = not flags[pos] - else: - flags.append(random.choice([True, False])) - else: - root = random_bytes(32) - - leaf_hashes = [keccak256(leaf) for leaf in leaves] - assert not self._merkle_proof.verifyMultiProof(proof, root, leaf_hashes, flags) - assert not self._merkle_proof.verifyMultiProofCalldata(proof, root, leaf_hashes, flags) - - -@default_chain.connect() -def test_merkle_proof_fuzz(): - MerkleProofFuzzTest().run(10, 100) diff --git a/grouperBot/lib/solady/ext/wake/test_signature_checker_fuzz.py b/grouperBot/lib/solady/ext/wake/test_signature_checker_fuzz.py deleted file mode 100644 index 24da1ce..0000000 --- a/grouperBot/lib/solady/ext/wake/test_signature_checker_fuzz.py +++ /dev/null @@ -1,177 +0,0 @@ -from wake.testing import * -from wake.testing.fuzzing import * -from pytypes.tests.SignatureCheckerMock import SignatureCheckerMock, ERC1271SignatureChecker - -class SignatureCheckerFuzzTest(FuzzTest): - _signature_checker: SignatureCheckerMock - _erc1271_signature_checker: ERC1271SignatureChecker - _signer: Account - - def pre_sequence(self) -> None: - self._signature_checker = SignatureCheckerMock.deploy() - self._erc1271_signature_checker = ERC1271SignatureChecker.deploy() - self._signer = Account.new() - - @flow() - def flow_check_signature(self) -> None: - data = random_bytes(0, 1000) - hash = keccak256(data) - signature = self._signer.sign_hash(hash) - r = signature[:32] - s = signature[32:64] - v = signature[64] - - assert self._signature_checker.isValidSignatureNow(self._signer, hash, signature) - assert self._signature_checker.isValidSignatureNow_( - self._signer, - hash, - r, - s if v == 27 else (s[0] | 0x80).to_bytes(1, "big") + s[1:], - ) - assert self._signature_checker.isValidSignatureNow__(self._signer, hash, v, r, s) - assert self._signature_checker.isValidSignatureNowCalldata(self._signer, hash, signature) - - # erc1271 - assert self._signature_checker.isValidSignatureNow(self._erc1271_signature_checker, hash, signature, from_=self._signer) - assert self._signature_checker.isValidSignatureNow_( - self._erc1271_signature_checker, - hash, - r, - s if v == 27 else (s[0] | 0x80).to_bytes(1, "big") + s[1:], - from_=self._signer, - ) - assert self._signature_checker.isValidSignatureNow__(self._erc1271_signature_checker, hash, v, r, s, from_=self._signer) - assert self._signature_checker.isValidSignatureNowCalldata(self._erc1271_signature_checker, hash, signature, from_=self._signer) - - assert not self._signature_checker.isValidSignatureNow(self._erc1271_signature_checker, hash, signature) - assert not self._signature_checker.isValidSignatureNow_( - self._erc1271_signature_checker, - hash, - r, - s if v == 27 else (s[0] | 0x80).to_bytes(1, "big") + s[1:], - ) - assert not self._signature_checker.isValidSignatureNow__(self._erc1271_signature_checker, hash, v, r, s) - assert not self._signature_checker.isValidSignatureNowCalldata(self._erc1271_signature_checker, hash, signature) - - @flow(weight=40) - def flow_check_signature_invalid_random(self, signer: Address, hash: bytes32) -> None: - signature = random_bytes(65) - r = signature[:32] - s = signature[32:64] - v = signature[64] - - assert not self._signature_checker.isValidSignatureNow(signer, hash, signature) - assert not self._signature_checker.isValidSignatureNow_( - self._signer, - hash, - r, - s if v == 27 else (s[0] | 0x80).to_bytes(1, "big") + s[1:], - ) - assert not self._signature_checker.isValidSignatureNow__(signer, hash, v, r, s) - assert not self._signature_checker.isValidSignatureNowCalldata(signer, hash, signature) - - assert not self._signature_checker.isValidSignatureNow(self._erc1271_signature_checker, hash, signature, from_=signer) - assert not self._signature_checker.isValidSignatureNow_( - self._erc1271_signature_checker, - hash, - r, - s if v == 27 else (s[0] | 0x80).to_bytes(1, "big") + s[1:], - from_=signer, - ) - assert not self._signature_checker.isValidSignatureNow__(self._erc1271_signature_checker, hash, v, r, s, from_=signer) - assert not self._signature_checker.isValidSignatureNowCalldata(self._erc1271_signature_checker, hash, signature, from_=signer) - - assert not self._signature_checker.isValidERC1271SignatureNow(self._erc1271_signature_checker, hash, signature, from_=signer) - assert not self._signature_checker.isValidERC1271SignatureNow_( - self._erc1271_signature_checker, - hash, - r, - s if v == 27 else (s[0] | 0x80).to_bytes(1, "big") + s[1:], - from_=signer, - ) - assert not self._signature_checker.isValidERC1271SignatureNow__(self._erc1271_signature_checker, hash, v, r, s, from_=signer) - assert not self._signature_checker.isValidERC1271SignatureNowCalldata(self._erc1271_signature_checker, hash, signature, from_=signer) - - @flow(weight=60) - def flow_check_signature_invalid_modified(self) -> None: - signer = self._signer.address - data = random_bytes(0, 1000) - hash = bytearray(keccak256(data)) - signature = bytearray(self._signer.sign_hash(hash)) - original_v = None - - x = random_int(0, 2) - if x == 0: - signer_bytes = bytearray(bytes(signer)) - pos = random_int(0, 19) - new_byte = random_bytes(1)[0] - while signer_bytes[pos] == new_byte: - new_byte = random_bytes(1)[0] - signer_bytes[pos] = new_byte - signer = Address(signer_bytes.hex()) - elif x == 1: - pos = random_int(0, 31) - new_byte = random_bytes(1)[0] - while hash[pos] == new_byte: - new_byte = random_bytes(1)[0] - hash[pos] = new_byte - elif x == 2: - pos = random_int(0, 64) - if pos == 64: - original_v = signature[64] - - new_byte = random_bytes(1)[0] - while signature[pos] == new_byte: - new_byte = random_bytes(1)[0] - signature[pos] = new_byte - else: - assert False - - r = signature[:32] - s = signature[32:64] - v = signature[64] - - if original_v is None: - # v was not modified - vs = s if v == 27 else (s[0] | 0x80).to_bytes(1, "big") + s[1:] - else: - # v was modified - vs = s if original_v == 28 else (s[0] | 0x80).to_bytes(1, "big") + s[1:] - - assert not self._signature_checker.isValidSignatureNow(signer, hash, signature) - assert not self._signature_checker.isValidSignatureNow_( - signer, - hash, - r, - vs, - ) - assert not self._signature_checker.isValidSignatureNow__(signer, hash, v, r, s) - assert not self._signature_checker.isValidSignatureNowCalldata(signer, hash, signature) - - # erc1271 - assert not self._signature_checker.isValidSignatureNow(self._erc1271_signature_checker, hash, signature, from_=signer) - assert not self._signature_checker.isValidSignatureNow_( - self._erc1271_signature_checker, - hash, - r, - vs, - from_=signer, - ) - assert not self._signature_checker.isValidSignatureNow__(self._erc1271_signature_checker, hash, v, r, s, from_=signer) - assert not self._signature_checker.isValidSignatureNowCalldata(self._erc1271_signature_checker, hash, signature, from_=signer) - - assert not self._signature_checker.isValidERC1271SignatureNow(self._erc1271_signature_checker, hash, signature, from_=signer) - assert not self._signature_checker.isValidERC1271SignatureNow_( - self._erc1271_signature_checker, - hash, - r, - vs, - from_=signer, - ) - assert not self._signature_checker.isValidERC1271SignatureNow__(self._erc1271_signature_checker, hash, v, r, s, from_=signer) - assert not self._signature_checker.isValidERC1271SignatureNowCalldata(self._erc1271_signature_checker, hash, signature, from_=signer) - - -@default_chain.connect() -def test_signature_checker(): - SignatureCheckerFuzzTest().run(10, 20) diff --git a/grouperBot/lib/solady/ext/wake/utils.py b/grouperBot/lib/solady/ext/wake/utils.py deleted file mode 100644 index eec4c32..0000000 --- a/grouperBot/lib/solady/ext/wake/utils.py +++ /dev/null @@ -1,89 +0,0 @@ -from typing import List, Tuple - -from wake.testing import keccak256 - - -class MerkleTree: - _is_ready: bool - _leaves: List[bytes] - _levels: List[List[bytes]] - - def __init__(self): - self._is_ready = False - self._leaves = [] - self._levels = [] - - @property - def root(self) -> bytes: - if not self._is_ready: - self._build_tree() - return self._levels[-1][0] - - @property - def values(self) -> Tuple[bytes, ...]: - return tuple(self._leaves) - - def get_proof(self, index: int) -> List[bytes]: - if not self._is_ready: - self._build_tree() - - proof = [] - for level in self._levels[:-1]: - if index % 2 == 0: - proof.append(level[index + 1]) - else: - proof.append(level[index - 1]) - index //= 2 - return proof - - def get_multiproof(self, indexes: List[int]) -> Tuple[List[bytes], List[bool]]: - if not self._is_ready: - self._build_tree() - - proof = [] - flags = [] - known = indexes - assert known == sorted(known), "Leaves must be sorted" - - for level in self._levels[:-1]: - new_known = [] - for i in known: - if i % 2 == 0: - if i + 1 in known: - flags.append(True) - else: - flags.append(False) - if i + 1 < len(level): - proof.append(level[i + 1]) - else: - proof.append(level[i]) - else: - if i - 1 in known: - pass # already processed - else: - flags.append(False) - proof.append(level[i - 1]) - if len(new_known) == 0 or new_known[-1] != i // 2: - new_known.append(i // 2) - known = new_known - - return proof, flags - - def add_leaf(self, leaf: bytes): - self._leaves.append(leaf) - self._is_ready = False - - def _build_tree(self) -> None: - self._levels.append([keccak256(leaf) for leaf in self._leaves]) - while len(self._levels[-1]) > 1: - self._levels.append(self._build_level(self._levels[-1])) - self._is_ready = True - - def _build_level(self, level: List[bytes]) -> List[bytes]: - if len(level) % 2 == 1: - level.append(level[-1]) - return [ - keccak256(level[i] + level[i + 1]) if level[i] < level[i + 1] - else keccak256(level[i + 1] + level[i]) - for i in range(0, len(level), 2) - ] diff --git a/grouperBot/lib/solady/ext/wake/wake.toml b/grouperBot/lib/solady/ext/wake/wake.toml deleted file mode 100644 index 94c5f64..0000000 --- a/grouperBot/lib/solady/ext/wake/wake.toml +++ /dev/null @@ -1,27 +0,0 @@ -[compiler.solc] -exclude_paths = ["node_modules", "venv", ".venv", "lib", "script", "test"] -include_paths = ["node_modules"] -remappings = [ - "forge-std/=test/utils/forge-std/", -] - -[compiler.solc.optimizer] -enabled = true -runs = 1000 - -[detectors] -exclude = ["unused-contract", "unused-import"] -ignore_paths = ["venv", ".venv", "test"] -exclude_paths = ["node_modules", "lib", "script"] - -[testing] -cmd = "anvil" - -[testing.anvil] -cmd_args = "--prune-history 100 --transaction-block-keeper 10 --steps-tracing --silent" - -[testing.ganache] -cmd_args = "-k istanbul -q" - -[testing.hardhat] -cmd_args = "" \ No newline at end of file diff --git a/grouperBot/lib/solady/ext/wake/weird/Approval.sol b/grouperBot/lib/solady/ext/wake/weird/Approval.sol deleted file mode 100644 index ff1026f..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/Approval.sol +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract ApprovalRaceToken is ERC20 { - // --- Init --- - constructor(uint _totalSupply) ERC20(_totalSupply) public {} - - // --- Token --- - function approve(address usr, uint wad) override public returns (bool) { - require(allowance[msg.sender][usr] == 0, "unsafe-approve"); - return super.approve(usr, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/ApprovalToZero.sol b/grouperBot/lib/solady/ext/wake/weird/ApprovalToZero.sol deleted file mode 100644 index 01ffff3..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/ApprovalToZero.sol +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract ApprovalToZeroToken is ERC20 { - // --- Init --- - constructor(uint _totalSupply) ERC20(_totalSupply) public {} - - // --- Token --- - function approve(address usr, uint wad) override public returns (bool) { - require(usr != address(0), "no approval for the zero address"); - return super.approve(usr, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/BlockList.sol b/grouperBot/lib/solady/ext/wake/weird/BlockList.sol deleted file mode 100644 index a4f76f1..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/BlockList.sol +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract BlockableToken is ERC20 { - // --- Access Control --- - address owner; - modifier auth() { require(msg.sender == owner, "unauthorised"); _; } - - // --- BlockList --- - mapping(address => bool) blocked; - function block(address usr) auth public { blocked[usr] = true; } - function allow(address usr) auth public { blocked[usr] = false; } - - // --- Init --- - constructor(uint _totalSupply) ERC20(_totalSupply) public { - owner = msg.sender; - } - - // --- Token --- - function transferFrom(address src, address dst, uint wad) override public returns (bool) { - require(!blocked[src], "blocked"); - require(!blocked[dst], "blocked"); - return super.transferFrom(src, dst, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/Bytes32Metadata.sol b/grouperBot/lib/solady/ext/wake/weird/Bytes32Metadata.sol deleted file mode 100644 index 3a03f27..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/Bytes32Metadata.sol +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -contract Math { - // --- Math --- - function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x); - } - function sub(uint x, uint y) internal pure returns (uint z) { - require((z = x - y) <= x); - } -} - -contract ERC20 is Math { - // --- ERC20 Data --- - bytes32 public constant name = "Token"; - bytes32 public constant symbol = "TKN"; - uint8 public constant decimals = 18; - uint256 public totalSupply; - - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Init --- - constructor(uint _totalSupply) public { - totalSupply = _totalSupply; - balanceOf[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - // --- Token --- - function transfer(address dst, uint wad) virtual public returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - function transferFrom(address src, address dst, uint wad) virtual public returns (bool) { - require(balanceOf[src] >= wad, "insufficient-balance"); - if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) { - require(allowance[src][msg.sender] >= wad, "insufficient-allowance"); - allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); - } - balanceOf[src] = sub(balanceOf[src], wad); - balanceOf[dst] = add(balanceOf[dst], wad); - emit Transfer(src, dst, wad); - return true; - } - function approve(address usr, uint wad) virtual public returns (bool) { - allowance[msg.sender][usr] = wad; - emit Approval(msg.sender, usr, wad); - return true; - } - - function mint(address usr, uint wad) virtual public { - balanceOf[usr] = add(balanceOf[usr], wad); - totalSupply = add(totalSupply, wad); - emit Transfer(address(0), usr, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/DaiPermit.sol b/grouperBot/lib/solady/ext/wake/weird/DaiPermit.sol deleted file mode 100644 index 80188b8..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/DaiPermit.sol +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -contract Math { - // --- Math --- - function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x); - } - function sub(uint x, uint y) internal pure returns (uint z) { - require((z = x - y) <= x); - } -} - -contract DaiPermit is Math { - // --- ERC20 Data --- - string public constant name = "Token"; - string public constant symbol = "TKN"; - uint8 public decimals = 18; - uint256 public totalSupply; - bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb; - bytes32 public immutable DOMAIN_SEPARATOR = keccak256( - abi.encode( - keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), - keccak256(bytes(name)), - keccak256(bytes('1')), - block.chainid, - address(this) - ) - ); - - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; - mapping (address => uint) public nonces; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Init --- - constructor(uint _totalSupply) public { - totalSupply = _totalSupply; - balanceOf[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - // --- Token --- - function transfer(address dst, uint wad) virtual public returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - function transferFrom(address src, address dst, uint wad) virtual public returns (bool) { - require(balanceOf[src] >= wad, "insufficient-balance"); - if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) { - require(allowance[src][msg.sender] >= wad, "insufficient-allowance"); - allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); - } - balanceOf[src] = sub(balanceOf[src], wad); - balanceOf[dst] = add(balanceOf[dst], wad); - emit Transfer(src, dst, wad); - return true; - } - function approve(address usr, uint wad) virtual public returns (bool) { - allowance[msg.sender][usr] = wad; - emit Approval(msg.sender, usr, wad); - return true; - } - function permit(address holder, address spender, uint256 nonce, uint256 expiry, - bool allowed, uint8 v, bytes32 r, bytes32 s) external - { - bytes32 digest = - keccak256(abi.encodePacked( - "\x19\x01", - DOMAIN_SEPARATOR, - keccak256(abi.encode(PERMIT_TYPEHASH, - holder, - spender, - nonce, - expiry, - allowed)) - )); - - require(holder != address(0), "Dai/invalid-address-0"); - require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit"); - require(expiry == 0 || block.timestamp <= expiry, "Dai/permit-expired"); - require(nonce == nonces[holder]++, "Dai/invalid-nonce"); - uint wad = allowed ? type(uint256).max : 0; - allowance[holder][spender] = wad; - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/ERC20.sol b/grouperBot/lib/solady/ext/wake/weird/ERC20.sol deleted file mode 100644 index 15adf96..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/ERC20.sol +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -contract Math { - // --- Math --- - function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x); - } - function sub(uint x, uint y) internal pure returns (uint z) { - require((z = x - y) <= x); - } -} - -contract ERC20 is Math { - // --- ERC20 Data --- - string public constant name = "Token"; - string public constant symbol = "TKN"; - uint8 public decimals = 18; - uint256 public totalSupply; - - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Init --- - constructor(uint _totalSupply) public { - totalSupply = _totalSupply; - balanceOf[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - // --- Token --- - function transfer(address dst, uint wad) virtual public returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - function transferFrom(address src, address dst, uint wad) virtual public returns (bool) { - require(balanceOf[src] >= wad, "insufficient-balance"); - if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) { - require(allowance[src][msg.sender] >= wad, "insufficient-allowance"); - allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); - } - balanceOf[src] = sub(balanceOf[src], wad); - balanceOf[dst] = add(balanceOf[dst], wad); - emit Transfer(src, dst, wad); - return true; - } - function approve(address usr, uint wad) virtual public returns (bool) { - allowance[msg.sender][usr] = wad; - emit Approval(msg.sender, usr, wad); - return true; - } - - function mint(address usr, uint wad) virtual public { - balanceOf[usr] = add(balanceOf[usr], wad); - totalSupply = add(totalSupply, wad); - emit Transfer(address(0), usr, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/HighDecimals.sol b/grouperBot/lib/solady/ext/wake/weird/HighDecimals.sol deleted file mode 100644 index 423c2f4..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/HighDecimals.sol +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract HighDecimalToken is ERC20 { - constructor(uint _totalSupply) ERC20(_totalSupply) public { - decimals = 50; - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/LowDecimals.sol b/grouperBot/lib/solady/ext/wake/weird/LowDecimals.sol deleted file mode 100644 index aa5284d..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/LowDecimals.sol +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract LowDecimalToken is ERC20 { - constructor(uint _totalSupply) ERC20(_totalSupply) public { - decimals = 2; - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/MissingReturns.sol b/grouperBot/lib/solady/ext/wake/weird/MissingReturns.sol deleted file mode 100644 index 6793b53..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/MissingReturns.sol +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -contract MissingReturnToken { - // --- ERC20 Data --- - string public constant name = "Token"; - string public constant symbol = "TKN"; - uint8 public constant decimals = 18; - uint256 public totalSupply; - - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Math --- - function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x); - } - function sub(uint x, uint y) internal pure returns (uint z) { - require((z = x - y) <= x); - } - - // --- Init --- - constructor(uint _totalSupply) public { - totalSupply = _totalSupply; - balanceOf[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - // --- Token --- - function transfer(address dst, uint wad) external { - transferFrom(msg.sender, dst, wad); - } - function transferFrom(address src, address dst, uint wad) public { - require(balanceOf[src] >= wad, "insufficient-balance"); - if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) { - require(allowance[src][msg.sender] >= wad, "insufficient-allowance"); - allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); - } - balanceOf[src] = sub(balanceOf[src], wad); - balanceOf[dst] = add(balanceOf[dst], wad); - emit Transfer(src, dst, wad); - } - function approve(address usr, uint wad) external { - allowance[msg.sender][usr] = wad; - emit Approval(msg.sender, usr, wad); - } - - function mint(address usr, uint wad) external { - balanceOf[usr] = add(balanceOf[usr], wad); - totalSupply = add(totalSupply, wad); - emit Transfer(address(0), usr, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/NoRevert.sol b/grouperBot/lib/solady/ext/wake/weird/NoRevert.sol deleted file mode 100644 index 01e5abc..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/NoRevert.sol +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -contract NoRevertToken { - // --- ERC20 Data --- - string public constant name = "Token"; - string public constant symbol = "TKN"; - uint8 public decimals = 18; - uint256 public totalSupply; - - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Init --- - constructor(uint _totalSupply) public { - totalSupply = _totalSupply; - balanceOf[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - // --- Token --- - function transfer(address dst, uint wad) external returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - function transferFrom(address src, address dst, uint wad) virtual public returns (bool) { - if (balanceOf[src] < wad) return false; // insufficient src bal - if (balanceOf[dst] >= (type(uint256).max - wad)) return false; // dst bal too high - - if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) { - if (allowance[src][msg.sender] < wad) return false; // insufficient allowance - allowance[src][msg.sender] = allowance[src][msg.sender] - wad; - } - - balanceOf[src] = balanceOf[src] - wad; - balanceOf[dst] = balanceOf[dst] + wad; - - emit Transfer(src, dst, wad); - return true; - } - function approve(address usr, uint wad) virtual external returns (bool) { - allowance[msg.sender][usr] = wad; - emit Approval(msg.sender, usr, wad); - return true; - } - - function mint(address usr, uint wad) virtual external { - balanceOf[usr] = balanceOf[usr] + wad; - totalSupply = totalSupply + wad; - emit Transfer(address(0), usr, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/Pausable.sol b/grouperBot/lib/solady/ext/wake/weird/Pausable.sol deleted file mode 100644 index cc0518f..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/Pausable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract PausableToken is ERC20 { - // --- Access Control --- - address owner; - modifier auth() { require(msg.sender == owner, "unauthorised"); _; } - - // --- Pause --- - bool live = true; - function stop() auth external { live = false; } - function start() auth external { live = true; } - - // --- Init --- - constructor(uint _totalSupply) ERC20(_totalSupply) public { - owner = msg.sender; - } - - // --- Token --- - function approve(address usr, uint wad) override public returns (bool) { - require(live, "paused"); - return super.approve(usr, wad); - } - function transfer(address dst, uint wad) override public returns (bool) { - require(live, "paused"); - return super.transfer(dst, wad); - } - function transferFrom(address src, address dst, uint wad) override public returns (bool) { - require(live, "paused"); - return super.transferFrom(src, dst, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/Proxied.sol b/grouperBot/lib/solady/ext/wake/weird/Proxied.sol deleted file mode 100644 index 6ae632d..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/Proxied.sol +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -/* - Provides two contracts: - - 1. ProxiedToken: The underlying token, state modifications must be made through a proxy - 2. TokenProxy: Proxy contract, appends the original msg.sender to any calldata provided by the user - - The ProxiedToken can have many trusted frontends (TokenProxy's). - The frontends should append the address of their caller to calldata when calling into the backend. - Admin users of the ProxiedToken can add new delegators. -*/ - -contract ProxiedToken { - // --- ERC20 Data --- - string public constant name = "Token"; - string public constant symbol = "TKN"; - uint8 public constant decimals = 18; - uint256 public totalSupply; - - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Math --- - function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x); - } - function sub(uint x, uint y) internal pure returns (uint z) { - require((z = x - y) <= x); - } - - // --- Init --- - constructor(uint _totalSupply) public { - admin[msg.sender] = true; - totalSupply = _totalSupply; - balanceOf[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - // --- Access Control --- - mapping(address => bool) public admin; - function rely(address usr) external auth { admin[usr] = true; } - function deny(address usr) external auth { admin[usr] = false; } - modifier auth() { require(admin[msg.sender], "non-admin-call"); _; } - - mapping(address => bool) public delegators; - modifier delegated() { require(delegators[msg.sender], "non-delegator-call"); _; } - function setDelegator(address delegator, bool status) external { - delegators[delegator] = status; - } - - // --- Token --- - function transfer(address dst, uint wad) delegated external returns (bool) { - return _transferFrom(_getCaller(), _getCaller(), dst, wad); - } - function transferFrom(address src, address dst, uint wad) delegated external returns (bool) { - return _transferFrom(_getCaller(), src, dst, wad); - } - function approve(address usr, uint wad) delegated external returns (bool) { - return _approve(_getCaller(), usr, wad); - } - - // --- Internals --- - function _transferFrom( - address caller, address src, address dst, uint wad - ) internal returns (bool) { - require(balanceOf[src] >= wad, "insufficient-balance"); - if (src != caller && allowance[src][caller] != type(uint).max) { - require(allowance[src][caller] >= wad, "insufficient-allowance"); - allowance[src][caller] = sub(allowance[src][caller], wad); - } - balanceOf[src] = sub(balanceOf[src], wad); - balanceOf[dst] = add(balanceOf[dst], wad); - emit Transfer(src, dst, wad); - return true; - } - function _approve(address caller, address usr, uint wad) internal returns (bool) { - allowance[caller][usr] = wad; - emit Approval(caller, usr, wad); - return true; - } - // grabs the first word after the calldata and masks it with 20bytes of 1's - // to turn it into an address - function _getCaller() internal pure returns (address result) { - bytes memory array = msg.data; - uint256 index = msg.data.length; - assembly { - result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff) - } - return result; - } - - function mint(address usr, uint wad) external { - balanceOf[usr] = add(balanceOf[usr], wad); - totalSupply = add(totalSupply, wad); - emit Transfer(address(0), usr, wad); - } -} - -contract TokenProxy { - address payable immutable public impl; - constructor(address _impl) public { - impl = payable(_impl); - } - - receive() external payable { revert("don't send me ETH!"); } - - fallback() external payable { - address _impl = impl; // pull impl onto the stack - assembly { - // get free data pointer - let ptr := mload(0x40) - - // write calldata to ptr - calldatacopy(ptr, 0, calldatasize()) - // store msg.sender after the calldata - mstore(add(ptr, calldatasize()), caller()) - - // call impl with the contents of ptr as caldata - let result := call(gas(), _impl, callvalue(), ptr, add(calldatasize(), 32), 0, 0) - - // copy the returndata to ptr - let size := returndatasize() - returndatacopy(ptr, 0, size) - - switch result - // revert if the call failed - case 0 { revert(ptr, size) } - // return ptr otherwise - default { return(ptr, size) } - } - } - -} diff --git a/grouperBot/lib/solady/ext/wake/weird/Reentrant.sol b/grouperBot/lib/solady/ext/wake/weird/Reentrant.sol deleted file mode 100644 index f14dbe9..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/Reentrant.sol +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract ReentrantToken is ERC20 { - // --- Init --- - constructor(uint _totalSupply) ERC20(_totalSupply) public {} - - // --- Call Targets --- - mapping (address => Target) public targets; - struct Target { - bytes data; - address addr; - } - function setTarget(address addr, bytes calldata data) external { - targets[msg.sender] = Target(data, addr); - } - - // --- Token --- - function transferFrom(address src, address dst, uint wad) override public returns (bool res) { - res = super.transferFrom(src, dst, wad); - Target memory target = targets[src]; - if (target.addr != address(0)) { - (bool status,) = target.addr.call{gas: gasleft()}(target.data); - require(status, "call failed"); - } - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/ReturnsFalse.sol b/grouperBot/lib/solady/ext/wake/weird/ReturnsFalse.sol deleted file mode 100644 index 5800805..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/ReturnsFalse.sol +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -contract ReturnsFalseToken { - // --- ERC20 Data --- - string public constant name = "Token"; - string public constant symbol = "TKN"; - uint8 public constant decimals = 18; - uint256 public totalSupply; - - mapping (address => uint) public balanceOf; - mapping (address => mapping (address => uint)) public allowance; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Math --- - function add(uint x, uint y) internal pure returns (uint z) { - require((z = x + y) >= x); - } - function sub(uint x, uint y) internal pure returns (uint z) { - require((z = x - y) <= x); - } - - // --- Init --- - constructor(uint _totalSupply) public { - totalSupply = _totalSupply; - balanceOf[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - // --- Token --- - function transfer(address dst, uint wad) external returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - function transferFrom(address src, address dst, uint wad) public returns (bool) { - require(balanceOf[src] >= wad, "insufficient-balance"); - if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) { - require(allowance[src][msg.sender] >= wad, "insufficient-allowance"); - allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); - } - balanceOf[src] = sub(balanceOf[src], wad); - balanceOf[dst] = add(balanceOf[dst], wad); - emit Transfer(src, dst, wad); - return false; - } - function approve(address usr, uint wad) external returns (bool) { - allowance[msg.sender][usr] = wad; - emit Approval(msg.sender, usr, wad); - return false; - } - - function mint(address usr, uint wad) external returns (bool) { - balanceOf[usr] = add(balanceOf[usr], wad); - totalSupply = add(totalSupply, wad); - emit Transfer(address(0), usr, wad); - return false; - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/RevertToZero.sol b/grouperBot/lib/solady/ext/wake/weird/RevertToZero.sol deleted file mode 100644 index 6a50c90..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/RevertToZero.sol +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract RevertToZeroToken is ERC20 { - // --- Init --- - constructor(uint _totalSupply) ERC20(_totalSupply) public {} - - // --- Token --- - function transferFrom(address src, address dst, uint wad) override public returns (bool) { - require(dst != address(0), "transfer-to-zero"); - return super.transferFrom(src, dst, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/RevertZero.sol b/grouperBot/lib/solady/ext/wake/weird/RevertZero.sol deleted file mode 100644 index 1357578..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/RevertZero.sol +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract RevertZeroToken is ERC20 { - // --- Init --- - constructor(uint _totalSupply) ERC20(_totalSupply) public {} - - // --- Token --- - function transferFrom(address src, address dst, uint wad) override public returns (bool) { - require(wad != 0, "zero-value-transfer"); - return super.transferFrom(src, dst, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/TransferFee.sol b/grouperBot/lib/solady/ext/wake/weird/TransferFee.sol deleted file mode 100644 index 0a1eb58..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/TransferFee.sol +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract TransferFeeToken is ERC20 { - - uint immutable fee; - - // --- Init --- - constructor(uint _totalSupply, uint _fee) ERC20(_totalSupply) public { - fee = _fee; - } - - // --- Token --- - function transferFrom(address src, address dst, uint wad) override public returns (bool) { - require(balanceOf[src] >= wad, "insufficient-balance"); - if (src != msg.sender && allowance[src][msg.sender] != type(uint).max) { - require(allowance[src][msg.sender] >= wad, "insufficient-allowance"); - allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); - } - - balanceOf[src] = sub(balanceOf[src], wad); - balanceOf[dst] = add(balanceOf[dst], sub(wad, fee)); - balanceOf[address(0)] = add(balanceOf[address(0)], fee); - - emit Transfer(src, dst, sub(wad, fee)); - emit Transfer(src, address(0), fee); - - return true; - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/Uint96.sol b/grouperBot/lib/solady/ext/wake/weird/Uint96.sol deleted file mode 100644 index 26a862e..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/Uint96.sol +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2017, 2018, 2019, 2020 dbrock, rain, mrchico, d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -contract Uint96ERC20 { - // --- ERC20 Data --- - string public constant name = "Token"; - string public constant symbol = "TKN"; - uint8 public decimals = 18; - uint96 internal supply; - - mapping (address => uint96) internal balances; - mapping (address => mapping (address => uint96)) internal allowances; - - event Approval(address indexed src, address indexed guy, uint wad); - event Transfer(address indexed src, address indexed dst, uint wad); - - // --- Math --- - function add(uint96 x, uint96 y) internal pure returns (uint96 z) { - require((z = x + y) >= x); - } - function sub(uint96 x, uint96 y) internal pure returns (uint96 z) { - require((z = x - y) <= x); - } - function safe96(uint256 n) internal pure returns (uint96) { - require(n < 2**96); - return uint96(n); - } - - // --- Init --- - constructor(uint96 _supply) public { - supply = _supply; - balances[msg.sender] = _supply; - emit Transfer(address(0), msg.sender, _supply); - } - - // --- Getters --- - function totalSupply() external view returns (uint) { - return supply; - } - function balanceOf(address usr) external view returns (uint) { - return balances[usr]; - } - function allowance(address src, address dst) external view returns (uint) { - return allowances[src][dst]; - } - - // --- Token --- - function transfer(address dst, uint wad) virtual public returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - function transferFrom(address src, address dst, uint wad) virtual public returns (bool) { - uint96 amt = safe96(wad); - - if (src != msg.sender && allowances[src][msg.sender] != type(uint96).max) { - allowances[src][msg.sender] = sub(allowances[src][msg.sender], amt); - } - - balances[src] = sub(balances[src], amt); - balances[dst] = add(balances[dst], amt); - emit Transfer(src, dst, wad); - return true; - } - function approve(address usr, uint wad) virtual public returns (bool) { - uint96 amt; - if (wad == type(uint).max) { - amt = type(uint96).max; - } else { - amt = safe96(wad); - } - - allowances[msg.sender][usr] = amt; - - emit Approval(msg.sender, usr, amt); - return true; - } - - function mint(address usr, uint wad) virtual public { - uint96 amt = safe96(wad); - - balances[usr] = add(balances[usr], amt); - supply = add(supply, amt); - - emit Transfer(address(0), usr, wad); - } -} diff --git a/grouperBot/lib/solady/ext/wake/weird/Upgradable.sol b/grouperBot/lib/solady/ext/wake/weird/Upgradable.sol deleted file mode 100644 index fa04d3a..0000000 --- a/grouperBot/lib/solady/ext/wake/weird/Upgradable.sol +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2020 d-xo -// SPDX-License-Identifier: AGPL-3.0-only - -pragma solidity >=0.6.12; - -import {ERC20} from "./ERC20.sol"; - -contract Proxy { - bytes32 constant ADMIN_KEY = bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1); - bytes32 constant IMPLEMENTATION_KEY = bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1); - - // --- init --- - - constructor(uint totalSupply) public { - - // Manual give() - bytes32 slot = ADMIN_KEY; - address usr = msg.sender; - assembly { sstore(slot, usr) } - - upgrade(address(new ERC20(totalSupply))); - - } - - // --- auth --- - - modifier auth() { require(msg.sender == owner(), "unauthorised"); _; } - - function owner() public view returns (address usr) { - bytes32 slot = ADMIN_KEY; - assembly { usr := sload(slot) } - } - - function give(address usr) public auth { - bytes32 slot = ADMIN_KEY; - assembly { sstore(slot, usr) } - } - - // --- upgrade --- - - function implementation() public view returns (address impl) { - bytes32 slot = IMPLEMENTATION_KEY; - assembly { impl := sload(slot) } - } - - function upgrade(address impl) public auth { - bytes32 slot = IMPLEMENTATION_KEY; - assembly { sstore(slot, impl) } - } - - // --- proxy --- - - fallback() external payable { - address impl = implementation(); - (bool success, bytes memory returndata) = impl.delegatecall{gas: gasleft()}(msg.data); - require(success); - assembly { return(add(returndata, 0x20), mload(returndata)) } - } - - receive() external payable { revert("don't send me ETH!"); } -} diff --git a/grouperBot/lib/solady/foundry.toml b/grouperBot/lib/solady/foundry.toml deleted file mode 100644 index aa93785..0000000 --- a/grouperBot/lib/solady/foundry.toml +++ /dev/null @@ -1,55 +0,0 @@ -# Foundry Configuration File -# Default definitions: https://github.com/foundry-rs/foundry/blob/b7917fa8491aedda4dd6db53fbb206ea233cd531/config/src/lib.rs#L782 -# See more config options at: https://github.com/foundry-rs/foundry/tree/master/.config - -# The Default Profile -[profile.default] -solc_version = "0.8.30" -evm_version = "paris" # Cancun will be tested in the CI. -auto_detect_solc = false -optimizer = true -optimizer_runs = 1_000 -gas_limit = 100_000_000 # ETH is 30M, but we use a higher value. -skip = ["*/*7702*", "*/*BlockHashLib*", "*/*Transient*", "*/ext/ithaca/*", "*/ext/zksync/*"] -fs_permissions = [{ access = "read", path = "./test/data"}] -remappings = [ - "forge-std=test/utils/forge-std/" -] - -[profile.pre_global_structs] -skip = ["*/g/*", "*/*7702*", "*/*BlockHashLib*", "*/*Transient*", "*/ext/ithaca/*", "*/ext/zksync/*"] - -[profile.post_cancun] -evm_version = "cancun" -skip = ["*/ext/ithaca/*"] - -[profile.zksync] -match_path = "*/ext/zksync/*" -evm_version = "cancun" -skip = [] - -[profile.ithaca] -evm_version = "cancun" -odyssey = true -skip = [] - -[profile.solx] -solc_version = "/usr/local/bin/solx" -evm_version = "paris" # Cancun will be tested in the CI. -optimization = 3 -gas_limit = 100_000_000 # ETH is 30M, but we use a higher value. -skip = ["*/*7702*", "*/*Transient*", "*/ext/ithaca/*", "*/ext/zksync/*"] -fs_permissions = [{ access = "read", path = "./test/data"}] -remappings = [ - "forge-std=test/utils/forge-std/" -] - -[fmt] -line_length = 100 # While we allow up to 120, we lint at 100 for readability. - -[profile.default.fuzz] -runs = 256 - -[invariant] -depth = 15 -runs = 10 diff --git a/grouperBot/lib/solady/funding.json b/grouperBot/lib/solady/funding.json deleted file mode 100644 index a790faf..0000000 --- a/grouperBot/lib/solady/funding.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "opRetro": { - "projectId": "0x9151666888d0ca532a529be98a50d2eb992988117e202163f865fa9a27eb7149" - } -} \ No newline at end of file diff --git a/grouperBot/lib/solady/js/solady.d.ts b/grouperBot/lib/solady/js/solady.d.ts deleted file mode 100644 index 318c86b..0000000 --- a/grouperBot/lib/solady/js/solady.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Accompanying JavaScript library for Solady. - * - * To install: - * - * ``` - * npm install solady - * ``` - * - * Module exports: - * - * - `LibZip` - * - `flzCompress(data)`: Compresses hex encoded data with FastLZ. - * - `flzDecompress(data)`: Decompresses hex encoded data with FastLZ. - * - `cdCompress(data)`: Compresses hex encoded calldata. - * - `cdDecompress(data)`: Decompresses hex encoded calldata. - * - * - `ERC1967Factory` - * - `address`: Canonical address of Solady's ERC1967Factory. - * - `abi`: ABI of Solady's ERC1967Factory. - */ -declare module "solady" { - /** - * FastLZ and calldata compression / decompression functions. - */ - namespace LibZip { - /** - * Compresses hex encoded data with the FastLZ LZ77 algorithm. - * @param data - A hex encoded string representing the original data. - * @returns The compressed result as a hex encoded string. - */ - function flzCompress(data: string): string; - /** - * Decompresses hex encoded data with the FastLZ LZ77 algorithm. - * @param data - A hex encoded string representing the compressed data. - * @returns The decompressed result as a hex encoded string. - */ - function flzDecompress(data: string): string; - /** - * Compresses hex encoded calldata. - * @param data - A hex encoded string representing the original data. - * @returns The compressed result as a hex encoded string. - */ - function cdCompress(data: string): string; - /** - * Decompresses hex encoded calldata. - * @param data - A hex encoded string representing the compressed data. - * @returns The decompressed result as a hex encoded string. - */ - function cdDecompress(data: string): string; - } - /** - * ERC1967Factory canonical address and ABI. - */ - namespace ERC1967Factory { - /** - * Canonical address of Solady's ERC1967Factory. - */ - var address: string; - /** - * ABI of Solady's ERC1967Factory. - */ - var abi: any; - } -} - diff --git a/grouperBot/lib/solady/js/solady.js b/grouperBot/lib/solady/js/solady.js deleted file mode 100644 index 3d79248..0000000 --- a/grouperBot/lib/solady/js/solady.js +++ /dev/null @@ -1,255 +0,0 @@ -/** - * Accompanying JavaScript library for Solady. - * - * To install: - * - * ``` - * npm install solady - * ``` - * - * Module exports: - * - * - `LibZip` - * - `flzCompress(data)`: Compresses hex encoded data with FastLZ. - * - `flzDecompress(data)`: Decompresses hex encoded data with FastLZ. - * - `cdCompress(data)`: Compresses hex encoded calldata. - * - `cdDecompress(data)`: Decompresses hex encoded calldata. - * - * - `ERC1967Factory` - * - `address`: Canonical address of Solady's ERC1967Factory. - * - `abi`: ABI of Solady's ERC1967Factory. - * - * @module solady - */ -(function(global, factory) { - - "use strict"; - - if (typeof module === "object" && typeof module.exports === "object") { - module.exports = factory(global, 1); - if (typeof exports === "object") { - exports.LibZip = module.exports.LibZip; - exports.ERC1967Factory = module.exports.ERC1967Factory; - } - } else { - factory(global); - } - -})(typeof window !== "undefined" ? window : this, function(window, noGlobal) { - - "use strict"; - - var solady = {}; - - /*============================================================*/ - /* LibZip Operations */ - /*============================================================*/ - - // See: https://github.com/vectorized/solady/blob/main/src/utils/LibZip.sol - - /** - * FastLZ and calldata compression / decompression functions. - * @namespace - * @alias module:solady.LibZip - */ - var LibZip = {}; - - solady.LibZip = LibZip; - - function hexString(data) { - if (typeof data === "string" || data instanceof String) { - if (data = data.match(/^[\s\uFEFF\xA0]*(0[Xx])?([0-9A-Fa-f]*)[\s\uFEFF\xA0]*$/)) { - if (data[2].length % 2) { - throw new Error("Hex string length must be a multiple of 2."); - } - return data[2]; - } - } - throw new Error("Data must be a hex string."); - } - - function byteToString(b) { - return (b | 0x100).toString(16).slice(1); - } - - function parseByte(data, i) { - return parseInt(data.substr(i, 2), 16); - } - - function hexToBytes(data) { - var a = [], i = 0; - for (; i < data.length; i += 2) a.push(parseByte(data, i)); - return a; - } - - function bytesToHex(a) { - var o = "0x", i = 0; - for (; i < a.length; o += byteToString(a[i++])) ; - return o; - } - - /** - * Compresses hex encoded data with the FastLZ LZ77 algorithm. - * @param {string} data A hex encoded string representing the original data. - * @returns {string} The compressed result as a hex encoded string. - */ - LibZip.flzCompress = function(data) { - var ib = hexToBytes(hexString(data)), b = ib.length - 4; - var ht = [], ob = [], a = 0, i = 2, o = 0, j, s, h, d, c, l, r, p, q, e; - - function u24(i) { - return ib[i] | (ib[++i] << 8) | (ib[++i] << 16); - } - - function hash(x) { - return ((2654435769 * x) >> 19) & 8191; - } - - function literals(r, s) { - while (r >= 32) for (ob[o++] = 31, j = 32; j--; r--) ob[o++] = ib[s++]; - if (r) for (ob[o++] = r - 1; r--; ) ob[o++] = ib[s++]; - } - - while (i < b - 9) { - do { - r = ht[h = hash(s = u24(i))] || 0; - c = (d = (ht[h] = i) - r) < 8192 ? u24(r) : 0x1000000; - } while (i < b - 9 && i++ && s != c); - if (i >= b - 9) break; - if (--i > a) literals(i - a, a); - for (l = 0, p = r + 3, q = i + 3, e = b - q; l < e; l++) e *= ib[p + l] === ib[q + l]; - i += l; - for (--d; l > 262; l -= 262) ob[o++] = 224 + (d >> 8), ob[o++] = 253, ob[o++] = d & 255; - if (l < 7) ob[o++] = (l << 5) + (d >> 8), ob[o++] = d & 255; - else ob[o++] = 224 + (d >> 8), ob[o++] = l - 7, ob[o++] = d & 255; - ht[hash(u24(i))] = i++, ht[hash(u24(i))] = i++, a = i; - } - literals(b + 4 - a, a); - return bytesToHex(ob); - } - - /** - * Decompresses hex encoded data with the FastLZ LZ77 algorithm. - * @param {string} data A hex encoded string representing the compressed data. - * @returns {string} The decompressed result as a hex encoded string. - */ - LibZip.flzDecompress = function(data) { - var ib = hexToBytes(hexString(data)), i = 0, o = 0, l, f, t, r, h, ob = []; - while (i < ib.length) { - if (!(t = ib[i] >> 5)) { - for (l = 1 + ib[i++]; l--;) ob[o++] = ib[i++]; - } else { - f = 256 * (ib[i] & 31) + ib[i + 2 - (t = t < 7)]; - l = t ? 2 + (ib[i] >> 5) : 9 + ib[i + 1]; - i = i + 3 - t; - r = o - f - 1; - while (l--) ob[o++] = ob[r++]; - } - } - return bytesToHex(ob); - } - - /** - * Compresses hex encoded calldata. - * @param {string} data A hex encoded string representing the original data. - * @returns {string} The compressed result as a hex encoded string. - */ - LibZip.cdCompress = function(data) { - data = hexString(data); - var o = "0x", z = 0, y = 0, i = 0, c; - - function pushByte(b) { - o += byteToString(((o.length < 4 * 2 + 2) * 0xff) ^ b); - } - - function rle(v, d) { - pushByte(0x00); - pushByte(d - 1 + v * 0x80); - } - - for (; i < data.length; i += 2) { - c = parseByte(data, i); - if (!c) { - if (y) rle(1, y), y = 0; - if (++z === 0x80) rle(0, 0x80), z = 0; - continue; - } - if (c === 0xff) { - if (z) rle(0, z), z = 0; - if (++y === 0x20) rle(1, 0x20), y = 0; - continue; - } - if (y) rle(1, y), y = 0; - if (z) rle(0, z), z = 0; - pushByte(c); - } - if (y) rle(1, y), y = 0; - if (z) rle(0, z), z = 0; - return o; - } - - /** - * Decompresses hex encoded calldata. - * @param {string} data A hex encoded string representing the compressed data. - * @returns {string} The decompressed result as a hex encoded string. - */ - LibZip.cdDecompress = function(data) { - data = hexString(data); - var o = "0x", i = 0, j, c, s; - - while (i < data.length) { - c = ((i < 4 * 2) * 0xff) ^ parseByte(data, i); - i += 2; - if (!c) { - c = ((i < 4 * 2) * 0xff) ^ parseByte(data, i); - s = (c & 0x7f) + 1; - i += 2; - for (j = 0; j < s; ++j) o += byteToString((c >> 7 && j < 32) * 0xff); - continue; - } - o += byteToString(c); - } - return o; - } - - /*============================================================*/ - /* ERC1967Factory */ - /*============================================================*/ - - // See: https://github.com/vectorized/solady/blob/main/src/utils/ERC1967Factory.sol - - /** - * ERC1967Factory canonical address and ABI. - * @namespace - * @alias module:solady.ERC1967Factory - */ - var ERC1967Factory = {}; - - solady.ERC1967Factory = ERC1967Factory; - - /** - * Canonical address of Solady's ERC1967Factory. - * @type {string} - */ - ERC1967Factory.address = "0x0000000000006396FF2a80c067f99B3d2Ab4Df24"; - - /** - * ABI of Solady's ERC1967Factory. - * @type {Object} - */ - ERC1967Factory.abi = JSON.parse('[{0:[],1:"DeploymentFailed"96"SaltDoesNotStartWithCaller"96"Unauthorized"96"UpgradeFailed",2:3959790,9791],1:"AdminChanged",2:10959790,9792,9791],1:"Deployed",2:10959790,9792],1:"Upgraded",2:10},{0:[{90],1:"adminOf",12:[{9199{0:[{90,{91],1:"changeAdmin",12:[],13:"nonpayable",2:15},{0:[{92,{91],1:"deploy",12:[{9098,{0:[{92,{91,{94],1:"deployAndCall",12:[{9098,{0:[{92,{91,{93],1:"deployDeterministic",12:[{9098,{0:[{92,{91,{93,{94],1:"deployDeterministicAndCall",12:[{9098,{0:[],1:"initCodeHash",12:[{6:19,1:"result",2:19}99{0:[{93],1:"predictDeterministicAddress",12:[{6:7,1:"predicted",2:7}99{0:[{90,{92],1:"upgrade",12:[98,{0:[{90,{92,{94],1:"upgradeAndCall",12:[98]'.replace(/9\d/g, function (m) { return ["6:7,1:8,2:7}","6:7,1:9,2:7}","6:7,1:11,2:7}","6:19,1:20,2:19}","6:17,1:18,2:17}","},{4:false,0:[",",2:3},{0:[],1:","{5:true,","],13:16,2:15}","],13:14,2:15},"][m-90] }).replace(/\d+/g, function (m) { return '"' + ("inputs,name,type,error,anonymous,indexed,internalType,address,proxy,admin,event,implementation,outputs,stateMutability,view,function,payable,bytes,data,bytes32,salt".split(",")[m]) + '"' })); - - /*--------------------------- END ----------------------------*/ - - if (typeof define === "function" && define.amd) { - define("solady", [], function() { - return solady - }); - } - - if (!noGlobal) { - window.solady = solady; - } - - return solady; -}); diff --git a/grouperBot/lib/solady/js/solady.test.js b/grouperBot/lib/solady/js/solady.test.js deleted file mode 100644 index 7049b49..0000000 --- a/grouperBot/lib/solady/js/solady.test.js +++ /dev/null @@ -1,123 +0,0 @@ -var solady = require("./solady.js"); - -function test(msg, fn) { - msg = msg.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "").replace(/([^\.])$/, "$1."); - try { - fn(); - console.log("\x1b[32m[PASS]\x1b[0m", msg); - } catch (e) { - process.exitCode = 1; - console.error("\x1b[31m[FAIL]\x1b[0m", msg); - console.error(e.stack); - } -} - -function assert(cond, msg) { - if (!cond) throw new Error(msg); -} - -function assertEq(a, b) { - assert(a === b, "Assertion failed!\n Expected: " + b + "\n Actual: " + a); -} - -function expectRevert(fn) { - var hasRevert = false; - try { fn() } catch (e) { hasRevert = true } - assert(hasRevert, "Revert expected.\n" + fn); -} - -function randomData() { - var n = ~~(Math.random() * 2000); - var s = Math.random() < 0.5 ? "" : "0x"; - var g = Math.random() < 0.5 ? 0.45 : (Math.random() ? 0.99 : 0.999); - var h = g + 0.5 * (1.0 - g); - for (var i = 0; i < n; ++i) { - var r = Math.random(); - if (r < g) { - s += "00"; - } else if (r < h) { - s += "ff"; - } else { - var b = ((Math.random() * 0x100) & 0xff).toString(16); - s += b.length === 1 ? "0" + b : b; - } - } - return Math.random() < 0.5 ? s.toUpperCase() : s.toLowerCase(); -} - -function padRandomWhitespace(data) { - var before = ""; - var after = ""; - while (Math.random() < 0.5) before += Math.random() ? "\t" : " "; - while (Math.random() < 0.5) after += Math.random() ? "\t" : " "; - return before + data + after; -} - -function testCompressDecompress(compress, decompress) { - var totalDataLength = 0; - var totalCompressedLength = 0; - for (var t = 0; t < 1000; ++t) { - var data = randomData(); - var compressed = compress(padRandomWhitespace(data)); - var decompressed = decompress(padRandomWhitespace(compressed)); - totalDataLength += data.length; - totalCompressedLength += compressed.length; - assertEq(compressed.slice(0, 2), "0x"); - assertEq(decompressed.slice(0, 2), "0x"); - assertEq(decompressed.replace(/^0x/, ""), data.toLowerCase().replace(/^0x/, "")); - } - assert(totalCompressedLength < totalDataLength, "Compress not working as intended."); - - assertEq(compress(""), "0x"); - assertEq(compress("0x"), "0x"); - assertEq(decompress(""), "0x"); - assertEq(decompress("0x"), "0x"); - - function checkRevertOnInvalidInputs(fn) { - expectRevert(function () { fn("hehe") }); - expectRevert(function () { fn("0xa") }); - expectRevert(function () { fn("0xas") }); - expectRevert(function () { fn(123) }); - expectRevert(function () { fn(false) }); - expectRevert(function () { fn(null) }); - expectRevert(function () { fn(undefined) }); - expectRevert(function () { fn([]) }); - expectRevert(function () { fn({}) }); - } - - checkRevertOnInvalidInputs(compress); - checkRevertOnInvalidInputs(decompress); -} - -test("LibZip: FastLZ compress / decompress.", function() { - testCompressDecompress(solady.LibZip.flzCompress, solady.LibZip.flzDecompress); -}); - -test("LibZip: Calldata compress / decompress.", function() { - testCompressDecompress(solady.LibZip.cdCompress, solady.LibZip.cdDecompress); -}); - -test("LibZip: Calldata compress", function() { - var data = "0xac9650d80000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000a40c49ccbe000000000000000000000000000000000000000000000000000000000005b70e00000000000000000000000000000000000000000000000000000dfc79825feb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000645c48a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084fc6f7865000000000000000000000000000000000000000000000000000000000005b70e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f1cdf1a632eaaab40d1c263edf49faf749010a1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064df2ab5bb0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f1cdf1a632eaaab40d1c263edf49faf749010a100000000000000000000000000000000000000000000000000000000"; - var expected = "0x5369af27001e20001e04001e80001d0160001d0220001d02a0001ea40c49ccbe001c05b70e00190dfc79825feb005b645c48a7003a84fc6f7865001c05b70e002f008f000f008f003a4449404b7c002b1f1cdf1a632eaaab40d1c263edf49faf749010a1003a64df2ab5bb000b7f5c764cbc14f9669b88837ca1490cca17c31607002b1f1cdf1a632eaaab40d1c263edf49faf749010a1001b"; - assertEq(solady.LibZip.cdCompress(data), expected); -}); - -test("LibZip: Calldata decompress on invalid input", function() { - var data = "0xffffffff00ff"; - var expected = "0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - assertEq(solady.LibZip.cdDecompress(data), expected); -}); - -test("ERC1967Factory: ABI and address", function() { - function hashFnv32a(s) { - var h = 0x811c9dc5; - for (var i = 0; i < s.length; i++) { - h ^= s.charCodeAt(i); - h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24); - } - return h >>> 0; - } - assertEq(hashFnv32a(JSON.stringify(solady.ERC1967Factory.abi)), 1277805820); - assertEq(solady.ERC1967Factory.address, "0x0000000000006396FF2a80c067f99B3d2Ab4Df24"); -}); diff --git a/grouperBot/lib/solady/logo.svg b/grouperBot/lib/solady/logo.svg deleted file mode 100644 index 8589e73..0000000 --- a/grouperBot/lib/solady/logo.svg +++ /dev/null @@ -1 +0,0 @@ -solady diff --git a/grouperBot/lib/solady/package-lock.json b/grouperBot/lib/solady/package-lock.json deleted file mode 100644 index e58c913..0000000 --- a/grouperBot/lib/solady/package-lock.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "solady", - "version": "0.0.55", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "solady", - "version": "0.0.55", - "license": "MIT" - } - } -} diff --git a/grouperBot/lib/solady/package.json b/grouperBot/lib/solady/package.json deleted file mode 100644 index 48205b3..0000000 --- a/grouperBot/lib/solady/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "solady", - "license": "MIT", - "version": "0.1.26", - "description": "Optimized Solidity snippets.", - "files": [ - "src/**/*.sol", - "js/**/*" - ], - "main": "js/solady.js", - "module": "js/solady.js", - "types": "js/solady.d.ts", - "repository": { - "type": "git", - "url": "git+https://github.com/vectorized/solady.git" - } -} diff --git a/grouperBot/lib/solady/prep/all.js b/grouperBot/lib/solady/prep/all.js deleted file mode 100644 index 52ef3f9..0000000 --- a/grouperBot/lib/solady/prep/all.js +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env node -const path = require('path'); -const { runCommandSync } = require('./common.js'); - -async function main() { - const scripts = [ - 'gen-efficient-hash-lib.js', - 'gen-enumerable-map-lib.js', - 'gen-safe-cast-lib.js', - 'gen-globalized-libs.js', - 'remove-trailing-whitespace.js' - ]; - const jsRuntime = process.argv[0]; - scripts.forEach(scriptRelPath => { - const absScriptPath = path.join(__dirname, scriptRelPath); - console.log('Running:', scriptRelPath); - const scriptOutput = runCommandSync(jsRuntime, [absScriptPath]); - console.log(scriptOutput); - }); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/common.js b/grouperBot/lib/solady/prep/common.js deleted file mode 100644 index 713ab2e..0000000 --- a/grouperBot/lib/solady/prep/common.js +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env node -const fs = require('fs'); -const path = require('path'); -const { spawnSync, execSync } = require('child_process'); - -const normalizeNewlines = s => s.replace(/\n(\n\s*)+/g, '\n\n'); - -const hexNoPrefix = x => x.toString(16).replace(/^0[xX]/, ''); - -const readSync = srcPath => - fs.existsSync(srcPath) ? fs.readFileSync(srcPath, { encoding: 'utf8', flag: 'r' }) : ''; - -const runCommandSync = (command, args) => { - const result = spawnSync(command, args, { encoding:'utf-8' }); - if (result.error) { - console.error('Error executing command:', result.error.message); - } else { - return result.stdout; - } -}; - -const hasAnyPathSequence = (srcPath, paths) => { - const d = '\0', norm = p => d + path.normalize(p).split(path.sep).join(d) + d; - return paths.some(p => norm(srcPath).indexOf(norm(p)) !== -1); -}; - -const genSectionRegex = name => - new RegExp( - '(\\s*\\/\\*\\S+?\\*\\/\\s*\\/\\*\\s+' + - name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + - '\\s+\\*\\/\\s*\\/\\*\\S+?\\*\\/)[\\s\\S]+?(\\/\\*\\S+?\\*\\/)' - ); - -const writeSync = (srcPath, src) => { - const dir = path.dirname(srcPath); - if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); - fs.writeFileSync(srcPath, src); -}; - -const writeAndFmtSync = (srcPath, src) => { - writeSync(srcPath, src); - runCommandSync('forge', ['fmt', srcPath]); -}; - -const walkSync = (dir, callback) => { - fs.readdirSync(dir).forEach(file => { - const srcPath = path.join(dir, file); - const stats = fs.statSync(srcPath); - stats.isDirectory() ? walkSync(srcPath, callback) : stats.isFile() && callback(srcPath, stats); - }); -}; - -const forEachWalkSync = (dirs, callback) => { - dirs.forEach(dir => walkSync(dir, callback)); -}; - -const readSolWithLineLengthSync = (srcPath, lineLength) => { - const tmpDir = path.join(__dirname, 'out', ('__t' + Math.random()).replace(/\./g, '_')); - writeSync( - path.resolve(path.join(tmpDir, 'foundry.toml')), - fs.readFileSync(path.resolve('foundry.toml'), 'utf8') - .replace(/line_length\s*=\s*\d+/g, 'line_length = ' + lineLength) - ); - fs.copyFileSync(srcPath, path.join(tmpDir, 'x.sol')); - execSync('forge fmt x.sol', { cwd: tmpDir, stdio: 'inherit' }); - const content = fs.readFileSync(path.join(tmpDir, 'x.sol'), 'utf8'); - fs.rmSync(tmpDir, { recursive: true, force: true }); - return content; -}; - -module.exports = { - genSectionRegex, - hexNoPrefix, - hasAnyPathSequence, - normalizeNewlines, - readSync, - runCommandSync, - writeSync, - writeAndFmtSync, - walkSync, - forEachWalkSync, - readSolWithLineLengthSync -}; diff --git a/grouperBot/lib/solady/prep/eof-compat-analysis.js b/grouperBot/lib/solady/prep/eof-compat-analysis.js deleted file mode 100644 index 5c2f23b..0000000 --- a/grouperBot/lib/solady/prep/eof-compat-analysis.js +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env node -const { readSync, forEachWalkSync } = require('./common.js'); -const { execSync } = require('child_process'); - -async function main() { - const getLastModifiedGitTimestamp = (filePath) => { - try { - const output = execSync(`git log -1 --format=%ct -- ${filePath}`, { encoding: 'utf-8' }); - return ~~output.trim(); - } catch (error) { - return null; - } - }; - - let eofBannedOpcodes = [ - 'codesize', 'codecopy', - 'extcodesize', 'extcodecopy', 'extcodehash', - 'jump', 'pc', - 'gas', 'gaslimit', 'gasprice', - 'create', 'create2', - 'call', 'staticcall', 'delegatecall', - 'selfdestruct', 'callcode' - ]; - - let specialPatterns = [ - {name: 'returndatacopyOGG', reStr: 'returndatacopy\\([\\s\\S]*?,[\\s\\S]*?returndatasize'} - ] - - let flattenedPathsAndScores = []; - - forEachWalkSync(['src'], srcPath => { - if (!srcPath.match(/\.sol$/i) || srcPath.match(/\/(g|legacy)\//)) return; - - const src = readSync(srcPath); - const numMatches = reStr => (src.match(new RegExp(reStr, 'g')) || []).length; - let totalScore = 0; - let scores = {}; - let redundantGasCount = 0; - eofBannedOpcodes.forEach(opcode => { - const score = numMatches('[^a-zA-z]' + opcode + '\\('); - if (opcode.match(/call$/)) { - redundantGasCount += numMatches('[^a-zA-z]' + opcode + '\\([\\S\\s]*?gas\\s*?\\('); - } - totalScore += score; - scores[opcode] = score; - }); - specialPatterns.forEach(c => { - const score = numMatches(c.reStr); - totalScore += score; - scores[c.name] = score; - }); - if (redundantGasCount) scores['gas'] -= redundantGasCount; - for (const key in scores) if (scores[key] === 0) delete scores[key]; - const lastModifiedGitTimestamp = getLastModifiedGitTimestamp(srcPath); - flattenedPathsAndScores.push({srcPath, scores, totalScore, lastModifiedGitTimestamp}); - }); - - flattenedPathsAndScores.sort((a, b) => a.totalScore - b.totalScore); - flattenedPathsAndScores.forEach(x => { - if (x.totalScore === 0) delete x.scores; - delete x.totalScore; - }); - console.log(JSON.stringify(flattenedPathsAndScores, null, 4)); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/gen-docs.js b/grouperBot/lib/solady/prep/gen-docs.js deleted file mode 100644 index e18c146..0000000 --- a/grouperBot/lib/solady/prep/gen-docs.js +++ /dev/null @@ -1,281 +0,0 @@ -#!/usr/bin/env node -const { - readSync, - writeSync, - forEachWalkSync, - hasAnyPathSequence, - readSolWithLineLengthSync, - normalizeNewlines -} = require('./common.js'); -const path = require('path'); - -async function main() { - const pathSequencesToIgnore = ['g', 'ext', 'legacy']; - - const cleanForRegex = s => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - - const makeTagRegex = tag => new RegExp( - '()([\s\S]*?)' + - '()' - ); - - const has = (a, b) => a.toLowerCase().indexOf(b.toLowerCase()) !== -1; - - const strip = s => s.replace(/^\s+|\s+$/g, ''); - - const replaceInTag = (s, tag, replacement) => - s.replace( - makeTagRegex(tag), - (m0, m1, m2, m3) => m1 + '\n' + strip(replacement) + '\n' + m3 - ); - - const getTag = (s, tag) => { - const m = s.match(makeTagRegex(tag)); - if (m === null) return '' + ''; - return m[0]; - }; - - const coalesce = (m, f) => m === null ? '' : f(m); - - const toHeaderCase = str => - strip(str).toLowerCase() - .replace(/(eth|sha|lz|uups|(eip|rip|erc|push|create)\-?[0-9]+i?)/g, m => m.toUpperCase()) - .split(/\s+/) - .map(w => w.replace(/^([a-zA-Z])/, c => c.toUpperCase())) - .join(' '); - - const deindent = s => s.replace(/^ {4}/gm, ''); - - const getFunctionSig = s => coalesce( - s.match(/(\w+)\s*\(([^)]*)\)/), - m => m[1] + '(' + m[2].split(',').map(x => strip(x).split(/\s+/)[0]) + ')' - ); - - const cleanNatspecOrNote = s => deindent(strip( - s.replace(/\s+\/\/\/?/g, '\n') - .replace(/\s?\n\s?/g, ' \n') - .replace(/```([\s\S]+?)```/g, '```solidity$1```') - .replace(/^\/\/\/\s+@[a-z]+\s?/, '') - .replace(/\n\s*?((?:Note|Requirement)s?)\:[\s\/]*?(\-)/gi, '\n\n$1:\n\n$2') - .replace(/\n\s*?(Emits)/gi, '\n\n$1') - .replace(/\{([A-Za-z0-9\-]+)\}/g, '`$1`') - )); - - const getSections = s => { - const sectionHeaderRe = /\/\*\S+?\*\/\s*\/\*([^*]{60})\*\/\s*\/\*\S+?\*\//g; - let a = [], l = null; - for (let m = null; (m = sectionHeaderRe.exec(s)) !== null; l = m) { - if (l !== null) { - a.push({ - h2: toHeaderCase(l[1]), - src: s.slice(l.index + l[0].length, m.index) - }); - } - } - if (l !== null) { - a.push({ - h2: toHeaderCase(l[1]), - src: s.slice(l.index + l[0].length) - }); - } - return a - .filter(x => !has(x.h2, 'private')) - .map(item => { - const m = item.src.match(/^((\s+\/\/\s[^\n]+)+)/); - if (m) item.note = cleanNatspecOrNote(m[0]); - return item; - }); - }; - - const getSubSections = (s, r) => { - let a = []; - for (let m = null; (m = r.exec(s)) !== null; ) { - if (!has(m[2], '///') && !/\sprivate\s/.test(m[2])) a.push(m); - } - return a; - } - - const getFunctionsAndModifiers = s => - getSubSections(s, /((?:\/\/\/\s[^\n]+\n\s*?)+)((?:function|fallback|receive|modifier)[^{]+)/g) - .map(m => ({ - natspec: cleanNatspecOrNote(m[1]), - def: deindent(strip(m[2])), - h3: getFunctionSig(deindent(strip(m[2]))) - })); - - const getConstantsAndImmutables = s => - getSubSections(s, /((?:\/\/\/\s[^\n]+\n\s*?)+)((?:bytes|uint|address)[0-9]*\s+(?:public|internal)\s+(?:immutable|constant)\s+([A-Za-z0-9_]+)[^;]*)/g) - .map(m => ({ - natspec: cleanNatspecOrNote(m[1]), - def: deindent(strip(m[2])), - h3: deindent(strip(m[3])) - })); - - const getCustomErrors = s => - getSubSections(s, /((?:\/\/\/\s[^\n]+\n\s*?)+)(error\s[^;]+);/g) - .map(m => ({ - natspec: cleanNatspecOrNote(m[1]), - def: deindent(strip(m[2])), - h3: getFunctionSig(deindent(strip(m[2]))) - })); - - const getEvents = s => - getSubSections(s, /((?:\/\/\/\s[^\n]+\n\s*?)+)(event\s[^;]+);/g) - .map(m => ({ - natspec: cleanNatspecOrNote(m[1]), - def: deindent(strip(m[2])), - h3: getFunctionSig(deindent(strip(m[2]))) - })); - - const getStructsAndEnums = s => - getSubSections(s, /((?:\/\/\/\s[^\n]+\n\s*?)+)((?:struct|enum)\s([A-Za-z0-9_]+)\s+\{[^}]+})/g) - .map(m => ({ - natspec: cleanNatspecOrNote(m[1]), - def: deindent(strip(m[2])), - h3: deindent(strip(m[3])) - })); - - const getNotice = s => coalesce( - s.match(/\/\/\/\s+@notice\s+([\s\S]+?)\/\/\/\s?@author/), - m => m[1].replace(/\n\/\/\//g, '') - ); - - const getImports = (s, srcPath) => { - const r = /import\s[\s\S]*?(["'][\s\S]+?["'])/g; - let a = []; - for (let m = null; (m = r.exec(s)) !== null; ) { - const p = path.normalize(path.join(path.dirname(srcPath), m[1].slice(1, -1))); - a.push(p.split(path.sep).slice(-2).join(path.sep)); - } - return a; - }; - - const getTopIntro = s => coalesce( - s.match(/\/\/\/\s+@notice\s+[\s\S]+?(?:\/\/\/\s?@author\s+[\s\S]+?\n|\/\/\/\s+\([\s\S]+?\)\n)+([\s\S]*?)(?:library|abstract\s+contract|contract)\s[^.]+\{/), - m => normalizeNewlines(strip( - m[1].replace('\n\n', '\n\n\n').split('\n') - .map(l => l - .replace(/(\d\d)\:(\d\d)\:/g, '$1:$2:') - .replace(/^\/{2,3}\s{2,3}([1-9][0-9]*?)\.\s/, ' $1. ') - .replace(/^\/{2,3}\s*/, '') - .replace(/^(-\s+[\s\S]{1,64})\:/, '$1:') - .replace(/^@dev\s?([\s\S]+?)\:/, '$1:\n\n') - .replace(/^Note\:/, 'Note:\n\n') - .replace(/^[\s\S]{1,64}\:/, m => has(m, 'http') ? m : '' + m + '') - ).join('\n') - .replace(/\.\n\([\s\S]+?)\:\<\/b\>/, '. $1:') - .replace(/@dev\s/g, '') - .replace(/\-{32,}\s?\+\s*?([\s\S]+)\-{32,}\s?\+/g, (m0, m1) => { - const lines = strip(m1.replace(/\-+\s*$/g, '')).split('\n'); - const n = Math.max.apply(null, lines.map(l => l.split('|').map(strip).filter(c => c.length).length)); - const h = '|' + Array(n + 1).join(' -- |'); - return '\n\n' + lines.map(l => l.match(/\-{32,}\s?\|/) ? h : '| ' + l).join('\n') + '\n\n'; - }) - )) - ); - - const getInherits = (s, srcPath) => coalesce( - s.match(/contract\s+[A-Za-z0-9_]+\s+is\s+([^\{]*?)\s*\{/), - m => 'Inherits: \n\n' + - m[1].split(',').map(strip).map(p => - getImports(s, srcPath).map(q => has(q, p) ? '- `' + q + '` \n' : '').join('') - ).join('') - ); - - const getSrcDir = srcPath => srcPath.split(path.sep).slice(-2)[0]; - const getTitle = srcPath => path.parse(srcPath).name; - const getDocSubPath = srcPath => path.join(getSrcDir(srcPath), getTitle(srcPath).toLowerCase() + '.md'); - const getDocPath = srcPath => path.join('docs', getDocSubPath(srcPath)); - - let docSrcPaths = []; - - forEachWalkSync(['src'], srcPath => { - if (!srcPath.match(/\.sol$/i)) return; - if (hasAnyPathSequence(srcPath, pathSequencesToIgnore)) return; - if (has(srcPath, 'Milady.sol')) return; - console.log(srcPath); - - let src = readSolWithLineLengthSync(srcPath, 80); - let sections = getSections(src); - - if (sections.length < 1) { - src = src.replace( - /(library|contract)\s[\s\S]*?\{/, - m => m + - '/*============================================================*/\n' + - '/* FUNCTIONS */\n' + - '/*============================================================*/\n' - ); - sections = getSections(src); - } - - const docHeader = '# ' + getTitle(srcPath) + '\n\n' + getNotice(src); - let docChunks = []; - sections.forEach(x => - [ - getStructsAndEnums, - getCustomErrors, - getEvents, - getFunctionsAndModifiers, - getConstantsAndImmutables - ] - .reduce((acc, f) => acc.length ? acc : f(x.src), []) - .forEach((y, i) => - docChunks.push( - ...(i ? [] : ['## ' + x.h2, ...(x.note ? [x.note] : [])]), - '### ' + y.h3, - '```solidity\n' + y.def + '\n```', - y.natspec - ) - ) - ); - - if (docChunks.length) { - writeSync( - getDocPath(srcPath), - [ - docHeader, - getTopIntro(src), - getInherits(src, srcPath), - getTag(readSync(getDocPath(srcPath)), 'customintro'), - docChunks.join('\n\n') - ].join('\n\n') - ); - docSrcPaths.push(srcPath); - } - }); - - if (docSrcPaths.length) { - docSrcPaths.forEach(p => { - writeSync( - getDocPath(p), - readSync(getDocPath(p)) - .replace(/((?:See\:)?\s)`([A-Za-z0-9\/]+?\.sol)`/ig, (m0, m1, m2) => { - if (!m0.match(/^See\:/i) && !m2.match(/\.sol$/i)) return m0; - let l = docSrcPaths.filter(q => has(q, getTitle(m2))); - return l.length ? m1 + '[`' + m2 + '`](' + getDocSubPath(l[0]) + ')' : m0; - }) - ); - }); - const sidebarDocPath = path.join('docs', 'sidebar.md'); - writeSync( - sidebarDocPath, - replaceInTag( - readSync(sidebarDocPath), - 'gen', - [...new Set(docSrcPaths.map(getSrcDir))] - .map(dir => '- ' + dir + '\n' + - docSrcPaths - .filter(p => getSrcDir(p) === dir) - .map(p => ' - [' + getTitle(p) + '](' + getDocSubPath(p) + ')') - .join('\n') - ).join('\n') - ) - ); - } -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/gen-efficient-hash-lib.js b/grouperBot/lib/solady/prep/gen-efficient-hash-lib.js deleted file mode 100644 index 79ceca8..0000000 --- a/grouperBot/lib/solady/prep/gen-efficient-hash-lib.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node -const { genSectionRegex, readSync, writeAndFmtSync, normalizeNewlines, hexNoPrefix } = require('./common.js'); - -async function main() { - const srcPath = 'src/utils/EfficientHashLib.sol'; - const maxDepth = 14; - let src = readSync(srcPath); - - const genHashDef = (t, n) => { - let s = '/// @dev Returns `keccak256(abi.encode('; - let a = []; - for (let i = 0; i < n; ++i) a.push(t + ' v' + i); - let b = (n > 4 ? [a[0], '..', a[n - 1]] : a).join(', '); - s += b.replace(new RegExp(t + ' ', 'g'), ''); - s += '))`.\nfunction hash(' + a.join(', '); - s += ') internal pure returns (bytes32 result) {\n'; - s += '/// @solidity memory-safe-assembly\nassembly {\n'; - if (n == 1) { - s += 'mstore(0x00, v0)\nresult := keccak256(0x00, 0x20)}}\n' - } else if (n == 2) { - s += 'mstore(0x00, v0)\nmstore(0x20, v1)\nresult := keccak256(0x00, 0x40)}}\n' - } else { - s += 'let m := mload(0x40)\nmstore(m, v0)\n'; - for (let i = 1; i < n; ++i) { - s += 'mstore(add(m, 0x' + hexNoPrefix(i << 5) + '), v' + i + ')\n'; - } - s += 'result := keccak256(m, 0x' + hexNoPrefix(n << 5) +')}}\n'; - } - return s; - }; - - src = src.replace( - genSectionRegex('MALLOC-LESS HASHING OPERATIONS'), - (m0, m1, m2) => { - let chunks = [m1]; - for (let i = 1; i <= maxDepth; ++i) { - chunks.push(genHashDef('bytes32', i)); - chunks.push(genHashDef('uint256', i)); - } - chunks.push(m2); - return normalizeNewlines(chunks.join('\n\n\n')); - } - ); - writeAndFmtSync(srcPath, src); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/gen-enumerable-map-lib.js b/grouperBot/lib/solady/prep/gen-enumerable-map-lib.js deleted file mode 100644 index 5d32be2..0000000 --- a/grouperBot/lib/solady/prep/gen-enumerable-map-lib.js +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env node -const { genSectionRegex, readSync, writeAndFmtSync, normalizeNewlines, hexNoPrefix } = require('./common.js'); - -async function main() { - const srcPath = 'src/utils/EnumerableMapLib.sol'; - const maxDepth = 14; - let src = readSync(srcPath); - - const capitalize = s => s.charAt(0).toUpperCase() + s.slice(1); - - const mapType = (f, t) => capitalize(f) + 'To' + capitalize(t) + 'Map'; - - const crossForEach = (a, fn) => a.forEach(x => a.forEach(y => fn(x, y))); - - const genStructDef = (f, t) => { - return '/// @dev An enumerable map of `' + f + '` to `' + t + '`.\n' + - 'struct ' + mapType(f, t) + '{\n' + - 'EnumerableSetLib.' + capitalize(f) + 'Set _keys;\n' + - 'mapping(' + f + ' => ' + t + ') _values;\n}\n\n'; - }; - - const genGettersAndSettersDef = (f, t) => { - const mt = mapType(f, t); - let s = '/// @dev Adds a key-value pair to the map, or updates the value for an existing key.\n'; - s += '/// Returns true if `key` was added to the map, that is if it was not already present.\n'; - s += 'function set(' + mt + ' storage map, ' + f + ' key, ' + t + ' value) internal returns (bool) {\n'; - s += 'map._values[key] = value;\nreturn EnumerableSetLib.add(map._keys, key);\n}\n\n'; - - s += '/// @dev Adds a key-value pair to the map, or updates the value for an existing key.\n'; - s += '/// Returns true if `key` was added to the map, that is if it was not already present.\n'; - s += '/// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`.\n'; - s += 'function set(' + mt + ' storage map, ' + f + ' key, ' + t + ' value, uint256 cap) internal returns (bool) {\n'; - s += 'map._values[key] = value;\nreturn EnumerableSetLib.add(map._keys, key, cap);\n}\n\n'; - - s += '/// @dev Removes a key-value pair from the map.\n'; - s += '/// Returns true if `key` was removed from the map, that is if it was present.\n'; - s += 'function remove(' + mt + ' storage map, ' + f + ' key) internal returns (bool) {\n'; - s += 'delete map._values[key];\nreturn EnumerableSetLib.remove(map._keys, key);\n}\n\n'; - - s += '/// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`.\n' - s += 'function update(' + mt + ' storage map, ' + f + ' key, ' + t + ' value, bool isAdd, uint256 cap) internal returns (bool) {\n'; - s += 'return isAdd ? set(map, key, value, cap) : remove(map, key);\n}\n\n'; - - s += '/// @dev Returns true if the key is in the map.\n'; - s += 'function contains(' + mt + ' storage map, ' + f + ' key) internal view returns (bool) {\n'; - s += 'return EnumerableSetLib.contains(map._keys, key);\n}\n\n'; - - s += '/// @dev Returns the number of key-value pairs in the map.\n'; - s += 'function length(' + mt + ' storage map) internal view returns (uint256) {\n'; - s += 'return EnumerableSetLib.length(map._keys);\n}\n\n'; - - s += '/// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds.\n'; - s += 'function at(' + mt + ' storage map, uint256 i)' - s += 'internal view returns (' + f + ' key, ' + t + ' value) {\n'; - s += 'value = map._values[key = EnumerableSetLib.at(map._keys, i)];\n}\n\n'; - - s += '/// @dev Tries to return the value associated with the key.\n'; - s += 'function tryGet(' + mt + ' storage map, ' + f + ' key)' - s += 'internal view returns (bool exists, ' + t + ' value) {\n'; - s += 'exists = (value = map._values[key]) != ' + t + '(0) || contains(map, key);\n}\n\n'; - - s += '/// @dev Returns the value for the key. Reverts if the key is not found.\n'; - s += 'function get(' + mt + ' storage map, ' + f + ' key)' - s += 'internal view returns (' + t + ' value)\n{\n'; - s += 'if ((value = map._values[key]) == ' + t + '(0)) if (!contains(map, key)) _revertNotFound();\n}\n\n'; - - s += '/// @dev Returns the keys. May run out-of-gas if the map is too big.\n'; - s += 'function keys(' + mt + ' storage map) internal view returns (' + f + '[] memory) {\n'; - s += 'return EnumerableSetLib.values(map._keys);\n}\n\n'; - return s; - } - - const types = ['bytes32', 'uint256', 'address']; - - src = src.replace( - genSectionRegex('STRUCTS'), - (m0, m1, m2) => { - let chunks = [m1]; - crossForEach(types, (f, t) => chunks.push(genStructDef(f, t))); - chunks.push(m2); - return normalizeNewlines(chunks.join('\n\n\n')); - } - ).replace( - genSectionRegex('GETTERS / SETTERS'), - (m0, m1, m2) => { - let chunks = [m1]; - crossForEach(types, (f, t) => chunks.push(genGettersAndSettersDef(f, t))); - chunks.push(m2); - return normalizeNewlines(chunks.join('\n\n\n')); - } - ); - writeAndFmtSync(srcPath, src); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/gen-globalized-libs.js b/grouperBot/lib/solady/prep/gen-globalized-libs.js deleted file mode 100644 index 9fbe9b2..0000000 --- a/grouperBot/lib/solady/prep/gen-globalized-libs.js +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env node -const { hasAnyPathSequence, readSync, writeSync, forEachWalkSync } = require('./common.js'); - -async function main() { - const pathSequencesToIgnore = ['g', 'utils/ext/ithaca']; - - forEachWalkSync(['src/utils'], srcPath => { - if (!srcPath.match(/\.sol$/i)) return; - if (hasAnyPathSequence(srcPath, pathSequencesToIgnore)) return; - - let src = readSync(srcPath); - const libraryStartMatch = src.match(/library\s+([A-Za-z0-9]+)\s+\{/); - if (!libraryStartMatch) return; - - let structsSrc = '', usings = []; - src = src.replace( - /\s*\/\*\S+?\*\/\s*\/\*\s+STRUCTS?\s+\*\/\s*\/\*\S+?\*\/([\s\S]+?struct\s+[A-Za-z0-9]+\s+\{[\s\S]+?\})+/, - m => (structsSrc = m, '') - ); - - for (let m, r = /struct\s+([A-Za-z0-9]+)\s+\{/g; m = r.exec(structsSrc); ) { - usings.push('using ' + libraryStartMatch[1] + ' for ' + m[1] + ' global;'); - } - if (usings.length === 0 || structsSrc === '') return; - - const dstPath = srcPath.replace(/([A-Za-z0-9]+\.sol)/, 'g/$1'); - console.log(dstPath); - writeSync( - dstPath, - src.replace( - /pragma\s+solidity\s+\^0\.8\.\d+;/, - [ - 'pragma solidity ^0.8.13;', - '// This file is auto-generated.', - structsSrc.replace(/\n /g, '\n').replace(/^\s*\n+|\n+\s*$/g, ''), - usings.join('\n').replace(/^\s*\n+|\n+\s*$/g, '') - ].join('\n\n') - ) - .replace(/(https\:\/\/\S+?\/solady\/\S+?\/)([A-Za-z0-9]+\.sol)/, '$1g/$2') - .replace(/(import\s[\s\S]*?["'])\.\/([\s\S]+?["'])/g, '$1../$2') - .replace(/(library\s+([A-Za-z0-9]+)\s+\{\n)\n*/, '$1') - ); - }); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/gen-safe-cast-lib.js b/grouperBot/lib/solady/prep/gen-safe-cast-lib.js deleted file mode 100644 index 2ca760e..0000000 --- a/grouperBot/lib/solady/prep/gen-safe-cast-lib.js +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env node -const { genSectionRegex, readSync, writeAndFmtSync, normalizeNewlines, hexNoPrefix } = require('./common.js'); - -async function main() { - const srcPath = 'src/utils/SafeCastLib.sol'; - let src = readSync(srcPath); - - const genUint256ToUintXCastDef = i => { - const n = i * 8; - let s = '/// @dev Casts `x` to a uint' + n + '. Reverts on overflow.\n' - s += 'function toUint' + n + '(uint256 x) internal pure returns (uint' + n + ') {'; - s += 'if (x >= 1 << ' + n + ') _revertOverflow();' - s += 'return uint' + n + '(x);}\n'; - return s; - }; - - const genInt256ToIntXCastDef = i => { - const n = i * 8; - const m = n - 1; - let s = '/// @dev Casts `x` to a int' + n + '. Reverts on overflow.\n' - s += 'function toInt' + n + '(int256 x) internal pure returns (int' + n + ') {'; - s += 'unchecked {'; - s += 'if (((1 << ' + m + ') + uint256(x)) >> ' + n + ' == uint256(0)) return int' + n + '(x);'; - s += '_revertOverflow();}}\n'; - return s; - }; - - const genUInt256ToIntXCastDef = i => { - const n = i * 8; - const m = n - 1; - let s = '/// @dev Casts `x` to a int' + n + '. Reverts on overflow.\n' - s += 'function toInt' + n + '(uint256 x) internal pure returns (int' + n + ') {'; - s += 'if (x >= 1 << ' + m + ') _revertOverflow();'; - s += 'return int' + n + '(int256(x));}\n'; - return s; - }; - - src = src.replace( - genSectionRegex('UNSIGNED INTEGER SAFE CASTING OPERATIONS'), - (m0, m1, m2) => { - let chunks = [m1]; - for (let i = 1; i <= 31; ++i) { - chunks.push(genUint256ToUintXCastDef(i)); - } - chunks.push(m2); - return normalizeNewlines(chunks.join('\n\n\n')); - } - ).replace( - genSectionRegex('SIGNED INTEGER SAFE CASTING OPERATIONS'), - (m0, m1, m2) => { - let chunks = [m1]; - for (let i = 1; i <= 31; ++i) { - chunks.push(genInt256ToIntXCastDef(i)); - } - chunks.push(m2); - return normalizeNewlines(chunks.join('\n\n\n')); - } - ).replace( - genSectionRegex('OTHER SAFE CASTING OPERATIONS'), - (m0, m1, m2) => { - let chunks = [m1]; - for (let i = 1; i <= 31; ++i) { - chunks.push(genUInt256ToIntXCastDef(i)); - } - chunks.push( - '/// @dev Casts `x` to a int256. Reverts on overflow.\n' + - 'function toInt256(uint256 x) internal pure returns (int256) {' + - 'if (int256(x) >= 0) return int256(x);'+ - '_revertOverflow();}' - ); - chunks.push( - '/// @dev Casts `x` to a uint256. Reverts on overflow.\n' + - 'function toUint256(int256 x) internal pure returns (uint256) {' + - 'if (x >= 0) return uint256(x);'+ - '_revertOverflow();}' - ); - chunks.push(m2); - return normalizeNewlines(chunks.join('\n\n\n')); - } - ); - writeAndFmtSync(srcPath, src); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/memory-safe-scan.js b/grouperBot/lib/solady/prep/memory-safe-scan.js deleted file mode 100644 index c63c3ed..0000000 --- a/grouperBot/lib/solady/prep/memory-safe-scan.js +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env node -const { readSync, forEachWalkSync, hasAnyPathSequence } = require('./common.js'); - -async function main() { - const pathSequencesToIgnore = ['g', 'legacy']; - - const loggedSrcPaths = []; - forEachWalkSync(['src'], srcPath => { - if (!srcPath.match(/\.sol$/i)) return; - if (hasAnyPathSequence(srcPath, pathSequencesToIgnore)) return; - - const src = readSync(srcPath); - const assemblyTagRe = /(\/\/\/\s*?@solidity\s*?memory-safe-assembly\s+?)?assembly\s*?(\(.*?\))?\{/gm; - for (let m = null; (m = assemblyTagRe.exec(src)) !== null; ) { - if ((m[0] + '').indexOf('memory-safe') === -1) { - if (loggedSrcPaths.indexOf(srcPath) === -1) { - loggedSrcPaths.push(srcPath); - console.log(srcPath + ':'); - } - console.log(' line:', src.slice(0, m.index).split(/\n/).length); - } - } - }); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/remove-trailing-whitespace.js b/grouperBot/lib/solady/prep/remove-trailing-whitespace.js deleted file mode 100644 index 0e42f30..0000000 --- a/grouperBot/lib/solady/prep/remove-trailing-whitespace.js +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node -const { readSync, writeSync, forEachWalkSync } = require('./common.js'); - -async function main() { - forEachWalkSync(['src'], srcPath => { - if (!srcPath.match(/\.sol$/i)) return; - const src = readSync(srcPath); - const cleanedSrc = src.split('\n').map(l => l.replace(/\s+$/, '')).join('\n'); - if (src !== cleanedSrc) writeSync(srcPath, src); - }); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/prep/zksync-compat-analysis.js b/grouperBot/lib/solady/prep/zksync-compat-analysis.js deleted file mode 100644 index 9c19486..0000000 --- a/grouperBot/lib/solady/prep/zksync-compat-analysis.js +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env node -const { readSync, forEachWalkSync } = require('./common.js'); -const { execSync } = require('child_process'); - -async function main() { - const getLastModifiedGitTimestamp = (filePath) => { - try { - const output = execSync(`git log -1 --format=%ct -- ${filePath}`, { encoding: 'utf-8' }); - return ~~output.trim(); - } catch (error) { - return null; - } - }; - - let zkSyncIncompatOpcodes = [ - 'codecopy', 'extcodecopy' - ]; - - let specialPatterns = [ - {name: 'precompile4', reStr: 'staticcall\\([^,]*?,\\s*?(0x0*)?4'} - ] - - let flattenedPathsAndScores = []; - - forEachWalkSync(['src'], srcPath => { - if (!srcPath.match(/\.sol$/i) || srcPath.match(/\/(g|legacy)\//)) return; - - const src = readSync(srcPath); - const numMatches = reStr => (src.match(new RegExp(reStr, 'img')) || []).length; - let totalScore = 0; - let scores = {}; - let redundantGasCount = 0; - zkSyncIncompatOpcodes.forEach(opcode => { - const score = numMatches('[^a-zA-z]' + opcode + '\\('); - if (opcode.match(/call$/)) { - redundantGasCount += numMatches('[^a-zA-z]' + opcode + '\\([\\S\\s]*?gas\\s*?\\('); - } - totalScore += score; - scores[opcode] = score; - }); - specialPatterns.forEach(c => { - const score = numMatches(c.reStr); - totalScore += score; - scores[c.name] = score; - }); - if (redundantGasCount) scores['gas'] -= redundantGasCount; - for (const key in scores) if (scores[key] === 0) delete scores[key]; - const lastModifiedGitTimestamp = getLastModifiedGitTimestamp(srcPath); - flattenedPathsAndScores.push({srcPath, scores, totalScore, lastModifiedGitTimestamp}); - }); - - flattenedPathsAndScores.sort((a, b) => a.totalScore - b.totalScore); - flattenedPathsAndScores.forEach(x => { - if (x.totalScore === 0) delete x.scores; - delete x.totalScore; - }); - console.log(JSON.stringify(flattenedPathsAndScores, null, 4)); -}; - -main().catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/grouperBot/lib/solady/src/Milady.sol b/grouperBot/lib/solady/src/Milady.sol deleted file mode 100644 index 1749970..0000000 --- a/grouperBot/lib/solady/src/Milady.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./accounts/ERC1271.sol"; -import "./accounts/ERC4337.sol"; -import "./accounts/ERC4337Factory.sol"; -import "./accounts/ERC6551.sol"; -import "./accounts/ERC6551Proxy.sol"; -import "./accounts/ERC7821.sol"; -import "./accounts/LibERC6551.sol"; -import "./accounts/LibERC7579.sol"; -import "./accounts/Receiver.sol"; -import "./accounts/Timelock.sol"; -import "./auth/EnumerableRoles.sol"; -import "./auth/Ownable.sol"; -import "./auth/OwnableRoles.sol"; -import "./auth/TimedRoles.sol"; -import "./tokens/ERC1155.sol"; -import "./tokens/ERC20.sol"; -import "./tokens/ERC20Votes.sol"; -import "./tokens/ERC2981.sol"; -import "./tokens/ERC4626.sol"; -import "./tokens/ERC6909.sol"; -import "./tokens/ERC721.sol"; -import "./tokens/WETH.sol"; -import "./utils/Base58.sol"; -import "./utils/Base64.sol"; -import "./utils/BlockHashLib.sol"; -import "./utils/CREATE3.sol"; -import "./utils/CallContextChecker.sol"; -import "./utils/DateTimeLib.sol"; -import "./utils/DeploylessPredeployQueryer.sol"; -import "./utils/DynamicArrayLib.sol"; -import "./utils/DynamicBufferLib.sol"; -import "./utils/ECDSA.sol"; -import "./utils/EIP712.sol"; -import "./utils/ERC1967Factory.sol"; -import "./utils/ERC1967FactoryConstants.sol"; -import "./utils/EfficientHashLib.sol"; -import "./utils/EnumerableMapLib.sol"; -import "./utils/EnumerableSetLib.sol"; -import "./utils/FixedPointMathLib.sol"; -import "./utils/GasBurnerLib.sol"; -import "./utils/Initializable.sol"; -import "./utils/JSONParserLib.sol"; -import "./utils/LibBit.sol"; -import "./utils/LibBitmap.sol"; -import "./utils/LibClone.sol"; -import "./utils/LibMap.sol"; -import "./utils/LibPRNG.sol"; -import "./utils/LibRLP.sol"; -import "./utils/LibSort.sol"; -import "./utils/LibStorage.sol"; -import "./utils/LibString.sol"; -import "./utils/LibZip.sol"; -import "./utils/Lifebuoy.sol"; -import "./utils/MerkleProofLib.sol"; -import "./utils/MerkleTreeLib.sol"; -import "./utils/MetadataReaderLib.sol"; -import "./utils/MinHeapLib.sol"; -import "./utils/Multicallable.sol"; -import "./utils/P256.sol"; -import "./utils/RedBlackTreeLib.sol"; -import "./utils/ReentrancyGuard.sol"; -import "./utils/SSTORE2.sol"; -import "./utils/SafeCastLib.sol"; -import "./utils/SafeTransferLib.sol"; -import "./utils/SemVerLib.sol"; -import "./utils/SignatureCheckerLib.sol"; -import "./utils/UUPSUpgradeable.sol"; -import "./utils/UpgradeableBeacon.sol"; -import "./utils/WebAuthn.sol"; -import "./utils/ext/delegatexyz/DelegateCheckerLib.sol"; - -library Milady { - string internal constant WEBSITE = "https://miladymaker.net"; - - address internal constant CONTRACT = 0x5Af0D9827E0c53E4799BB226655A1de152A425a5; -} diff --git a/grouperBot/lib/solady/src/accounts/EIP7702Proxy.sol b/grouperBot/lib/solady/src/accounts/EIP7702Proxy.sol deleted file mode 100644 index 0254124..0000000 --- a/grouperBot/lib/solady/src/accounts/EIP7702Proxy.sol +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; -// solc: 0.8.28, optimization runs: 200, evm version: cancun. - -/// @notice Relay proxy for EIP7702 delegations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/EIP7702Proxy.sol) -/// -/// @dev Note: This relay proxy is useful for upgradeable EIP7702 accounts -/// without the need for redelegation. -/// -/// EOA -> EIP7702Proxy (relay) -> EIP7702 account implementation. -/// -/// This relay proxy also allows for correctly revealing the -/// "Read as Proxy" and "Write as Proxy" tabs on Etherscan. -contract EIP7702Proxy { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For differentiating calls on the EOA and calls on the proxy itself. - uint256 internal immutable __self = uint256(uint160(address(this))); - - /// @dev The default implementation. Provided for optimization. - /// Set if the `initialAdmin == address(0) && initialImplementation != address(0)`. - uint256 internal immutable _defaultImplementation; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /// @dev The ERC-1967 storage slot for the admin in the proxy. - /// `uint256(keccak256("eip1967.proxy.admin")) - 1`. - bytes32 internal constant _ERC1967_ADMIN_SLOT = - 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - /// @dev The transient storage slot for requesting the proxy to initialize the implementation. - /// `uint256(keccak256("eip7702.proxy.delegation.initialization.request")) - 1`. - /// While we would love to use a smaller constant, this slot is used in both the proxy - /// and the delegation, so we shall just use bytes32 in case we want to standardize this. - bytes32 internal constant _EIP7702_PROXY_DELEGATION_INITIALIZATION_REQUEST_SLOT = - 0x94e11c6e41e7fb92cb8bb65e13fdfbd4eba8b831292a1a220f7915c78c7c078f; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor(address initialImplementation, address initialAdmin) payable { - uint256 defaultImplementation; - /// @solidity memory-safe-assembly - assembly { - // We will store the implementation in the storage regardless, - // to aid proxy detection on block explorers. - sstore(_ERC1967_IMPLEMENTATION_SLOT, initialImplementation) - sstore(_ERC1967_ADMIN_SLOT, initialAdmin) - defaultImplementation := - mul(lt(initialAdmin, iszero(iszero(initialImplementation))), initialImplementation) - } - _defaultImplementation = defaultImplementation; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* FALLBACK */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - fallback() external payable virtual { - uint256 s = __self; - uint256 defaultImplementation = _defaultImplementation; - bytes32 implementationSlot = _ERC1967_IMPLEMENTATION_SLOT; - uint256 addrMask = (~msg.data.length) >> 96; - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, 1) - // Workflow for calling on the proxy itself. - // We cannot put these functions in the public ABI as this proxy must - // fully forward all the calldata from EOAs pointing to this proxy. - if iszero(xor(address(), s)) { - if iszero(gt(calldatasize(), 1)) { - mstore(0x00, and(addrMask, sload(implementationSlot))) - return(0x00, 0x20) - } - let fnSel := shr(224, calldataload(0x00)) - // `implementation()`. - if eq(0x5c60da1b, fnSel) { - mstore(0x00, and(addrMask, sload(implementationSlot))) - return(0x00, 0x20) - } - let adminSlot := _ERC1967_ADMIN_SLOT - // `admin()`. - if eq(0xf851a440, fnSel) { - mstore(0x00, sload(adminSlot)) - return(0x00, 0x20) - } - // Admin workflow. - if eq(caller(), sload(adminSlot)) { - let addrSlot := - or( - mul(eq(0x8f283970, fnSel), adminSlot), // `changeAdmin(address)`. - mul(eq(0x0900f010, fnSel), implementationSlot) // `upgrade(address)`. - ) - if addrSlot { - sstore(addrSlot, and(addrMask, calldataload(0x04))) - return(0x40, 0x20) // Return `true`. - } - // For minimalism, we shall skip events and calldata bounds checks. - // We don't need to forward any data to the new implementation. - // This "proxy" is actually close to an upgradeable beacon. - } - revert(0x00, 0x00) - } - // Workflow for the EIP7702 authority (i.e. the EOA). - let implementation := and(addrMask, sload(implementationSlot)) // On EOA's storage. - // Special workflow for retrieving the implementation directly. - if eq(1, calldatasize()) { - // If the preferred implementation is `address(0)`. - if iszero(implementation) { - implementation := defaultImplementation - // If `defaultImplementation` is `address(0)` - if iszero(implementation) { - // Fetch the implementation from the proxy. - if staticcall(gas(), s, 0x00, 0x00, 0x00, 0x20) { - return(0x00, returndatasize()) - } - revert(0x00, 0x00) - } - } - mstore(0x00, implementation) - return(0x00, 0x20) - } - calldatacopy(0x00, 0x00, calldatasize()) // Copy the calldata for the delegatecall. - // If the preferred implementation is `address(0)`. - if iszero(implementation) { - implementation := defaultImplementation - // If `defaultImplementation` is `address(0)`, perform the initialization workflow. - if iszero(implementation) { - if iszero( - and( // The arguments of `and` are evaluated from right to left. - delegatecall( - gas(), mload(calldatasize()), 0x00, calldatasize(), 0x00, 0x00 - ), - // Fetch the implementation from the proxy. - staticcall(gas(), s, 0x00, 0x00, calldatasize(), 0x20) - ) - ) { - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - // Because we cannot reliably and efficiently tell if the call is made - // via staticcall or call, we shall ask the delegation to make a proxy delegation - // initialization request to signal that we should initialize the storage slot with - // the actual implementation. This also gives flexibility on whether to let the - // proxy auto-upgrade, or let the authority manually upgrade (via 7702 or passkey). - // A non-zero value in the transient storage denotes a initialization request. - let initializationRequestSlot := - _EIP7702_PROXY_DELEGATION_INITIALIZATION_REQUEST_SLOT - if tload(initializationRequestSlot) { - // The `implementation` is still at `calldatasize()` in memory. - // Preserve the upper 96 bits when updating in case they are used for some stuff. - sstore( - implementationSlot, - or(and(not(addrMask), sload(implementationSlot)), mload(calldatasize())) - ) - tstore(initializationRequestSlot, 0) // Clear. - } - returndatacopy(0x00, 0x00, returndatasize()) - return(0x00, returndatasize()) - } - } - // Otherwise, just delegatecall and bubble up the results without initialization. - if iszero(delegatecall(gas(), implementation, 0x00, calldatasize(), 0x00, 0x00)) { - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - returndatacopy(0x00, 0x00, returndatasize()) - return(0x00, returndatasize()) - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/ERC1271.sol b/grouperBot/lib/solady/src/accounts/ERC1271.sol deleted file mode 100644 index 86d2eac..0000000 --- a/grouperBot/lib/solady/src/accounts/ERC1271.sol +++ /dev/null @@ -1,327 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {EIP712} from "../utils/EIP712.sol"; -import {SignatureCheckerLib} from "../utils/SignatureCheckerLib.sol"; - -/// @notice ERC1271 mixin with nested EIP-712 approach. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC1271.sol) -abstract contract ERC1271 is EIP712 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev `keccak256("PersonalSign(bytes prefixed)")`. - bytes32 internal constant _PERSONAL_SIGN_TYPEHASH = - 0x983e65e5148e570cd828ead231ee759a8d7958721a768f93bc4483ba005c32de; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1271 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Validates the signature with ERC1271 return, - /// so that this account can also be used as a signer. - function isValidSignature(bytes32 hash, bytes calldata signature) - public - view - virtual - returns (bytes4 result) - { - // For automatic detection that the smart account supports the nested EIP-712 workflow, - // See: https://eips.ethereum.org/EIPS/eip-7739. - // If `hash` is `0x7739...7739`, returns `bytes4(0x77390001)`. - // The returned number MAY be increased in future ERC7739 versions. - unchecked { - if (signature.length == uint256(0)) { - // Forces the compiler to optimize for smaller bytecode size. - if (uint256(hash) == ~signature.length / 0xffff * 0x7739) return 0x77390001; - } - } - bool success = _erc1271IsValidSignature(hash, _erc1271UnwrapSignature(signature)); - /// @solidity memory-safe-assembly - assembly { - // `success ? bytes4(keccak256("isValidSignature(bytes32,bytes)")) : 0xffffffff`. - // We use `0xffffffff` for invalid, in convention with the reference implementation. - result := shl(224, or(0x1626ba7e, sub(0, iszero(success)))) - } - } - - /// @dev Returns the ERC1271 signer. - /// Override to return the signer `isValidSignature` checks against. - function _erc1271Signer() internal view virtual returns (address); - - /// @dev Returns whether the `msg.sender` is considered safe, such - /// that we don't need to use the nested EIP-712 workflow. - /// Override to return true for more callers. - /// See: https://mirror.xyz/curiousapple.eth/pFqAdW2LiJ-6S4sg_u1z08k4vK6BCJ33LcyXpnNb8yU - function _erc1271CallerIsSafe() internal view virtual returns (bool) { - // The canonical `MulticallerWithSigner` at 0x000000000000D9ECebf3C23529de49815Dac1c4c - // is known to include the account in the hash to be signed. - return msg.sender == 0x000000000000D9ECebf3C23529de49815Dac1c4c; - } - - /// @dev Returns whether the `hash` and `signature` are valid. - /// Override if you need non-ECDSA logic. - function _erc1271IsValidSignatureNowCalldata(bytes32 hash, bytes calldata signature) - internal - view - virtual - returns (bool) - { - return SignatureCheckerLib.isValidSignatureNowCalldata(_erc1271Signer(), hash, signature); - } - - /// @dev Unwraps and returns the signature. - function _erc1271UnwrapSignature(bytes calldata signature) - internal - view - virtual - returns (bytes calldata result) - { - result = signature; - /// @solidity memory-safe-assembly - assembly { - // Unwraps the ERC6492 wrapper if it exists. - // See: https://eips.ethereum.org/EIPS/eip-6492 - if eq( - calldataload(add(result.offset, sub(result.length, 0x20))), - mul(0x6492, div(not(shr(address(), address())), 0xffff)) // `0x6492...6492`. - ) { - let o := add(result.offset, calldataload(add(result.offset, 0x40))) - result.length := calldataload(o) - result.offset := add(o, 0x20) - } - } - } - - /// @dev Returns whether the `signature` is valid for the `hash. - function _erc1271IsValidSignature(bytes32 hash, bytes calldata signature) - internal - view - virtual - returns (bool) - { - return _erc1271IsValidSignatureViaSafeCaller(hash, signature) - || _erc1271IsValidSignatureViaNestedEIP712(hash, signature) - || _erc1271IsValidSignatureViaRPC(hash, signature); - } - - /// @dev Performs the signature validation without nested EIP-712 if the caller is - /// a safe caller. A safe caller must include the address of this account in the hash. - function _erc1271IsValidSignatureViaSafeCaller(bytes32 hash, bytes calldata signature) - internal - view - virtual - returns (bool result) - { - if (_erc1271CallerIsSafe()) result = _erc1271IsValidSignatureNowCalldata(hash, signature); - } - - /// @dev ERC1271 signature validation (Nested EIP-712 workflow). - /// - /// This uses ECDSA recovery by default (see: `_erc1271IsValidSignatureNowCalldata`). - /// It also uses a nested EIP-712 approach to prevent signature replays when a single EOA - /// owns multiple smart contract accounts, - /// while still enabling wallet UIs (e.g. Metamask) to show the EIP-712 values. - /// - /// Crafted for phishing resistance, efficiency, flexibility. - /// __________________________________________________________________________________________ - /// - /// Glossary: - /// - /// - `APP_DOMAIN_SEPARATOR`: The domain separator of the `hash` passed in by the application. - /// Provided by the front end. Intended to be the domain separator of the contract - /// that will call `isValidSignature` on this account. - /// - /// - `ACCOUNT_DOMAIN_SEPARATOR`: The domain separator of this account. - /// See: `EIP712._domainSeparator()`. - /// __________________________________________________________________________________________ - /// - /// For the `TypedDataSign` workflow, the final hash will be: - /// ``` - /// keccak256(\x19\x01 ‖ APP_DOMAIN_SEPARATOR ‖ - /// hashStruct(TypedDataSign({ - /// contents: hashStruct(originalStruct), - /// name: keccak256(bytes(eip712Domain().name)), - /// version: keccak256(bytes(eip712Domain().version)), - /// chainId: eip712Domain().chainId, - /// verifyingContract: eip712Domain().verifyingContract, - /// salt: eip712Domain().salt - /// })) - /// ) - /// ``` - /// where `‖` denotes the concatenation operator for bytes. - /// The order of the fields is important: `contents` comes before `name`. - /// - /// The signature will be `r ‖ s ‖ v ‖ APP_DOMAIN_SEPARATOR ‖ - /// contents ‖ contentsDescription ‖ uint16(contentsDescription.length)`, - /// where: - /// - `contents` is the bytes32 struct hash of the original struct. - /// - `contentsDescription` can be either: - /// a) `contentsType` (implicit mode) - /// where `contentsType` starts with `contentsName`. - /// b) `contentsType ‖ contentsName` (explicit mode) - /// where `contentsType` may not necessarily start with `contentsName`. - /// - /// The `APP_DOMAIN_SEPARATOR` and `contents` will be used to verify if `hash` is indeed correct. - /// __________________________________________________________________________________________ - /// - /// For the `PersonalSign` workflow, the final hash will be: - /// ``` - /// keccak256(\x19\x01 ‖ ACCOUNT_DOMAIN_SEPARATOR ‖ - /// hashStruct(PersonalSign({ - /// prefixed: keccak256(bytes(\x19Ethereum Signed Message:\n ‖ - /// base10(bytes(someString).length) ‖ someString)) - /// })) - /// ) - /// ``` - /// where `‖` denotes the concatenation operator for bytes. - /// - /// The `PersonalSign` type hash will be `keccak256("PersonalSign(bytes prefixed)")`. - /// The signature will be `r ‖ s ‖ v`. - /// __________________________________________________________________________________________ - /// - /// For demo and typescript code, see: - /// - https://github.com/junomonster/nested-eip-712 - /// - https://github.com/frangio/eip712-wrapper-for-eip1271 - /// - /// Their nomenclature may differ from ours, although the high-level idea is similar. - /// - /// Of course, if you have control over the codebase of the wallet client(s) too, - /// you can choose a more minimalistic signature scheme like - /// `keccak256(abi.encode(address(this), hash))` instead of all these acrobatics. - /// All these are just for widespread out-of-the-box compatibility with other wallet clients. - /// We want to create bazaars, not walled castles. - /// And we'll use push the Turing Completeness of the EVM to the limits to do so. - function _erc1271IsValidSignatureViaNestedEIP712(bytes32 hash, bytes calldata signature) - internal - view - virtual - returns (bool result) - { - uint256 t = uint256(uint160(address(this))); - // Forces the compiler to pop the variables after the scope, avoiding stack-too-deep. - if (t != uint256(0)) { - ( - , - string memory name, - string memory version, - uint256 chainId, - address verifyingContract, - bytes32 salt, - ) = eip712Domain(); - /// @solidity memory-safe-assembly - assembly { - t := mload(0x40) // Grab the free memory pointer. - // Skip 2 words for the `typedDataSignTypehash` and `contents` struct hash. - mstore(add(t, 0x40), keccak256(add(name, 0x20), mload(name))) - mstore(add(t, 0x60), keccak256(add(version, 0x20), mload(version))) - mstore(add(t, 0x80), chainId) - mstore(add(t, 0xa0), shr(96, shl(96, verifyingContract))) - mstore(add(t, 0xc0), salt) - mstore(0x40, add(t, 0xe0)) // Allocate the memory. - } - } - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - // `c` is `contentsDescription.length`, which is stored in the last 2 bytes of the signature. - let c := shr(240, calldataload(add(signature.offset, sub(signature.length, 2)))) - for {} 1 {} { - let l := add(0x42, c) // Total length of appended data (32 + 32 + c + 2). - let o := add(signature.offset, sub(signature.length, l)) // Offset of appended data. - mstore(0x00, 0x1901) // Store the "\x19\x01" prefix. - calldatacopy(0x20, o, 0x40) // Copy the `APP_DOMAIN_SEPARATOR` and `contents` struct hash. - // Use the `PersonalSign` workflow if the reconstructed hash doesn't match, - // or if the appended data is invalid, i.e. - // `appendedData.length > signature.length || contentsDescription.length == 0`. - if or(xor(keccak256(0x1e, 0x42), hash), or(lt(signature.length, l), iszero(c))) { - t := 0 // Set `t` to 0, denoting that we need to `hash = _hashTypedData(hash)`. - mstore(t, _PERSONAL_SIGN_TYPEHASH) - mstore(0x20, hash) // Store the `prefixed`. - hash := keccak256(t, 0x40) // Compute the `PersonalSign` struct hash. - break - } - // Else, use the `TypedDataSign` workflow. - // `TypedDataSign({ContentsName} contents,string name,...){ContentsType}`. - mstore(m, "TypedDataSign(") // Store the start of `TypedDataSign`'s type encoding. - let p := add(m, 0x0e) // Advance 14 bytes to skip "TypedDataSign(". - calldatacopy(p, add(o, 0x40), c) // Copy `contentsName`, optimistically. - mstore(add(p, c), 40) // Store a '(' after the end. - if iszero(eq(byte(0, mload(sub(add(p, c), 1))), 41)) { - let e := 0 // Length of `contentsName` in explicit mode. - for { let q := sub(add(p, c), 1) } 1 {} { - e := add(e, 1) // Scan backwards until we encounter a ')'. - if iszero(gt(lt(e, c), eq(byte(0, mload(sub(q, e))), 41))) { break } - } - c := sub(c, e) // Truncate `contentsDescription` to `contentsType`. - calldatacopy(p, add(add(o, 0x40), c), e) // Copy `contentsName`. - mstore8(add(p, e), 40) // Store a '(' exactly right after the end. - } - // `d & 1 == 1` means that `contentsName` is invalid. - let d := shr(byte(0, mload(p)), 0x7fffffe000000000000010000000000) // Starts with `[a-z(]`. - // Advance `p` until we encounter '('. - for {} iszero(eq(byte(0, mload(p)), 40)) { p := add(p, 1) } { - d := or(shr(byte(0, mload(p)), 0x120100000001), d) // Has a byte in ", )\x00". - } - mstore(p, " contents,string name,string") // Store the rest of the encoding. - mstore(add(p, 0x1c), " version,uint256 chainId,address") - mstore(add(p, 0x3c), " verifyingContract,bytes32 salt)") - p := add(p, 0x5c) - calldatacopy(p, add(o, 0x40), c) // Copy `contentsType`. - // Fill in the missing fields of the `TypedDataSign`. - calldatacopy(t, o, 0x40) // Copy the `contents` struct hash to `add(t, 0x20)`. - mstore(t, keccak256(m, sub(add(p, c), m))) // Store `typedDataSignTypehash`. - // The "\x19\x01" prefix is already at 0x00. - // `APP_DOMAIN_SEPARATOR` is already at 0x20. - mstore(0x40, keccak256(t, 0xe0)) // `hashStruct(typedDataSign)`. - // Compute the final hash, corrupted if `contentsName` is invalid. - hash := keccak256(0x1e, add(0x42, and(1, d))) - signature.length := sub(signature.length, l) // Truncate the signature. - break - } - mstore(0x40, m) // Restore the free memory pointer. - } - if (t == uint256(0)) hash = _hashTypedData(hash); // `PersonalSign` workflow. - result = _erc1271IsValidSignatureNowCalldata(hash, signature); - } - - /// @dev Performs the signature validation without nested EIP-712 to allow for easy sign ins. - /// This function must always return false or revert if called on-chain. - function _erc1271IsValidSignatureViaRPC(bytes32 hash, bytes calldata signature) - internal - view - virtual - returns (bool result) - { - // Non-zero gasprice is a heuristic to check if a call is on-chain, - // but we can't fully depend on it because it can be manipulated. - // See: https://x.com/NoahCitron/status/1580359718341484544 - if (tx.gasprice == uint256(0)) { - /// @solidity memory-safe-assembly - assembly { - mstore(gasprice(), gasprice()) - // See: https://gist.github.com/Vectorized/3c9b63524d57492b265454f62d895f71 - let b := 0x000000000000378eDCD5B5B0A24f5342d8C10485 // Basefee contract, - pop(staticcall(0xffff, b, codesize(), gasprice(), gasprice(), 0x20)) - // If `gasprice < basefee`, the call cannot be on-chain, and we can skip the gas burn. - if iszero(mload(gasprice())) { - let m := mload(0x40) // Cache the free memory pointer. - mstore(gasprice(), 0x1626ba7e) // `isValidSignature(bytes32,bytes)`. - mstore(0x20, b) // Recycle `b` to denote if we need to burn gas. - mstore(0x40, 0x40) - let gasToBurn := or(add(0xffff, gaslimit()), gaslimit()) - // Burns gas computationally efficiently. Also, requires that `gas > gasToBurn`. - if or(eq(hash, b), lt(gas(), gasToBurn)) { invalid() } - // Make a call to this with `b`, efficiently burning the gas provided. - // No valid transaction can consume more than the gaslimit. - // See: https://ethereum.github.io/yellowpaper/paper.pdf - // Most RPCs perform calls with a gas budget greater than the gaslimit. - pop(staticcall(gasToBurn, address(), 0x1c, 0x64, gasprice(), gasprice())) - mstore(0x40, m) // Restore the free memory pointer. - } - } - result = _erc1271IsValidSignatureNowCalldata(hash, signature); - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/ERC4337.sol b/grouperBot/lib/solady/src/accounts/ERC4337.sol deleted file mode 100644 index d5256f2..0000000 --- a/grouperBot/lib/solady/src/accounts/ERC4337.sol +++ /dev/null @@ -1,428 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Receiver} from "./Receiver.sol"; -import {LibZip} from "../utils/LibZip.sol"; -import {Ownable} from "../auth/Ownable.sol"; -import {UUPSUpgradeable} from "../utils/UUPSUpgradeable.sol"; -import {SignatureCheckerLib, ERC1271} from "../accounts/ERC1271.sol"; - -/// @notice Simple ERC4337 account implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC4337.sol) -/// @author Infinitism (https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol) -/// -/// @dev Recommended usage: -/// 1. Deploy the ERC4337 as an implementation contract, and verify it on Etherscan. -/// 2. Create a factory that uses `LibClone.deployERC1967` or -/// `LibClone.deployDeterministicERC1967` to clone the implementation. -/// See: `ERC4337Factory.sol`. -/// -/// Note: -/// ERC4337 is a very complicated standard with many potential gotchas. -/// Also, it is subject to change and has not been finalized -/// (so accounts are encouraged to be upgradeable). -/// Usually, ERC4337 account implementations are developed by companies with ample funds -/// for security reviews. This implementation is intended to serve as a base reference -/// for smart account developers working in such companies. If you are using this -/// implementation, please do get one or more security reviews before deployment. -abstract contract ERC4337 is Ownable, UUPSUpgradeable, Receiver, ERC1271 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The packed ERC4337 user operation (userOp) struct. - struct PackedUserOperation { - address sender; - uint256 nonce; - bytes initCode; // Factory address and `factoryData` (or empty). - bytes callData; - bytes32 accountGasLimits; // `verificationGas` (16 bytes) and `callGas` (16 bytes). - uint256 preVerificationGas; - bytes32 gasFees; // `maxPriorityFee` (16 bytes) and `maxFeePerGas` (16 bytes). - bytes paymasterAndData; // Paymaster fields (or empty). - bytes signature; - } - - /// @dev Call struct for the `executeBatch` function. - struct Call { - address target; - uint256 value; - bytes data; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys this ERC4337 account implementation and disables initialization (see below). - constructor() payable { - _disableERC4337ImplementationInitializer(); - } - - /// @dev Automatically initializes the owner for the implementation. This blocks someone - /// from initializing the implementation and doing a delegatecall to SELFDESTRUCT. - /// Proxies to the implementation will still be able to initialize as per normal. - function _disableERC4337ImplementationInitializer() internal virtual { - // Note that `Ownable._guardInitializeOwner` has been and must be overridden - // to return true, to block double-initialization. We'll initialize to `address(1)`, - // so that it's easier to verify that the implementation has been initialized. - _initializeOwner(address(1)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INITIALIZER */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Initializes the account with the owner. Can only be called once. - function initialize(address newOwner) public payable virtual { - _initializeOwner(newOwner); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ENTRY POINT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the canonical ERC4337 EntryPoint contract (0.7). - /// Override this function to return a different EntryPoint. - function entryPoint() public view virtual returns (address) { - return 0x0000000071727De22E5E9d8BAf0edAc6f37da032; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* VALIDATION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Validates the signature and nonce. - /// The EntryPoint will make the call to the recipient only if - /// this validation call returns successfully. - /// - /// Signature failure should be reported by returning 1 (see: `_validateSignature`). - /// This allows making a "simulation call" without a valid signature. - /// Other failures (e.g. nonce mismatch, or invalid signature format) - /// should still revert to signal failure. - function validateUserOp( - PackedUserOperation calldata userOp, - bytes32 userOpHash, - uint256 missingAccountFunds - ) - external - payable - virtual - onlyEntryPoint - payPrefund(missingAccountFunds) - returns (uint256 validationData) - { - validationData = _validateSignature(userOp, userOpHash); - _validateNonce(userOp.nonce); - } - - /// @dev Validate `userOp.signature` for the `userOpHash`. - function _validateSignature(PackedUserOperation calldata userOp, bytes32 userOpHash) - internal - virtual - returns (uint256 validationData) - { - bool success = SignatureCheckerLib.isValidSignatureNowCalldata( - owner(), SignatureCheckerLib.toEthSignedMessageHash(userOpHash), userOp.signature - ); - /// @solidity memory-safe-assembly - assembly { - // Returns 0 if the recovered address matches the owner. - // Else returns 1, which is equivalent to: - // `(success ? 0 : 1) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48))` - // where `validUntil` is 0 (indefinite) and `validAfter` is 0. - validationData := iszero(success) - } - } - - /// @dev Override to validate the nonce of the userOp. - /// This method may validate the nonce requirement of this account. - /// e.g. - /// To limit the nonce to use sequenced userOps only (no "out of order" userOps): - /// `require(nonce < type(uint64).max)` - /// For a hypothetical account that *requires* the nonce to be out-of-order: - /// `require(nonce & type(uint64).max == 0)` - /// - /// The actual nonce uniqueness is managed by the EntryPoint, and thus no other - /// action is needed by the account itself. - function _validateNonce(uint256 nonce) internal virtual { - nonce = nonce; // Silence unused variable warning. - } - - /// @dev Sends to the EntryPoint (i.e. `msg.sender`) the missing funds for this transaction. - /// Subclass MAY override this modifier for better funds management. - /// (e.g. send to the EntryPoint more than the minimum required, so that in future transactions - /// it will not be required to send again) - /// - /// `missingAccountFunds` is the minimum value this modifier should send the EntryPoint, - /// which MAY be zero, in case there is enough deposit, or the userOp has a paymaster. - modifier payPrefund(uint256 missingAccountFunds) virtual { - _; - /// @solidity memory-safe-assembly - assembly { - if missingAccountFunds { - // Ignore failure (it's EntryPoint's job to verify, not the account's). - pop(call(gas(), caller(), missingAccountFunds, codesize(), 0x00, codesize(), 0x00)) - } - } - } - - /// @dev Requires that the caller is the EntryPoint. - modifier onlyEntryPoint() virtual { - if (msg.sender != entryPoint()) revert Unauthorized(); - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EXECUTION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Execute a call from this account. - function execute(address target, uint256 value, bytes calldata data) - public - payable - virtual - onlyEntryPointOrOwner - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, data.offset, data.length) - if iszero(call(gas(), target, value, result, data.length, codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /// @dev Execute a sequence of calls from this account. - function executeBatch(Call[] calldata calls) - public - payable - virtual - onlyEntryPointOrOwner - returns (bytes[] memory results) - { - /// @solidity memory-safe-assembly - assembly { - results := mload(0x40) - mstore(results, calls.length) - let r := add(0x20, results) - let m := add(r, shl(5, calls.length)) - calldatacopy(r, calls.offset, shl(5, calls.length)) - for { let end := m } iszero(eq(r, end)) { r := add(r, 0x20) } { - let e := add(calls.offset, mload(r)) - let o := add(e, calldataload(add(e, 0x40))) - calldatacopy(m, add(o, 0x20), calldataload(o)) - // forgefmt: disable-next-item - if iszero(call(gas(), calldataload(e), calldataload(add(e, 0x20)), - m, calldataload(o), codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - mstore(r, m) // Append `m` into `results`. - mstore(m, returndatasize()) // Store the length, - let p := add(m, 0x20) - returndatacopy(p, 0x00, returndatasize()) // and copy the returndata. - m := add(p, returndatasize()) // Advance `m`. - } - mstore(0x40, m) // Allocate the memory. - } - } - - /// @dev Execute a delegatecall with `delegate` on this account. - function delegateExecute(address delegate, bytes calldata data) - public - payable - virtual - onlyEntryPointOrOwner - delegateExecuteGuard - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, data.offset, data.length) - // Forwards the `data` to `delegate` via delegatecall. - if iszero(delegatecall(gas(), delegate, result, data.length, codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /// @dev Ensures that the owner and implementation slots' values aren't changed. - /// You can override this modifier to ensure the sanctity of other storage slots too. - modifier delegateExecuteGuard() virtual { - bytes32 ownerSlotValue; - bytes32 implementationSlotValue; - /// @solidity memory-safe-assembly - assembly { - implementationSlotValue := sload(_ERC1967_IMPLEMENTATION_SLOT) - ownerSlotValue := sload(_OWNER_SLOT) - } - _; - /// @solidity memory-safe-assembly - assembly { - if iszero( - and( - eq(implementationSlotValue, sload(_ERC1967_IMPLEMENTATION_SLOT)), - eq(ownerSlotValue, sload(_OWNER_SLOT)) - ) - ) { revert(codesize(), 0x00) } - } - } - - /// @dev Requires that the caller is the EntryPoint, the owner, or the account itself. - modifier onlyEntryPointOrOwner() virtual { - if (msg.sender != entryPoint()) _checkOwner(); - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DIRECT STORAGE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the raw storage value at `storageSlot`. - function storageLoad(bytes32 storageSlot) public view virtual returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(storageSlot) - } - } - - /// @dev Writes the raw storage value at `storageSlot`. - function storageStore(bytes32 storageSlot, bytes32 storageValue) - public - payable - virtual - onlyEntryPointOrOwner - storageStoreGuard(storageSlot) - { - /// @solidity memory-safe-assembly - assembly { - sstore(storageSlot, storageValue) - } - } - - /// @dev Ensures that the `storageSlot` is prohibited for direct storage writes. - /// You can override this modifier to ensure the sanctity of other storage slots too. - modifier storageStoreGuard(bytes32 storageSlot) virtual { - /// @solidity memory-safe-assembly - assembly { - if or(eq(storageSlot, _OWNER_SLOT), eq(storageSlot, _ERC1967_IMPLEMENTATION_SLOT)) { - revert(codesize(), 0x00) - } - } - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DEPOSIT OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the account's balance on the EntryPoint. - function getDeposit() public view virtual returns (uint256 result) { - address ep = entryPoint(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, address()) // Store the `account` argument. - mstore(0x00, 0x70a08231) // `balanceOf(address)`. - result := - mul( // Returns 0 if the EntryPoint does not exist. - mload(0x20), - and( // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x1f), // At least 32 bytes returned. - staticcall(gas(), ep, 0x1c, 0x24, 0x20, 0x20) - ) - ) - } - } - - /// @dev Deposit more funds for this account in the EntryPoint. - function addDeposit() public payable virtual { - address ep = entryPoint(); - /// @solidity memory-safe-assembly - assembly { - // The EntryPoint has balance accounting logic in the `receive()` function, as defined in ERC-4337. - // forgefmt: disable-next-item - if iszero(mul(extcodesize(ep), call(gas(), ep, callvalue(), codesize(), 0x00, codesize(), 0x00))) { - revert(codesize(), 0x00) // For gas estimation. - } - } - } - - /// @dev Withdraw ETH from the account's deposit on the EntryPoint. - function withdrawDepositTo(address to, uint256 amount) public payable virtual onlyOwner { - address ep = entryPoint(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - mstore(0x00, 0x205c2878000000000000000000000000) // `withdrawTo(address,uint256)`. - if iszero(mul(extcodesize(ep), call(gas(), ep, 0, 0x10, 0x44, codesize(), 0x00))) { - returndatacopy(mload(0x40), 0x00, returndatasize()) - revert(mload(0x40), returndatasize()) - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OVERRIDES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Requires that the caller is the owner or the account itself. - /// This override affects the `onlyOwner` modifier. - function _checkOwner() internal view virtual override(Ownable) { - if (msg.sender != owner()) if (msg.sender != address(this)) revert Unauthorized(); - } - - /// @dev To prevent double-initialization (reuses the owner storage slot for efficiency). - function _guardInitializeOwner() internal pure virtual override(Ownable) returns (bool) { - return true; - } - - /// @dev Uses the `owner` as the ERC1271 signer. - function _erc1271Signer() internal view virtual override(ERC1271) returns (address) { - return owner(); - } - - /// @dev Allow the entry point to skip the ERC7739 nested typed data workflow. - /// This is safe as the entry point already includes the smart account in the user op digest. - function _erc1271CallerIsSafe() internal view virtual override(ERC1271) returns (bool) { - return msg.sender == entryPoint() || ERC1271._erc1271CallerIsSafe(); - } - - /// @dev To ensure that only the owner or the account itself can upgrade the implementation. - function _authorizeUpgrade(address) internal virtual override(UUPSUpgradeable) onlyOwner {} - - /// @dev If you don't need to use `LibZip.cdFallback`, override this function to return false. - function _useLibZipCdFallback() internal view virtual returns (bool) { - return true; - } - - /// @dev Handle token callbacks. If no token callback is triggered, - /// use `LibZip.cdFallback` for generalized calldata decompression. - fallback() external payable virtual override(Receiver) receiverFallback { - if (_useLibZipCdFallback()) { - // Reverts with out-of-gas by recursing infinitely if the first 4 bytes - // of the decompressed `msg.data` doesn't match any function selector. - LibZip.cdFallback(); - } else { - revert FnSelectorNotRecognized(); - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/ERC4337Factory.sol b/grouperBot/lib/solady/src/accounts/ERC4337Factory.sol deleted file mode 100644 index ed8b1d5..0000000 --- a/grouperBot/lib/solady/src/accounts/ERC4337Factory.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {LibClone} from "../utils/LibClone.sol"; - -/// @notice Simple ERC4337 account factory implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC4337Factory.sol) -/// -/// @dev Note: -/// - Unlike the ERC1967Factory, this factory does NOT store any admin info on the factory itself. -/// The deployed ERC4337 accounts are minimal ERC1967 proxies to an ERC4337 implementation. -/// The proxy bytecode does NOT contain any upgrading logic. -/// - This factory does NOT contain any logic for upgrading the ERC4337 accounts. -/// Upgrading must be done via UUPS logic on the accounts themselves. -/// - The ERC4337 standard expects the factory to use deterministic deployment. -/// As such, this factory does not include any non-deterministic deployment methods. -contract ERC4337Factory { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Address of the ERC4337 implementation. - address public immutable implementation; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor(address erc4337) payable { - implementation = erc4337; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DEPLOY FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys an ERC4337 account with `ownSalt` and returns its deterministic address. - /// The `owner` is encoded in the upper 160 bits of `ownSalt`. - /// If the account is already deployed, it will simply return its address. - /// Any `msg.value` will simply be forwarded to the account, regardless. - function createAccount(bytes32 ownSalt) public payable virtual returns (address) { - // Constructor data is optional, and is omitted for easier Etherscan verification. - (bool alreadyDeployed, address account) = - LibClone.createDeterministicERC1967(msg.value, implementation, ownSalt); - - if (!alreadyDeployed) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, shr(96, ownSalt)) // Store the `owner` argument. - mstore(0x00, 0xc4d66de8) // `initialize(address)`. - if iszero(call(gas(), account, 0, 0x1c, 0x24, codesize(), 0x00)) { - returndatacopy(mload(0x40), 0x00, returndatasize()) - revert(mload(0x40), returndatasize()) - } - } - } - return account; - } - - /// @dev Returns the deterministic address of the account created via `createAccount`. - function getAddress(bytes32 ownSalt) public view virtual returns (address) { - return LibClone.predictDeterministicAddressERC1967(implementation, ownSalt, address(this)); - } - - /// @dev Returns the initialization code hash of the ERC4337 account (a minimal ERC1967 proxy). - /// Used for mining vanity addresses with create2crunch. - function initCodeHash() public view virtual returns (bytes32) { - return LibClone.initCodeHashERC1967(implementation); - } -} diff --git a/grouperBot/lib/solady/src/accounts/ERC6551.sol b/grouperBot/lib/solady/src/accounts/ERC6551.sol deleted file mode 100644 index 7a4ede9..0000000 --- a/grouperBot/lib/solady/src/accounts/ERC6551.sol +++ /dev/null @@ -1,422 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Receiver} from "./Receiver.sol"; -import {ERC1271} from "./ERC1271.sol"; -import {LibZip} from "../utils/LibZip.sol"; -import {UUPSUpgradeable} from "../utils/UUPSUpgradeable.sol"; - -/// @notice Simple ERC6551 account implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC6551.sol) -/// @author ERC6551 team (https://github.com/erc6551/reference/blob/main/src/examples/upgradeable/ERC6551AccountUpgradeable.sol) -/// -/// @dev Recommended usage (regular): -/// 1. Deploy the ERC6551 as an implementation contract, and verify it on Etherscan. -/// 2. Use the canonical ERC6551Registry to deploy a clone to the ERC6551 implementation. -/// The UUPSUpgradeable functions will be disabled. -/// -/// Recommended usage (upgradeable): -/// 1. Deploy the ERC6551 as an implementation contract, and verify it on Etherscan. -/// 2. Deploy the ERC6551Proxy pointing to the implementation. -/// This relay proxy is required, but Etherscan verification of it is optional. -/// 3. Use the canonical ERC6551Registry to deploy a clone to the ERC6551Proxy. -/// If you want to reveal the "Read as Proxy" and "Write as Proxy" tabs on Etherscan, -/// send 0 ETH to the clone to initialize its ERC1967 implementation slot, -/// the click on "Is this a proxy?" on the clone's page on Etherscan. -/// -/// Note: -/// - This implementation does NOT include ERC4337 functionality. -/// This is intentional, because the canonical ERC4337 entry point may still change and we -/// don't want to encourage upgradeability by default for ERC6551 accounts just to handle this. -/// We may include ERC4337 functionality once ERC4337 has been finalized. -/// Recent updates to the account abstraction validation scope rules -/// [ERC7562](https://eips.ethereum.org/EIPS/eip-7562) has made ERC6551 compatible with ERC4337. -/// For an opinionated implementation, see https://github.com/tokenbound/contracts. -/// If you want to add it yourself, you'll just need to add in the -/// user operation validation functionality (and use ERC6551's execution functionality). -/// - Please refer to the official [ERC6551](https://github.com/erc6551/reference) reference -/// for latest updates on the ERC6551 standard, as well as canonical registry information. -abstract contract ERC6551 is UUPSUpgradeable, Receiver, ERC1271 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Call struct for the `executeBatch` function. - struct Call { - address target; - uint256 value; - bytes data; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The caller is not authorized to call the function. - error Unauthorized(); - - /// @dev The operation is not supported. - error OperationNotSupported(); - - /// @dev Self ownership detected. - error SelfOwnDetected(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS AND IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ERC6551 state slot is given by: - /// `bytes32(~uint256(uint32(bytes4(keccak256("_ERC6551_STATE_SLOT_NOT")))))`. - /// It is intentionally chosen to be a high value - /// to avoid collision with lower slots. - /// The choice of manual storage layout is to enable compatibility - /// with both regular and upgradeable contracts. - uint256 internal constant _ERC6551_STATE_SLOT = - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffb919c7a5; - - /// @dev Caches the chain ID in the deployed bytecode, - /// so that in the rare case of a hard fork, `owner` will still work. - uint256 private immutable _cachedChainId = block.chainid; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* TOKEN-BOUND OWNERSHIP OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the token-bound information. - function token() - public - view - virtual - returns (uint256 chainId, address tokenContract, uint256 tokenId) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - extcodecopy(address(), 0x00, 0x4d, 0x60) - chainId := mload(0x00) - tokenContract := mload(0x20) // Upper 96 bits will be clean. - tokenId := mload(0x40) - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Returns the owner of the contract. - function owner() public view virtual returns (address result) { - uint256 cachedChainId = _cachedChainId; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - extcodecopy(address(), 0x00, 0x4d, 0x60) - if eq(mload(0x00), cachedChainId) { - let tokenContract := mload(0x20) - // `tokenId` is already at 0x40. - mstore(0x20, 0x6352211e) // `ownerOf(uint256)`. - result := - mul( // Returns `address(0)` on failure or if contract does not exist. - mload(0x20), - and( - gt(returndatasize(), 0x1f), - staticcall(gas(), tokenContract, 0x3c, 0x24, 0x20, 0x20) - ) - ) - } - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Returns if `signer` is an authorized signer. - /// `extraData` can be anything (e.g. an address, a pointer to a struct / string in memory). - function _isValidSigner(address signer, bytes32 extraData, bytes calldata context) - internal - view - virtual - returns (bool) - { - extraData = extraData; // Silence unused variable warning. - context = context; // Silence unused variable warning. - return signer == owner(); - } - - /// @dev Returns if `signer` is an authorized signer, with an optional `context`. - /// MUST return the bytes4 magic value `0x523e3260` if the given signer is valid. - /// By default, the holder of the non-fungible token the account is bound to - /// MUST be considered a valid signer. - function isValidSigner(address signer, bytes calldata context) - public - view - virtual - returns (bytes4 result) - { - bool isValid = _isValidSigner(signer, bytes32(0), context); - /// @solidity memory-safe-assembly - assembly { - // `isValid ? bytes4(keccak256("isValidSigner(address,bytes)")) : 0x00000000`. - // We use `0x00000000` for invalid, in convention with the reference implementation. - result := shl(224, mul(0x523e3260, iszero(iszero(isValid)))) - } - } - - /// @dev Returns empty calldata bytes. - function _emptyContext() internal pure returns (bytes calldata context) { - /// @solidity memory-safe-assembly - assembly { - context.length := 0 - } - } - - /// @dev Requires that the caller is a valid signer (i.e. the owner). - modifier onlyValidSigner() virtual { - if (!_isValidSigner(msg.sender, bytes32(0), _emptyContext())) revert Unauthorized(); - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STATE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the current value of the state. - function state() public view virtual returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(_ERC6551_STATE_SLOT) - } - } - - /// @dev Mutates the state. This function is required to be called in every - /// public / external function that may modify storage or emit events. - function _updateState() internal virtual { - /// @solidity memory-safe-assembly - assembly { - let s := _ERC6551_STATE_SLOT - let m := mload(0x40) - mstore(m, sload(s)) - mstore(add(0x20, m), 0x40) - mstore(add(0x40, m), calldatasize()) - calldatacopy(add(0x60, m), 0x00, add(0x20, calldatasize())) - sstore(s, keccak256(m, and(add(0x7f, calldatasize()), not(0x1f)))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EXECUTION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Execute a call from this account. - /// Reverts and bubbles up error if operation fails. - /// Returns the result of the operation. - /// - /// Accounts MUST accept the following operation parameter values: - /// - 0 = CALL - /// - 1 = DELEGATECALL - /// - 2 = CREATE - /// - 3 = CREATE2 - /// - /// Accounts MAY support additional operations or restrict a signer's - /// ability to execute certain operations. - function execute(address target, uint256 value, bytes calldata data, uint8 operation) - public - payable - virtual - onlyValidSigner - returns (bytes memory result) - { - if (operation != 0) revert OperationNotSupported(); - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, data.offset, data.length) - if iszero(call(gas(), target, value, result, data.length, codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - _updateState(); - } - - /// @dev Execute a sequence of calls from this account. - /// Reverts and bubbles up error if an operation fails. - /// Returns the results of the operations. - /// - /// This is a batch variant of `execute` and is not required for `IERC6551Executable`. - function executeBatch(Call[] calldata calls, uint8 operation) - public - payable - virtual - onlyValidSigner - returns (bytes[] memory results) - { - if (operation != 0) revert OperationNotSupported(); - /// @solidity memory-safe-assembly - assembly { - results := mload(0x40) - mstore(results, calls.length) - let r := add(0x20, results) - let m := add(r, shl(5, calls.length)) - calldatacopy(r, calls.offset, shl(5, calls.length)) - for { let end := m } iszero(eq(r, end)) { r := add(r, 0x20) } { - let e := add(calls.offset, mload(r)) - let o := add(e, calldataload(add(e, 0x40))) - calldatacopy(m, add(o, 0x20), calldataload(o)) - // forgefmt: disable-next-item - if iszero(call(gas(), calldataload(e), calldataload(add(e, 0x20)), - m, calldataload(o), codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - mstore(r, m) // Append `m` into `results`. - mstore(m, returndatasize()) // Store the length, - let p := add(m, 0x20) - returndatacopy(p, 0x00, returndatasize()) // and copy the returndata. - m := add(p, returndatasize()) // Advance `m`. - } - mstore(0x40, m) // Allocate the memory. - } - _updateState(); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC165 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns true if this contract implements the interface defined by `interfaceId`. - /// See: https://eips.ethereum.org/EIPS/eip-165 - /// This function call must use less than 30000 gas. - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, interfaceId) - // ERC165: 0x01ffc9a7, ERC6551: 0x6faff5f1, ERC6551Executable: 0x51945447. - result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x6faff5f1)), eq(s, 0x51945447)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether there is an ownership cycle. - function _hasOwnershipCycle() internal view virtual returns (bool result) { - uint256 cachedChainId = _cachedChainId; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - extcodecopy(address(), 0x00, 0x4d, 0x60) // `(chainId, tokenContract, tokenId)`. - mstore(0x60, 0xfc0c546a) // `token()`. - for {} 1 {} { - let tokenContract := mload(0x20) - mstore(0x20, 0x6352211e) // `ownerOf(uint256)`. - let currentOwner := - mul( // `chainId == cachedChainId ? tokenContract.ownerOf(tokenId) : address(0)`. - mload(0x20), - and( - and(gt(returndatasize(), 0x1f), eq(mload(0x00), cachedChainId)), - staticcall(gas(), tokenContract, 0x3c, 0x24, 0x20, 0x20) - ) - ) - if iszero(eq(currentOwner, address())) { - if iszero( - and( // `(chainId, tokenContract, tokenId) = currentOwner.token()`. - gt(returndatasize(), 0x5f), - staticcall(gas(), currentOwner, 0x7c, 0x04, 0x00, 0x60) - ) - ) { break } - continue - } - result := 1 - break - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OVERRIDES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev To ensure that only the owner or the account itself can upgrade the implementation. - /// If you don't need upgradeability, override this function to return false for extra safety. - function _authorizeUpgrade(address) - internal - virtual - override(UUPSUpgradeable) - onlyValidSigner - onlyViaERC6551Proxy - { - _updateState(); - } - - /// @dev Guards `_authorizeUpgrade` such that it must be used via an ERC6551Proxy. - modifier onlyViaERC6551Proxy() virtual { - address selfImplementation = _selfImplementation(); - /// @solidity memory-safe-assembly - assembly { - extcodecopy(address(), 0x2c, 0x0a, 0x14) // Assumes the upper 20 bytes at 0x40 are zero. - // Revert if the implementation is the same as the self implementation. - if eq(mload(0x2c), shl(96, selfImplementation)) { - mstore(0x00, 0x9f03a026) // `UnauthorizedCallContext()`. - revert(0x1c, 0x04) - } - } - _; - } - - /// @dev Uses the `owner` as the ERC1271 signer. - function _erc1271Signer() internal view virtual override(ERC1271) returns (address) { - return owner(); - } - - /// @dev For handling token callbacks. - /// Safe-transferred ERC721 tokens will trigger an ownership cycle check. - modifier receiverFallback() override(Receiver) { - uint256 s = uint256(bytes32(msg.sig)) >> 224; - // 0x150b7a02: `onERC721Received(address,address,uint256,bytes)`. - if (s == 0x150b7a02) { - if (!_hasOwnershipCycle()) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, s) // Store `msg.sig`. - return(0x3c, 0x20) // Return `msg.sig`. - } - } - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xaed146d3) // `SelfOwnDetected()`. - revert(0x1c, 0x04) - } - } - /// @solidity memory-safe-assembly - assembly { - // 0xf23a6e61: `onERC1155Received(address,address,uint256,uint256,bytes)`. - // 0xbc197c81: `onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)`. - if or(eq(s, 0xf23a6e61), eq(s, 0xbc197c81)) { - mstore(0x20, s) // Store `msg.sig`. - return(0x3c, 0x20) // Return `msg.sig`. - } - } - _; - } - - /// @dev If you don't need to use `LibZip.cdFallback`, override this function to return false. - function _useLibZipCdFallback() internal view virtual returns (bool) { - return true; - } - - /// @dev Handle token callbacks. If no token callback is triggered, - /// use `LibZip.cdFallback` for generalized calldata decompression. - fallback() external payable virtual override(Receiver) receiverFallback { - if (_useLibZipCdFallback()) { - // Reverts with out-of-gas by recursing infinitely if the first 4 bytes - // of the decompressed `msg.data` doesn't match any function selector. - LibZip.cdFallback(); - } else { - revert FnSelectorNotRecognized(); - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/ERC6551Proxy.sol b/grouperBot/lib/solady/src/accounts/ERC6551Proxy.sol deleted file mode 100644 index 437a052..0000000 --- a/grouperBot/lib/solady/src/accounts/ERC6551Proxy.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Relay proxy for upgradeable ERC6551 accounts. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC6551Proxy.sol) -/// @author ERC6551 team (https://github.com/erc6551/reference/blob/main/src/examples/upgradeable/ERC6551AccountProxy.sol) -/// -/// @dev Note: This relay proxy is required for upgradeable ERC6551 accounts. -/// -/// ERC6551 clone -> ERC6551Proxy (relay) -> ERC6551 account implementation. -/// -/// This relay proxy also allows for correctly revealing the -/// "Read as Proxy" and "Write as Proxy" tabs on Etherscan. -/// -/// After using the registry to deploy a ERC6551 clone pointing to this relay proxy, -/// users must send 0 ETH to the clone before clicking on "Is this a proxy?" on Etherscan. -/// Verification of this relay proxy on Etherscan is optional. -contract ERC6551Proxy { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The default implementation. - bytes32 internal immutable _defaultImplementation; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor(address defaultImplementation) payable { - _defaultImplementation = bytes32(uint256(uint160(defaultImplementation))); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* FALLBACK */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - fallback() external payable virtual { - bytes32 implementation; - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, returndatasize()) // Optimization trick to change `6080604052` into `3d604052`. - implementation := sload(_ERC1967_IMPLEMENTATION_SLOT) - } - if (implementation == bytes32(0)) { - implementation = _defaultImplementation; - /// @solidity memory-safe-assembly - assembly { - // Only initialize if the calldatasize is zero, so that staticcalls to - // functions (which will have 4-byte function selectors) won't revert. - // Some users may be fine without Etherscan proxy detection and thus may - // choose to not initialize the ERC1967 implementation slot. - if iszero(calldatasize()) { sstore(_ERC1967_IMPLEMENTATION_SLOT, implementation) } - } - } - /// @solidity memory-safe-assembly - assembly { - calldatacopy(returndatasize(), returndatasize(), calldatasize()) - // forgefmt: disable-next-item - if iszero(delegatecall(gas(), implementation, - returndatasize(), calldatasize(), codesize(), returndatasize())) { - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - returndatacopy(0x00, 0x00, returndatasize()) - return(0x00, returndatasize()) - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/ERC7821.sol b/grouperBot/lib/solady/src/accounts/ERC7821.sol deleted file mode 100644 index 2f0a22b..0000000 --- a/grouperBot/lib/solady/src/accounts/ERC7821.sol +++ /dev/null @@ -1,246 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Receiver} from "./Receiver.sol"; - -/// @notice Minimal batch executor mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC7821.sol) -/// -/// @dev This contract can be inherited to create fully-fledged smart accounts. -/// If you merely want to combine approve-swap transactions into a single transaction -/// using [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), you will need to implement basic -/// [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) `isValidSignature` functionality to -/// validate signatures with `ecrecover` against the EOA address. This is necessary because some -/// signature checks skip `ecrecover` if the signer has code. For a basic EOA batch executor, -/// please refer to [BEBE](https://github.com/vectorized/bebe), which inherits from this class. -contract ERC7821 is Receiver { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Call struct for the `execute` function. - struct Call { - address to; // Replaced as `address(this)` if `address(0)`. Renamed to `to` for Ithaca Porto. - uint256 value; // Amount of native currency (i.e. Ether) to send. - bytes data; // Calldata to send with the call. - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The execution mode is not supported. - error UnsupportedExecutionMode(); - - /// @dev Cannot decode `executionData` as a batch of batches `abi.encode(bytes[])`. - error BatchOfBatchesDecodingError(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EXECUTION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Executes the calls in `executionData`. - /// Reverts and bubbles up error if any call fails. - /// - /// `executionData` encoding (single batch): - /// - If `opData` is empty, `executionData` is simply `abi.encode(calls)`. - /// - Else, `executionData` is `abi.encode(calls, opData)`. - /// See: https://eips.ethereum.org/EIPS/eip-7579 - /// - /// `executionData` encoding (batch of batches): - /// - `executionData` is `abi.encode(bytes[])`, where each element in `bytes[]` - /// is an `executionData` for a single batch. - /// - /// Supported modes: - /// - `0x01000000000000000000...`: Single batch. Does not support optional `opData`. - /// - `0x01000000000078210001...`: Single batch. Supports optional `opData`. - /// - `0x01000000000078210002...`: Batch of batches. - /// - /// For the "batch of batches" mode, each batch will be recursively passed into - /// `execute` internally with mode `0x01000000000078210001...`. - /// Useful for passing in batches signed by different signers. - /// - /// Authorization checks: - /// - If `opData` is empty, the implementation SHOULD require that - /// `msg.sender == address(this)`. - /// - If `opData` is not empty, the implementation SHOULD use the signature - /// encoded in `opData` to determine if the caller can perform the execution. - /// - If `msg.sender` is an authorized entry point, then `execute` MAY accept - /// calls from the entry point, and MAY use `opData` for specialized logic. - /// - /// `opData` may be used to store additional data for authentication, - /// paymaster data, gas limits, etc. - function execute(bytes32 mode, bytes calldata executionData) public payable virtual { - uint256 id = _executionModeId(mode); - if (id == 3) return _executeBatchOfBatches(mode, executionData); - Call[] calldata calls; - bytes calldata opData; - /// @solidity memory-safe-assembly - assembly { - if iszero(id) { - mstore(0x00, 0x7f181275) // `UnsupportedExecutionMode()`. - revert(0x1c, 0x04) - } - // Use inline assembly to extract the calls and optional `opData` efficiently. - opData.length := 0 - let o := add(executionData.offset, calldataload(executionData.offset)) - calls.offset := add(o, 0x20) - calls.length := calldataload(o) - // If the offset of `executionData` allows for `opData`, and the mode supports it. - if gt(eq(id, 2), gt(0x40, calldataload(executionData.offset))) { - let q := add(executionData.offset, calldataload(add(0x20, executionData.offset))) - opData.offset := add(q, 0x20) - opData.length := calldataload(q) - } - // Bounds checking for `executionData` is skipped here for efficiency. - // This is safe if it is only used as an argument to `execute` externally. - // If `executionData` used as an argument to other functions externally, - // please perform the bounds checks via `LibERC7579.decodeBatchAndOpData` - /// or `abi.decode` in the other functions for safety. - } - _execute(mode, executionData, calls, opData); - } - - /// @dev Provided for execution mode support detection. - function supportsExecutionMode(bytes32 mode) public view virtual returns (bool result) { - return _executionModeId(mode) != 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev 0: invalid mode, 1: no `opData` support, 2: with `opData` support, 3: batch of batches. - function _executionModeId(bytes32 mode) internal view virtual returns (uint256 id) { - // Only supports atomic batched executions. - // For the encoding scheme, see: https://eips.ethereum.org/EIPS/eip-7579 - // Bytes Layout: - // - [0] ( 1 byte ) `0x01` for batch call. - // - [1] ( 1 byte ) `0x00` for revert on any failure. - // - [2..5] ( 4 bytes) Reserved by ERC7579 for future standardization. - // - [6..9] ( 4 bytes) `0x00000000` or `0x78210001` or `0x78210002`. - // - [10..31] (22 bytes) Unused. Free for use. - /// @solidity memory-safe-assembly - assembly { - let m := and(shr(mul(22, 8), mode), 0xffff00000000ffffffff) - id := eq(m, 0x01000000000000000000) // 1. - id := or(shl(1, eq(m, 0x01000000000078210001)), id) // 2. - id := or(mul(3, eq(m, 0x01000000000078210002)), id) // 3. - } - } - - /// @dev For execution of a batch of batches. - function _executeBatchOfBatches(bytes32 mode, bytes calldata executionData) internal virtual { - // Replace with `0x0100________78210001...` while preserving optional and reserved fields. - mode ^= bytes32(uint256(3 << (22 * 8))); // `2 XOR 3 = 1`. - (uint256 n, uint256 o, uint256 e) = (0, 0, 0); - /// @solidity memory-safe-assembly - assembly { - let j := calldataload(executionData.offset) - let t := add(executionData.offset, j) - n := calldataload(t) // `batches.length`. - o := add(0x20, t) // Offset of `batches[0]`. - e := add(executionData.offset, executionData.length) // End of `executionData`. - // Do the bounds check on `executionData` treating it as `abi.encode(bytes[])`. - // Not too expensive, so we will just do it right here right now. - if or(shr(64, j), or(lt(executionData.length, 0x20), gt(add(o, shl(5, n)), e))) { - mstore(0x00, 0x3995943b) // `BatchOfBatchesDecodingError()`. - revert(0x1c, 0x04) - } - } - unchecked { - for (uint256 i; i != n; ++i) { - bytes calldata batch; - /// @solidity memory-safe-assembly - assembly { - let j := calldataload(add(o, shl(5, i))) - let t := add(o, j) - batch.offset := add(t, 0x20) - batch.length := calldataload(t) - // Validate that `batches[i]` is not out-of-bounds. - if or(shr(64, j), gt(add(batch.offset, batch.length), e)) { - mstore(0x00, 0x3995943b) // `BatchOfBatchesDecodingError()`. - revert(0x1c, 0x04) - } - } - execute(mode, batch); - } - } - } - - /// @dev Executes the calls. - /// Reverts and bubbles up error if any call fails. - /// The `mode` and `executionData` are passed along in case there's a need to use them. - function _execute( - bytes32 mode, - bytes calldata executionData, - Call[] calldata calls, - bytes calldata opData - ) internal virtual { - // Silence compiler warning on unused variables. - mode = mode; - executionData = executionData; - // Very basic auth to only allow this contract to be called by itself. - // Override this function to perform more complex auth with `opData`. - if (opData.length == uint256(0)) { - require(msg.sender == address(this)); - // Remember to return `_execute(calls, extraData)` when you override this function. - return _execute(calls, bytes32(0)); - } - revert(); // In your override, replace this with logic to operate on `opData`. - } - - /// @dev Executes the calls. - /// Reverts and bubbles up error if any call fails. - /// `extraData` can be any supplementary data (e.g. a memory pointer, some hash). - function _execute(Call[] calldata calls, bytes32 extraData) internal virtual { - unchecked { - uint256 i; - if (calls.length == uint256(0)) return; - do { - (address to, uint256 value, bytes calldata data) = _get(calls, i); - _execute(to, value, data, extraData); - } while (++i != calls.length); - } - } - - /// @dev Executes the call. - /// Reverts and bubbles up error if any call fails. - /// `extraData` can be any supplementary data (e.g. a memory pointer, some hash). - function _execute(address to, uint256 value, bytes calldata data, bytes32 extraData) - internal - virtual - { - /// @solidity memory-safe-assembly - assembly { - extraData := extraData // Silence unused variable compiler warning. - let m := mload(0x40) // Grab the free memory pointer. - calldatacopy(m, data.offset, data.length) - if iszero(call(gas(), to, value, m, data.length, codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - } - - /// @dev Convenience function for getting `calls[i]`, without bounds checks. - function _get(Call[] calldata calls, uint256 i) - internal - view - virtual - returns (address to, uint256 value, bytes calldata data) - { - /// @solidity memory-safe-assembly - assembly { - let c := add(calls.offset, calldataload(add(calls.offset, shl(5, i)))) - // Replaces `to` with `address(this)` if `address(0)` is provided. - let t := shr(96, shl(96, calldataload(c))) - to := or(mul(address(), iszero(t)), t) - value := calldataload(add(c, 0x20)) - let o := add(c, calldataload(add(c, 0x40))) - data.offset := add(o, 0x20) - data.length := calldataload(o) - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/LibEIP7702.sol b/grouperBot/lib/solady/src/accounts/LibEIP7702.sol deleted file mode 100644 index 0280cbb..0000000 --- a/grouperBot/lib/solady/src/accounts/LibEIP7702.sol +++ /dev/null @@ -1,237 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -/// @notice Library for EIP7702 operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/LibEIP7702.sol) -library LibEIP7702 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Failed to deploy the EIP7702Proxy. - error DeploymentFailed(); - - /// @dev The proxy query has failed. - error ProxyQueryFailed(); - - /// @dev Failed to change the proxy admin. - error ChangeProxyAdminFailed(); - - /// @dev Failed to upgrade the proxy. - error UpgradeProxyFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. - bytes32 internal constant ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /// @dev The transient storage slot for requesting the proxy to initialize the implementation. - /// `uint256(keccak256("eip7702.proxy.delegation.initialization.request")) - 1`. - /// While we would love to use a smaller constant, this slot is used in both the proxy - /// and the delegation, so we shall just use bytes32 in case we want to standardize this. - bytes32 internal constant EIP7702_PROXY_DELEGATION_INITIALIZATION_REQUEST_SLOT = - 0x94e11c6e41e7fb92cb8bb65e13fdfbd4eba8b831292a1a220f7915c78c7c078f; - - /// @dev The creation code for the EIP7702Proxy. - /// This is generated from `EIP7702Proxy.sol` with exact compilation settings. - bytes internal constant EIP7702_PROXY_CREATION_CODE = - hex"60c06040819052306080526102d63881900390819083398101604081905261002691610096565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8290557fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103819055811515110260a0526100c7565b80516001600160a01b0381168114610091575f5ffd5b919050565b5f5f604083850312156100a7575f5ffd5b6100b08361007b565b91506100be6020840161007b565b90509250929050565b60805160a0516101f06100e65f395f602701525f600601526101f05ff3fe60016040527f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc361960601c30841861010a576001361161008657815481165f5260205ff35b5f3560e01c80635c60da1b036100a157825482165f5260205ff35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038163f851a440036100d65780545f5260205ff35b80543303610106578382630900f01014028183638f2839701402178015610104576004358416815560206040f35b505b5f5ffd5b815481163660010361013b5780610133575082806101335760205f5f5f885afa15610106573d5ff35b805f5260205ff35b365f5f37806101a7575082806101a7576020365f5f885afa5f5f365f36515af416610168573d5f5f3e3d5ffd5b7f94e11c6e41e7fb92cb8bb65e13fdfbd4eba8b831292a1a220f7915c78c7c078f805c1561019e57365184548419161784555f815d5b503d5f5f3e3d5ff35b5f5f365f845af461019e573d5f5f3e3d5ffdfea2646970667358221220e8b1a2a38594baf32c154aa7dd7743c9cd741d4f386b5ab588a5dcd613c3a00e64736f6c634300081c0033"; - - /// @dev The keccak256 of runtime code for `EIP7702Proxy.sol` with exact compilation settings, - /// with immutables zeroized and without the CBOR metadata. - bytes32 internal constant EIP7702_PROXY_MINIMAL_CODE_HASH = - 0xf8710866f390ac7c12640457f9cb9663657ac8168b7d4ce6418a982932b3043e; - - /// @dev The length of the runtime code for `EIP7702Proxy.sol` with exact compilation settings, - /// with immutables zeroized and without the CBOR metadata. - uint256 internal constant EIP7702_PROXY_MINIMAL_CODE_LENGTH = 0x1ba; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* AUTHORITY AND PROXY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the delegation of the account. - /// If the account is not an EIP7702 authority, returns `address(0)`. - function delegationOf(address account) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - extcodecopy(account, 0x00, 0x00, 0x20) - // Note: Checking that it starts with hex"ef01" is the most general and futureproof. - // 7702 bytecode is `abi.encodePacked(hex"ef01", uint8(version), address(delegation))`. - result := mul(shr(96, mload(0x03)), eq(0xef01, shr(240, mload(0x00)))) - } - } - - /// @dev Returns the delegation and the implementation of the account. - /// If the account delegation is not a valid EIP7702Proxy, returns `address(0)`. - function delegationAndImplementationOf(address account) - internal - view - returns (address delegation, address implementation) - { - delegation = delegationOf(account); - if (isEIP7702Proxy(delegation)) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0) - if iszero(staticcall(gas(), account, 0x00, 0x01, 0x00, 0x20)) { revert(0x00, 0x00) } - implementation := mload(0x00) - } - } - } - - /// @dev Returns the implementation of `target`. - /// If `target` is neither an EIP7702Proxy nor an EOA delegated to an EIP7702Proxy, returns `address(0)`. - function implementationOf(address target) internal view returns (address result) { - if (!isEIP7702Proxy(target)) if (!isEIP7702Proxy(delegationOf(target))) return address(0); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0) - if iszero(staticcall(gas(), target, 0x00, 0x01, 0x00, 0x20)) { revert(0x00, 0x00) } - result := mload(0x00) - } - } - - /// @dev Returns if `target` is an valid EIP7702Proxy based on a bytecode hash check. - function isEIP7702Proxy(address target) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - // Copy the runtime bytecode without the CBOR metadata. - extcodecopy(target, m, 0x00, EIP7702_PROXY_MINIMAL_CODE_LENGTH) - // Zeroize the immutables. - mstore(add(m, 0x06), 0) // The first `7f`. - mstore(add(m, 0x27), 0) // The second `7f`. - let h := keccak256(m, EIP7702_PROXY_MINIMAL_CODE_LENGTH) - result := eq(EIP7702_PROXY_MINIMAL_CODE_HASH, h) - } - } - - /// @dev Returns the initialization code for the EIP7702Proxy. - function proxyInitCode(address initialImplementation, address initialAdmin) - internal - pure - returns (bytes memory) - { - return abi.encodePacked( - EIP7702_PROXY_CREATION_CODE, - uint256(uint160(initialImplementation)), - uint256(uint160(initialAdmin)) - ); - } - - /// @dev Deploys an EIP7702Proxy. - function deployProxy(address initialImplementation, address initialAdmin) - internal - returns (address instance) - { - bytes memory initCode = proxyInitCode(initialImplementation, initialAdmin); - /// @solidity memory-safe-assembly - assembly { - instance := create(0, add(initCode, 0x20), mload(initCode)) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Deploys an EIP7702Proxy to a deterministic address with `salt`. - function deployProxyDeterministic( - address initialImplementation, - address initialAdmin, - bytes32 salt - ) internal returns (address instance) { - bytes memory initCode = proxyInitCode(initialImplementation, initialAdmin); - /// @solidity memory-safe-assembly - assembly { - instance := create2(0, add(initCode, 0x20), mload(initCode), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns the admin of the proxy. - /// Assumes that the proxy is a proper EIP7702Proxy, if it exists. - function proxyAdmin(address proxy) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xf851a440) // `admin()`. - let t := staticcall(gas(), proxy, 0x1c, 0x04, 0x00, 0x20) - if iszero(and(gt(returndatasize(), 0x1f), t)) { - mstore(0x00, 0x26ec9b6a) // `ProxyQueryFailed()`. - revert(0x1c, 0x04) - } - result := mload(0x00) - } - } - - /// @dev Changes the admin on the proxy. The caller must be the admin. - /// Assumes that the proxy is a proper EIP7702Proxy, if it exists. - function changeProxyAdmin(address proxy, address newAdmin) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x8f283970) // `changeAdmin(address)`. - mstore(0x20, newAdmin) // The implementation will clean the upper 96 bits. - if iszero(and(eq(mload(0x00), 1), call(gas(), proxy, 0, 0x1c, 0x24, 0x00, 0x20))) { - mstore(0x00, 0xc502e37e) // `ChangeProxyAdminFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Changes the implementation on the proxy. The caller must be the admin. - /// Assumes that the proxy is a proper EIP7702Proxy, if it exists. - function upgradeProxy(address proxy, address newImplementation) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x0900f010) // `upgrade(address)`. - mstore(0x20, newImplementation) // The implementation will clean the upper 96 bits. - if iszero(and(eq(mload(0x00), 1), call(gas(), proxy, 0, 0x1c, 0x24, 0x00, 0x20))) { - mstore(0x00, 0xc6edd882) // `UpgradeProxyFailed()`. - revert(0x1c, 0x04) - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UUPS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Upgrades the implementation. - /// The new implementation will NOT be active until the next UserOp or transaction. - /// To "auto-upgrade" to the latest implementation on the proxy, pass in `address(0)` to reset - /// the implementation slot. This causes the proxy to use the latest default implementation, - /// which may be optionally reinitialized via `requestProxyDelegationInitialization()`. - /// This function is intended to be used on the authority of an EIP7702Proxy delegation. - /// The most intended usage pattern is to wrap this in an access-gated admin function. - function upgradeProxyDelegation(address newImplementation) internal { - /// @solidity memory-safe-assembly - assembly { - let s := ERC1967_IMPLEMENTATION_SLOT - // Preserve the upper 96 bits when updating in case they are used for some stuff. - mstore(0x00, sload(s)) - mstore(0x0c, shl(96, newImplementation)) - sstore(s, mload(0x00)) - } - } - - /// @dev Requests the implementation to be initialized to the latest implementation on the proxy. - /// This function is intended to be used on the authority of an EIP7702Proxy delegation. - /// The most intended usage pattern is to place it at the end of an `execute` function. - function requestProxyDelegationInitialization() internal { - /// @solidity memory-safe-assembly - assembly { - if iszero(shl(96, sload(ERC1967_IMPLEMENTATION_SLOT))) { - // Use a dedicated transient storage slot for better Swiss-cheese-model safety. - tstore(EIP7702_PROXY_DELEGATION_INITIALIZATION_REQUEST_SLOT, address()) - } - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/LibERC6551.sol b/grouperBot/lib/solady/src/accounts/LibERC6551.sol deleted file mode 100644 index 82afd2c..0000000 --- a/grouperBot/lib/solady/src/accounts/LibERC6551.sol +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for interacting with ERC6551 accounts. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/LibERC6551.sol) -/// @author ERC6551 team (https://github.com/erc6551/reference/blob/main/src/lib/ERC6551AccountLib.sol) -library LibERC6551 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Failed to create a ERC6551 account via the registry. - error AccountCreationFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The canonical ERC6551 registry address for EVM chains. - address internal constant REGISTRY = 0x000000006551c19487814612e58FE06813775758; - - /// @dev The canonical ERC6551 registry bytecode for EVM chains. - /// Useful for forge tests: - /// `vm.etch(REGISTRY, REGISTRY_BYTECODE)`. - bytes internal constant REGISTRY_BYTECODE = - hex"608060405234801561001057600080fd5b50600436106100365760003560e01c8063246a00211461003b5780638a54c52f1461006a575b600080fd5b61004e6100493660046101b7565b61007d565b6040516001600160a01b03909116815260200160405180910390f35b61004e6100783660046101b7565b6100e1565b600060806024608c376e5af43d82803e903d91602b57fd5bf3606c5285605d52733d60ad80600a3d3981f3363d3d373d3d3d363d7360495260ff60005360b76055206035523060601b60015284601552605560002060601b60601c60005260206000f35b600060806024608c376e5af43d82803e903d91602b57fd5bf3606c5285605d52733d60ad80600a3d3981f3363d3d373d3d3d363d7360495260ff60005360b76055206035523060601b600152846015526055600020803b61018b578560b760556000f580610157576320188a596000526004601cfd5b80606c52508284887f79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf887226060606ca46020606cf35b8060601b60601c60005260206000f35b80356001600160a01b03811681146101b257600080fd5b919050565b600080600080600060a086880312156101cf57600080fd5b6101d88661019b565b945060208601359350604086013592506101f46060870161019b565b94979396509194608001359291505056fea2646970667358221220ea2fe53af507453c64dd7c1db05549fa47a298dfb825d6d11e1689856135f16764736f6c63430008110033"; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ACCOUNT BYTECODE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the initialization code of the ERC6551 account. - function initCode( - address implementation_, - bytes32 salt_, - uint256 chainId_, - address tokenContract_, - uint256 tokenId_ - ) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) // Grab the free memory pointer.. - // Layout the variables and bytecode backwards. - mstore(add(result, 0xb7), tokenId_) - mstore(add(result, 0x97), shr(96, shl(96, tokenContract_))) - mstore(add(result, 0x77), chainId_) - mstore(add(result, 0x57), salt_) - mstore(add(result, 0x37), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(result, 0x28), implementation_) - mstore(add(result, 0x14), 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) - mstore(result, 0xb7) // Store the length. - mstore(0x40, add(result, 0xd7)) // Allocate the memory. - } - } - - /// @dev Returns the initialization code hash of the ERC6551 account. - function initCodeHash( - address implementation_, - bytes32 salt_, - uint256 chainId_, - address tokenContract_, - uint256 tokenId_ - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) // Grab the free memory pointer. - // Layout the variables and bytecode backwards. - mstore(add(result, 0xa3), tokenId_) - mstore(add(result, 0x83), shr(96, shl(96, tokenContract_))) - mstore(add(result, 0x63), chainId_) - mstore(add(result, 0x43), salt_) - mstore(add(result, 0x23), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(result, 0x14), implementation_) - mstore(result, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) - result := keccak256(add(result, 0x0c), 0xb7) - } - } - - /// @dev Creates an account via the ERC6551 registry. - function createAccount( - address implementation_, - bytes32 salt_, - uint256 chainId_, - address tokenContract_, - uint256 tokenId_ - ) internal returns (address result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(m, 0x14), implementation_) - mstore(add(m, 0x34), salt_) - mstore(add(m, 0x54), chainId_) - mstore(add(m, 0x74), shr(96, shl(96, tokenContract_))) - mstore(add(m, 0x94), tokenId_) - // `createAccount(address,bytes32,uint256,address,uint256)`. - mstore(m, 0x8a54c52f000000000000000000000000) - if iszero( - and( - gt(returndatasize(), 0x1f), - call(gas(), REGISTRY, 0, add(m, 0x10), 0xa4, 0x00, 0x20) - ) - ) { - mstore(0x00, 0x20188a59) // `AccountCreationFailed()`. - revert(0x1c, 0x04) - } - result := mload(0x00) - } - } - - /// @dev Returns the address of the ERC6551 account. - function account( - address implementation_, - bytes32 salt_, - uint256 chainId_, - address tokenContract_, - uint256 tokenId_ - ) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) // Grab the free memory pointer. - // Layout the variables and bytecode backwards. - mstore(add(result, 0xa3), tokenId_) - mstore(add(result, 0x83), shr(96, shl(96, tokenContract_))) - mstore(add(result, 0x63), chainId_) - mstore(add(result, 0x43), salt_) - mstore(add(result, 0x23), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(result, 0x14), implementation_) - mstore(result, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(add(result, 0x0c), 0xb7)) - mstore(0x01, shl(96, REGISTRY)) - mstore(0x15, salt_) - result := keccak256(0x00, 0x55) - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns if `a` is an ERC6551 account with `expectedImplementation`. - function isERC6551Account(address a, address expectedImplementation) - internal - view - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Grab the free memory pointer.. - extcodecopy(a, add(m, 0x20), 0x0a, 0xa3) - let implementation_ := shr(96, mload(add(m, 0x20))) - if mul( - extcodesize(implementation_), - gt(eq(extcodesize(a), 0xad), shl(96, xor(expectedImplementation, implementation_))) - ) { - // Layout the variables and bytecode backwards. - mstore(add(m, 0x23), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(m, 0x14), implementation_) - mstore(m, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(add(m, 0x0c), 0xb7)) - mstore(0x01, shl(96, REGISTRY)) - mstore(0x15, mload(add(m, 0x43))) - result := iszero(shl(96, xor(a, keccak256(0x00, 0x55)))) - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - } - - /// @dev Returns the implementation of the ERC6551 account `a`. - function implementation(address a) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - extcodecopy(a, 0x00, 0x0a, 0x14) - result := shr(96, mload(0x00)) - } - } - - /// @dev Returns the static variables of the ERC6551 account `a`. - function context(address a) - internal - view - returns (bytes32 salt_, uint256 chainId_, address tokenContract_, uint256 tokenId_) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - extcodecopy(a, 0x00, 0x2d, 0x80) - salt_ := mload(0x00) - chainId_ := mload(0x20) - tokenContract_ := mload(0x40) - tokenId_ := mload(0x60) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /// @dev Returns the salt of the ERC6551 account `a`. - function salt(address a) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - extcodecopy(a, 0x00, 0x2d, 0x20) - result := mload(0x00) - } - } - - /// @dev Returns the chain ID of the ERC6551 account `a`. - function chainId(address a) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - extcodecopy(a, 0x00, 0x4d, 0x20) - result := mload(0x00) - } - } - - /// @dev Returns the token contract of the ERC6551 account `a`. - function tokenContract(address a) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - extcodecopy(a, 0x00, 0x6d, 0x20) - result := mload(0x00) - } - } - - /// @dev Returns the token ID of the ERC6551 account `a`. - function tokenId(address a) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - extcodecopy(a, 0x00, 0x8d, 0x20) - result := mload(0x00) - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/LibERC7579.sol b/grouperBot/lib/solady/src/accounts/LibERC7579.sol deleted file mode 100644 index e7a601a..0000000 --- a/grouperBot/lib/solady/src/accounts/LibERC7579.sol +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for handling ERC7579 mode and execution data. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/LibERC7579.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/main/contracts/account/utils/draft-ERC7579Utils.sol) -library LibERC7579 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Cannot decode `executionData`. - error DecodingError(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A single execution. - bytes1 internal constant CALLTYPE_SINGLE = 0x00; - - /// @dev A batch of executions. - bytes1 internal constant CALLTYPE_BATCH = 0x01; - - /// @dev A single `staticcall` execution. - bytes1 internal constant CALLTYPE_STATICCALL = 0xfe; - - /// @dev A `delegatecall` execution. - bytes1 internal constant CALLTYPE_DELEGATECALL = 0xff; - - /// @dev Default execution type that reverts on failure. - bytes1 internal constant EXECTYPE_DEFAULT = 0x00; - - /// @dev Execution type that does not revert on failure. - bytes1 internal constant EXECTYPE_TRY = 0x01; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MODE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Encodes the fields into a mode. - function encodeMode(bytes1 callType, bytes1 execType, bytes4 selector, bytes22 payload) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - result := or(shl(8, byte(0, callType)), byte(0, execType)) - result := or(shr(224, selector), shl(64, result)) - result := or(shr(80, payload), shl(176, result)) - } - } - - /// @dev Returns the call type of the mode. - function getCallType(bytes32 mode) internal pure returns (bytes1) { - return bytes1(mode); - } - - /// @dev Returns the call type of the mode. - function getExecType(bytes32 mode) internal pure returns (bytes1) { - return mode[1]; - } - - /// @dev Returns the selector of the mode. - function getSelector(bytes32 mode) internal pure returns (bytes4) { - return bytes4(bytes32(uint256(mode) << 48)); - } - - /// @dev Returns the payload stored in the mode. - function getPayload(bytes32 mode) internal pure returns (bytes22) { - return bytes22(bytes32(uint256(mode) << 80)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EXECUTION DATA OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Decodes a single call execution. - /// Reverts if `executionData` is not correctly encoded. - function decodeSingle(bytes calldata executionData) - internal - pure - returns (address target, uint256 value, bytes calldata data) - { - /// @solidity memory-safe-assembly - assembly { - if iszero(gt(executionData.length, 0x33)) { - mstore(0x00, 0xba597e7e) // `DecodingError()`. - revert(0x1c, 0x04) - } - target := shr(96, calldataload(executionData.offset)) - value := calldataload(add(executionData.offset, 0x14)) - data.offset := add(executionData.offset, 0x34) - data.length := sub(executionData.length, 0x34) - } - } - - /// @dev Decodes a single call execution without bounds checks. - function decodeSingleUnchecked(bytes calldata executionData) - internal - pure - returns (address target, uint256 value, bytes calldata data) - { - /// @solidity memory-safe-assembly - assembly { - target := shr(96, calldataload(executionData.offset)) - value := calldataload(add(executionData.offset, 0x14)) - data.offset := add(executionData.offset, 0x34) - data.length := sub(executionData.length, 0x34) - } - } - - /// @dev Decodes a single delegate execution. - /// Reverts if `executionData` is not correctly encoded. - function decodeDelegate(bytes calldata executionData) - internal - pure - returns (address target, bytes calldata data) - { - /// @solidity memory-safe-assembly - assembly { - if iszero(gt(executionData.length, 0x13)) { - mstore(0x00, 0xba597e7e) // `DecodingError()`. - revert(0x1c, 0x04) - } - target := shr(96, calldataload(executionData.offset)) - data.offset := add(executionData.offset, 0x14) - data.length := sub(executionData.length, 0x14) - } - } - - /// @dev Decodes a single delegate execution without bounds checks. - function decodeDelegateUnchecked(bytes calldata executionData) - internal - pure - returns (address target, bytes calldata data) - { - /// @solidity memory-safe-assembly - assembly { - target := shr(96, calldataload(executionData.offset)) - data.offset := add(executionData.offset, 0x14) - data.length := sub(executionData.length, 0x14) - } - } - - /// @dev Decodes a batch. - /// Reverts if `executionData` is not correctly encoded. - function decodeBatch(bytes calldata executionData) - internal - pure - returns (bytes32[] calldata pointers) - { - /// @solidity memory-safe-assembly - assembly { - let u := calldataload(executionData.offset) - let s := add(executionData.offset, u) - let e := sub(add(executionData.offset, executionData.length), 0x20) - pointers.offset := add(s, 0x20) - pointers.length := calldataload(s) - if or(shr(64, u), gt(add(s, shl(5, pointers.length)), e)) { - mstore(0x00, 0xba597e7e) // `DecodingError()`. - revert(0x1c, 0x04) - } - if pointers.length { - // Perform bounds checks on the decoded `pointers`. - // Loop runs out-of-gas if `pointers.length` is big enough to cause overflows. - for { let i := pointers.length } 1 {} { - i := sub(i, 1) - let p := calldataload(add(pointers.offset, shl(5, i))) - let c := add(pointers.offset, p) - let q := calldataload(add(c, 0x40)) - let o := add(c, q) - // forgefmt: disable-next-item - if or(shr(64, or(calldataload(o), or(p, q))), - or(gt(add(c, 0x40), e), gt(add(o, calldataload(o)), e))) { - mstore(0x00, 0xba597e7e) // `DecodingError()`. - revert(0x1c, 0x04) - } - if iszero(i) { break } - } - } - } - } - - /// @dev Decodes a batch without bounds checks. - /// This function can be used in `execute`, if the validation phase has already - /// decoded the `executionData` with checks via `decodeBatch`. - function decodeBatchUnchecked(bytes calldata executionData) - internal - pure - returns (bytes32[] calldata pointers) - { - /// @solidity memory-safe-assembly - assembly { - let o := add(executionData.offset, calldataload(executionData.offset)) - pointers.offset := add(o, 0x20) - pointers.length := calldataload(o) - } - } - - /// @dev Decodes a batch and optional `opData`. - /// Reverts if `executionData` is not correctly encoded. - function decodeBatchAndOpData(bytes calldata executionData) - internal - pure - returns (bytes32[] calldata pointers, bytes calldata opData) - { - opData = emptyCalldataBytes(); - pointers = decodeBatch(executionData); - if (hasOpData(executionData)) { - /// @solidity memory-safe-assembly - assembly { - let e := sub(add(executionData.offset, executionData.length), 0x20) - let p := calldataload(add(0x20, executionData.offset)) - let q := add(executionData.offset, p) - opData.offset := add(q, 0x20) - opData.length := calldataload(q) - if or(shr(64, or(opData.length, p)), gt(add(q, opData.length), e)) { - mstore(0x00, 0xba597e7e) // `DecodingError()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Decodes a batch without bounds checks. - /// This function can be used in `execute`, if the validation phase has already - /// decoded the `executionData` with checks via `decodeBatchAndOpData`. - function decodeBatchAndOpDataUnchecked(bytes calldata executionData) - internal - pure - returns (bytes32[] calldata pointers, bytes calldata opData) - { - opData = emptyCalldataBytes(); - pointers = decodeBatchUnchecked(executionData); - if (hasOpData(executionData)) { - /// @solidity memory-safe-assembly - assembly { - let q := add(executionData.offset, calldataload(add(0x20, executionData.offset))) - opData.offset := add(q, 0x20) - opData.length := calldataload(q) - } - } - } - - /// @dev Returns whether the `executionData` has optional `opData`. - function hasOpData(bytes calldata executionData) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := - iszero(or(lt(executionData.length, 0x40), lt(calldataload(executionData.offset), 0x40))) - } - } - - /// @dev Returns the `i`th execution at `pointers`, without bounds checks. - /// The bounds check is excluded as this function is intended to be called in a bounded loop. - function getExecution(bytes32[] calldata pointers, uint256 i) - internal - pure - returns (address target, uint256 value, bytes calldata data) - { - /// @solidity memory-safe-assembly - assembly { - let c := add(pointers.offset, calldataload(add(pointers.offset, shl(5, i)))) - target := calldataload(c) - value := calldataload(add(c, 0x20)) - let o := add(c, calldataload(add(c, 0x40))) - data.offset := add(o, 0x20) - data.length := calldataload(o) - } - } - - /// @dev Reencodes `executionData` such that it has `opData` added to it. - /// Like `abi.encode(abi.decode(executionData, (Call[])), opData)`. - /// Useful for forwarding `executionData` with extra `opData`. - /// This function does not perform any check on the validity of `executionData`. - function reencodeBatch(bytes calldata executionData, bytes memory opData) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := add(0x64, mload(0x40)) // Give some space for `reencodeBatchAsExecuteCalldata`. - let s := calldataload(executionData.offset) // Offset of `calls`. - let n := sub(executionData.length, s) // Byte length of `calls`. - mstore(add(result, 0x20), 0x40) // Store the new offset of `calls`. - calldatacopy(add(result, 0x60), add(executionData.offset, s), n) - mstore(add(result, 0x40), add(0x40, n)) // Store the new offset of `opData`. - let o := add(add(result, 0x60), n) // Start offset of `opData` destination in memory. - let d := sub(opData, o) // Offset difference between `opData` source and `o`. - let end := add(mload(opData), add(0x20, o)) // End of `opData` destination in memory. - for {} 1 {} { - mstore(o, mload(add(o, d))) - o := add(o, 0x20) - if iszero(lt(o, end)) { break } - } - mstore(result, sub(o, add(result, 0x20))) // Store the length of `result`. - calldatacopy(end, calldatasize(), 0x40) // Zeroize the bytes after `end`. - mstore(0x40, add(0x20, o)) // Allocate memory. - } - } - - /// @dev `abi.encodeWithSignature("execute(bytes32,bytes)", mode, reencodeBatch(executionData, opData))`. - function reencodeBatchAsExecuteCalldata( - bytes32 mode, - bytes calldata executionData, - bytes memory opData - ) internal pure returns (bytes memory result) { - result = reencodeBatch(executionData, opData); - /// @solidity memory-safe-assembly - assembly { - let n := mload(result) - result := sub(result, 0x64) - mstore(add(result, 0x44), 0x40) // Offset of `executionData`. - mstore(add(result, 0x24), mode) - mstore(add(result, 0x04), 0xe9ae5c53) // `execute(bytes32,bytes)`. - mstore(result, add(0x64, n)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper function to return empty calldata bytes. - function emptyCalldataBytes() internal pure returns (bytes calldata result) { - /// @solidity memory-safe-assembly - assembly { - result.offset := 0 - result.length := 0 - } - } -} diff --git a/grouperBot/lib/solady/src/accounts/Receiver.sol b/grouperBot/lib/solady/src/accounts/Receiver.sol deleted file mode 100644 index aa8af05..0000000 --- a/grouperBot/lib/solady/src/accounts/Receiver.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Receiver mixin for ETH and safe-transferred ERC721 and ERC1155 tokens. -/// @author Solady (https://github.com/Vectorized/solady/blob/main/src/accounts/Receiver.sol) -/// -/// @dev Note: -/// - Handles all ERC721 and ERC1155 token safety callbacks. -/// - Collapses function table gas overhead and code size. -/// - Utilizes fallback so unknown calldata will pass on. -abstract contract Receiver { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The function selector is not recognized. - error FnSelectorNotRecognized(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RECEIVE / FALLBACK */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For receiving ETH. - receive() external payable virtual {} - - /// @dev Fallback function with the `receiverFallback` modifier. - fallback() external payable virtual receiverFallback { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x3c10b94e) // `FnSelectorNotRecognized()`. - revert(0x1c, 0x04) - } - } - - /// @dev Modifier for the fallback function to handle token callbacks. - modifier receiverFallback() virtual { - _beforeReceiverFallbackBody(); - if (_useReceiverFallbackBody()) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, calldataload(0)) - // 0x150b7a02: `onERC721Received(address,address,uint256,bytes)`. - // 0xf23a6e61: `onERC1155Received(address,address,uint256,uint256,bytes)`. - // 0xbc197c81: `onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)`. - if or(eq(s, 0x150b7a02), or(eq(s, 0xf23a6e61), eq(s, 0xbc197c81))) { - // Assumes `mload(0x40) <= 0xffffffff` to save gas on cleaning lower bytes. - mstore(0x20, s) // Store `msg.sig`. - return(0x3c, 0x20) // Return `msg.sig`. - } - } - } - _afterReceiverFallbackBody(); - _; - } - - /// @dev Whether we want to use the body of the `receiverFallback` modifier. - function _useReceiverFallbackBody() internal view virtual returns (bool) { - return true; - } - - /// @dev Called before the body of the `receiverFallback` modifier. - function _beforeReceiverFallbackBody() internal virtual {} - - /// @dev Called after the body of the `receiverFallback` modifier. - function _afterReceiverFallbackBody() internal virtual {} -} diff --git a/grouperBot/lib/solady/src/accounts/Timelock.sol b/grouperBot/lib/solady/src/accounts/Timelock.sol deleted file mode 100644 index 0a80f1d..0000000 --- a/grouperBot/lib/solady/src/accounts/Timelock.sol +++ /dev/null @@ -1,450 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC7821} from "./ERC7821.sol"; -import {LibERC7579} from "./LibERC7579.sol"; -import {EnumerableRoles} from "../auth/EnumerableRoles.sol"; - -/// @notice Simple timelock. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/Timelock.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/TimelockController.sol) -/// -/// @dev Note: -/// - This implementation only supports ERC7821 style execution. -/// - This implementation uses EnumerableRoles for better auditability. -/// - This implementation uses custom errors with arguments for easier debugging. -/// - `executionData` can be encoded in three different ways: -/// 1. `abi.encode(calls)`. -/// 2. `abi.encode(calls, abi.encode(predecessor))`. -/// 3. `abi.encode(calls, abi.encode(predecessor, salt))`. -/// - Where `calls` is of type `(address,uint256,bytes)[]`, and -/// `predecessor` is the id of the proposal that is required to be already executed. -/// - If `predecessor` is `bytes32(0)`, it will be ignored (treated as if not required). -/// - The optional `salt` allows for multiple proposals representing the same payload. -/// - The proposal id is given by: -/// `keccak256(abi.encode(mode, keccak256(executionData)))`. -/// -/// We recommended including the salt, even though it is optional for convenience. -/// -/// Supported modes: -/// - `bytes32(0x01000000000000000000...)`: does not support optional `opData`. -/// - `bytes32(0x01000000000078210001...)`: supports optional `opData`. -/// Where `opData` is `abi.encode(predecessor)` or `abi.encode(predecessor, salt)`, -/// and `...` is the remaining 22 bytes which can be anything. -/// For ease of mind, just use: -/// `0x0100000000007821000100000000000000000000000000000000000000000000`. -contract Timelock is ERC7821, EnumerableRoles { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Role that can add / remove roles without wait time. - /// This role cannot directly propose, execute, or cancel. - /// This role is NOT exempt from the execution wait time. - uint256 public constant ADMIN_ROLE = 0; - - /// @dev Role that can propose operations. - uint256 public constant PROPOSER_ROLE = 1; - - /// @dev Role that can execute operations. - uint256 public constant EXECUTOR_ROLE = 2; - - /// @dev Role that can cancel proposed operations. - uint256 public constant CANCELLER_ROLE = 3; - - /// @dev The maximum role. - uint256 public constant MAX_ROLE = 3; - - /// @dev Assign this holder to a role to allow anyone to call - /// the function guarded by `onlyRoleOrOpenRole`. - address public constant OPEN_ROLE_HOLDER = 0x0303030303030303030303030303030303030303; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ENUMS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Represents the state of an operation. - enum OperationState { - Unset, // 0. - Waiting, // 1. - Ready, // 2. - Done // 3. - - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The proposed operation has insufficient delay. - error TimelockInsufficientDelay(uint256 delay, uint256 minDelay); - - /// @dev The operation cannot be performed. - /// The `expectedStates` is a bitmap with the bits enabled for - /// each enum position, starting from the least significant bit. - error TimelockInvalidOperation(bytes32 id, uint256 expectedStates); - - /// @dev The operation has a predecessor that has not been executed. - error TimelockUnexecutedPredecessor(bytes32 predecessor); - - /// @dev Unauthorized to call the function. - error TimelockUnauthorized(); - - /// @dev The delay cannot be greater than `2 ** 254 - 1`. - error TimelockDelayOverflow(); - - /// @dev The timelock has already been initialized. - error TimelockAlreadyInitialized(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage slot for the timelock's minimum delay. - /// We restrict the `minDelay` to be less than `2 ** 254 - 1`, and store the negation of it. - /// This allows us to check if it has been initialized via a non-zero check. - /// Slot of operation `id` is given by: - /// ``` - /// mstore(0x09, _TIMELOCK_SLOT) - /// mstore(0x00, id) - /// let operationIdSlot := keccak256(0x00, 0x29) - /// ``` - /// Bits layout: - /// - [0] `done`. - /// - [1..255] `readyTimestamp`. - uint256 private constant _TIMELOCK_SLOT = 0x477f2812565c76a73f; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For guarding `initialize` if not via a delegate call. - uint256 private immutable __timelockSelf = uint256(uint160(address(this))); - - /// @dev For guarding `initialize` if not via a delegate call. - uint256 private immutable __timelockDeployer = uint256(uint160(address(msg.sender))); - - /// @dev For guarding `initialize` if not via a delegate call. - uint256 private immutable __timelockDeployerOrigin = uint256(uint160(address(tx.origin))); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The proposal `id` has been created. - event Proposed(bytes32 indexed id, bytes32 mode, bytes executionData, uint256 readyTimestamp); - - /// @dev The proposal `id` has been executed. - event Executed(bytes32 indexed id, bytes32 mode, bytes executionData); - - /// @dev The proposal `id` has been cancelled. - event Cancelled(bytes32 indexed id); - - /// @dev The minimum delay has been set to `newMinDelay`. - event MinDelaySet(uint256 newMinDelay); - - /// @dev `keccak256(bytes("Proposed(bytes32,bytes32,bytes,uint256)"))`. - uint256 private constant _PROPOSED_EVENT_SIGNATURE = - 0x9b40ebcd599cbeb62eedb5e0c1db0879688a09d169ab92dbed4957d49a44b671; - - /// @dev `keccak256(bytes("Executed(bytes32,bytes32,bytes)"))`. - uint256 private constant _EXECUTED_EVENT_SIGNATURE = - 0xb1fdd61c3a5405a73ea1f8fb29bfd62c6152241cb59843d3def17bfadb7cb0bf; - - /// @dev `keccak256(bytes("Cancelled(bytes32)"))`. - uint256 private constant _CANCELLED_EVENT_SIGNATURE = - 0xbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb70; - - /// @dev `keccak256(bytes("MinDelaySet(uint256)"))`. - uint256 private constant _MIN_DELAY_SET_EVENT_SIGNATURE = - 0x496c64b8781f4ad77f1c285beea54cc413b72276389ad6dd916ea2841395e63d; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INITIALIZER */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Initializes the timelock contract. - function initialize( - uint256 initialMinDelay, - address initialAdmin, - address[] calldata proposers, - address[] calldata executors, - address[] calldata cancellers - ) public virtual { - _initializeTimelockAuthorizationCheck(); - /// @solidity memory-safe-assembly - assembly { - if shr(254, initialMinDelay) { - mstore(0x00, 0xd1efaf25) // `TimelockDelayOverflow()`. - revert(0x1c, 0x04) - } - let s := _TIMELOCK_SLOT - if sload(s) { - mstore(0x00, 0xc44f149c) // `TimelockAlreadyInitialized()`. - revert(0x1c, 0x04) - } - sstore(s, not(initialMinDelay)) - mstore(0x00, initialMinDelay) - log1(0x00, 0x20, _MIN_DELAY_SET_EVENT_SIGNATURE) - } - if (initialAdmin != address(0)) { - _setRole(initialAdmin, ADMIN_ROLE, true); - } - _bulkSetRole(proposers, PROPOSER_ROLE, true); - _bulkSetRole(executors, EXECUTOR_ROLE, true); - _bulkSetRole(cancellers, CANCELLER_ROLE, true); - } - - /// @dev The Timelock is best used via a minimal proxy. - /// But in case it is not, we want to guard `initialize` from frontrun griefing. - /// Authorizing both `msg.sender` and `tx.origin` caters to the use case where - /// the Timelock is being deployed via a factory (e.g. Nicks, CreateX). - /// - /// Always call `initialize` as soon as possible after deployment. - /// In the rare case where `msg.sender` or `tx.origin` are untrusted - /// and abused to frontrun, `initialize` will revert on reinitialization, - /// so you will know that the deployment is compromised and must be discarded. - function _initializeTimelockAuthorizationCheck() internal virtual { - uint256 self = __timelockSelf; - uint256 deployer = __timelockDeployer; - uint256 deployerOrigin = __timelockDeployerOrigin; - /// @solidity memory-safe-assembly - assembly { - if eq(self, address()) { - if iszero(or(eq(caller(), deployer), eq(caller(), deployerOrigin))) { - mstore(0x00, 0x55140ae8) // `TimelockUnauthorized()`. - revert(0x1c, 0x04) - } - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC UPDATE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Proposes an execute payload (`mode`, `executionData`) with `delay`. - /// Emits a {Proposed} event. - function propose(bytes32 mode, bytes calldata executionData, uint256 delay) - public - virtual - onlyRole(PROPOSER_ROLE) - returns (bytes32 id) - { - LibERC7579.decodeBatchAndOpData(executionData); // Check if properly encoded. - uint256 t = minDelay(); - /// @solidity memory-safe-assembly - assembly { - if shr(254, delay) { - mstore(0x00, 0xd1efaf25) // `TimelockDelayOverflow()`. - revert(0x1c, 0x04) - } - if lt(delay, t) { - mstore(0x00, 0x54336609) // `TimelockInsufficientDelay(uint256,uint256)`. - mstore(0x20, delay) - mstore(0x40, t) - revert(0x1c, 0x44) - } - let m := mload(0x40) - calldatacopy(add(m, 0x80), executionData.offset, executionData.length) - mstore(0x00, mode) - mstore(0x20, keccak256(add(m, 0x80), executionData.length)) - id := keccak256(0x00, 0x40) - mstore(0x09, _TIMELOCK_SLOT) - mstore(0x00, id) - let s := keccak256(0x00, 0x29) // Operation slot. - if sload(s) { - mstore(0x00, 0xd639b0bf) // `TimelockInvalidOperation(bytes32,uint256)`. - mstore(0x20, id) - mstore(0x40, 1) // `1 << OperationState.Unset` - revert(0x1c, 0x44) - } - // Emits the {Proposed} event. - mstore(m, mode) - mstore(add(m, 0x20), 0x60) - let r := add(delay, timestamp()) // `readyTimestamp`. - sstore(s, shl(1, r)) // Update the operation in the storage. - mstore(add(m, 0x40), r) - mstore(add(m, 0x60), executionData.length) - // Some indexers require the bytes to be zero-right padded. - mstore(add(add(m, 0x80), executionData.length), 0) // Zeroize the slot after the end. - // forgefmt: disable-next-item - log2(m, add(0x80, and(not(0x1f), add(0x1f, executionData.length))), - _PROPOSED_EVENT_SIGNATURE, id) - } - } - - /// @dev Cancels the operation with `id`. - /// Emits a {Cancelled} event. - function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x09, _TIMELOCK_SLOT) - mstore(0x00, id) - let s := keccak256(0x00, 0x29) // Operation slot. - let p := sload(s) - if or(and(1, p), iszero(p)) { - mstore(0x00, 0xd639b0bf) // `TimelockInvalidOperation(bytes32,uint256)`. - mstore(0x20, id) - mstore(0x40, 6) // `(1 << OperationState.Waiting) | (1 << OperationState.Ready)` - revert(0x1c, 0x44) - } - sstore(s, 0) // Clears the operation's storage slot. - // Emits the {Cancelled} event. - log2(0x00, 0x00, _CANCELLED_EVENT_SIGNATURE, id) - } - } - - /// @dev Allows the timelock itself to set the minimum delay. - /// Emits a {MinDelaySet} event. - function setMinDelay(uint256 newMinDelay) public virtual { - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(caller(), address())) { - mstore(0x00, 0x55140ae8) // `TimelockUnauthorized()`. - revert(0x1c, 0x04) - } - if shr(254, newMinDelay) { - mstore(0x00, 0xd1efaf25) // `TimelockDelayOverflow()`. - revert(0x1c, 0x04) - } - sstore(_TIMELOCK_SLOT, not(newMinDelay)) - // Emits the {SetMinDelay} event. - mstore(0x00, newMinDelay) - log1(0x00, 0x20, _MIN_DELAY_SET_EVENT_SIGNATURE) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC VIEW FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the minimum delay. - function minDelay() public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := not(sload(_TIMELOCK_SLOT)) - } - } - - /// @dev Returns the ready timestamp for `id`. - function readyTimestamp(bytes32 id) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x09, _TIMELOCK_SLOT) - mstore(0x00, id) - result := shr(1, sload(keccak256(0x00, 0x29))) - } - } - - /// @dev Returns the current operation state of `id`. - function operationState(bytes32 id) public view virtual returns (OperationState result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x09, _TIMELOCK_SLOT) - mstore(0x00, id) - result := sload(keccak256(0x00, 0x29)) - // forgefmt: disable-next-item - result := mul(iszero(iszero(result)), - add(and(result, 1), sub(2, lt(timestamp(), shr(1, result))))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper to set roles in bulk. - function _bulkSetRole(address[] calldata addresses, uint256 role, bool active) - internal - virtual - { - for (uint256 i; i != addresses.length;) { - address a; - /// @solidity memory-safe-assembly - assembly { - a := calldataload(add(addresses.offset, shl(5, i))) - i := add(i, 1) - } - _setRole(a, role, active); - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OVERRIDES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For ERC7821. - /// To ensure that the function can only be called by the proper role holder. - /// To ensure that the operation is ready to be executed. - /// Updates the operation state and emits a {Executed} event after the calls. - function _execute( - bytes32 mode, - bytes calldata executionData, - Call[] calldata calls, - bytes calldata opData - ) internal virtual override(ERC7821) { - if (!hasRole(OPEN_ROLE_HOLDER, EXECUTOR_ROLE)) _checkRole(EXECUTOR_ROLE); - bytes32 id; - uint256 s; - /// @solidity memory-safe-assembly - assembly { - // Copies the `executionData` for the event and to compute the `id`. - calldatacopy(mload(0x40), executionData.offset, executionData.length) - mstore(0x00, mode) - mstore(0x20, keccak256(mload(0x40), executionData.length)) - id := keccak256(0x00, 0x40) - mstore(0x09, _TIMELOCK_SLOT) - mstore(0x00, id) - s := keccak256(0x00, 0x29) - let p := sload(s) - if or(or(and(1, p), iszero(p)), lt(timestamp(), shr(1, p))) { - mstore(0x00, 0xd639b0bf) // `TimelockInvalidOperation(bytes32,uint256)`. - mstore(0x20, id) - mstore(0x40, 4) // `1 << OperationState.Ready` - revert(0x1c, 0x44) - } - // Check if optional predecessor has been executed. - if iszero(lt(opData.length, 0x20)) { - let b := calldataload(opData.offset) // Predecessor's id. - mstore(0x00, b) // `_TIMELOCK_SLOT` is already at `0x09`. - if iszero(or(iszero(b), and(1, sload(keccak256(0x00, 0x29))))) { - mstore(0x00, 0x90a9a618) // `TimelockUnexecutedPredecessor(bytes32)`. - mstore(0x20, b) - revert(0x1c, 0x24) - } - } - } - _execute(calls, id); - /// @solidity memory-safe-assembly - assembly { - // Recheck the operation after the calls, in case of reentrancy. - let p := sload(s) - if or(or(and(1, p), iszero(p)), lt(timestamp(), shr(1, p))) { - mstore(0x00, 0xd639b0bf) // `TimelockInvalidOperation(bytes32,uint256)`. - mstore(0x20, id) - mstore(0x40, 4) // `1 << OperationState.Ready` - revert(0x1c, 0x44) - } - let m := mload(0x40) - // Copies the `executionData` for the event. - calldatacopy(add(m, 0x60), executionData.offset, executionData.length) - // Emits the {Executed} event. - mstore(m, mode) - mstore(add(m, 0x20), 0x40) - mstore(add(m, 0x40), executionData.length) - // Some indexers require the bytes to be zero-right padded. - mstore(add(add(m, 0x60), executionData.length), 0) // Zeroize the slot after the end. - // forgefmt: disable-next-item - log2(m, add(0x60, and(not(0x1f), add(0x1f, executionData.length))), - _EXECUTED_EVENT_SIGNATURE, id) - sstore(s, or(1, p)) // Set the operation as executed in the storage. - } - } - - /// @dev This guards the public `setRole` function, - /// such that it can only be called by the timelock itself, or an admin. - function _authorizeSetRole(address, uint256, bool) internal virtual override(EnumerableRoles) { - if (msg.sender != address(this)) _checkRole(ADMIN_ROLE); - } -} diff --git a/grouperBot/lib/solady/src/auth/EnumerableRoles.sol b/grouperBot/lib/solady/src/auth/EnumerableRoles.sol deleted file mode 100644 index 19164b3..0000000 --- a/grouperBot/lib/solady/src/auth/EnumerableRoles.sol +++ /dev/null @@ -1,315 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Enumerable multiroles authorization mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/EnumerableRoles.sol) -/// -/// @dev Note: -/// This implementation is agnostic to the Ownable that the contract inherits from. -/// It performs a self-staticcall to the `owner()` function to determine the owner. -/// This is useful for situations where the contract inherits from -/// OpenZeppelin's Ownable, such as in LayerZero's OApp contracts. -/// -/// This implementation performs a self-staticcall to `MAX_ROLE()` to determine -/// the maximum role that can be set/unset. If the inheriting contract does not -/// have `MAX_ROLE()`, then any role can be set/unset. -/// -/// This implementation allows for any uint256 role, -/// it does NOT take in a bitmask of roles. -/// This is to accommodate teams that are allergic to bitwise flags. -/// -/// By default, the `owner()` is the only account that is authorized to set roles. -/// This behavior can be changed via overrides. -/// -/// This implementation is compatible with any Ownable. -/// This implementation is NOT compatible with OwnableRoles. -abstract contract EnumerableRoles { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The status of `role` for `holder` has been set to `active`. - event RoleSet(address indexed holder, uint256 indexed role, bool indexed active); - - /// @dev `keccak256(bytes("RoleSet(address,uint256,bool)"))`. - uint256 private constant _ROLE_SET_EVENT_SIGNATURE = - 0xaddc47d7e02c95c00ec667676636d772a589ffbf0663cfd7cd4dd3d4758201b8; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The index is out of bounds of the role holders array. - error RoleHoldersIndexOutOfBounds(); - - /// @dev Cannot set the role of the zero address. - error RoleHolderIsZeroAddress(); - - /// @dev The role has exceeded the maximum role. - error InvalidRole(); - - /// @dev Unauthorized to perform the action. - error EnumerableRolesUnauthorized(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage layout of the holders enumerable mapping is given by: - /// ``` - /// mstore(0x18, holder) - /// mstore(0x04, _ENUMERABLE_ROLES_SLOT_SEED) - /// mstore(0x00, role) - /// let rootSlot := keccak256(0x00, 0x24) - /// let positionSlot := keccak256(0x00, 0x38) - /// let holderSlot := add(rootSlot, sload(positionSlot)) - /// let holderInStorage := shr(96, sload(holderSlot)) - /// let length := shr(160, shl(160, sload(rootSlot))) - /// ``` - uint256 private constant _ENUMERABLE_ROLES_SLOT_SEED = 0xee9853bb; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC UPDATE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the status of `role` of `holder` to `active`. - function setRole(address holder, uint256 role, bool active) public payable virtual { - _authorizeSetRole(holder, role, active); - _setRole(holder, role, active); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC READ FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if `holder` has active `role`. - function hasRole(address holder, uint256 role) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x18, holder) - mstore(0x04, _ENUMERABLE_ROLES_SLOT_SEED) - mstore(0x00, role) - result := iszero(iszero(sload(keccak256(0x00, 0x38)))) - } - } - - /// @dev Returns an array of the holders of `role`. - function roleHolders(uint256 role) public view virtual returns (address[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x04, _ENUMERABLE_ROLES_SLOT_SEED) - mstore(0x00, role) - let rootSlot := keccak256(0x00, 0x24) - let rootPacked := sload(rootSlot) - let n := shr(160, shl(160, rootPacked)) - let o := add(0x20, result) - mstore(o, shr(96, rootPacked)) - for { let i := 1 } lt(i, n) { i := add(i, 1) } { - mstore(add(o, shl(5, i)), shr(96, sload(add(rootSlot, i)))) - } - mstore(result, n) - mstore(0x40, add(o, shl(5, n))) - } - } - - /// @dev Returns the total number of holders of `role`. - function roleHolderCount(uint256 role) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ENUMERABLE_ROLES_SLOT_SEED) - mstore(0x00, role) - result := shr(160, shl(160, sload(keccak256(0x00, 0x24)))) - } - } - - /// @dev Returns the holder of `role` at the index `i`. - function roleHolderAt(uint256 role, uint256 i) public view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ENUMERABLE_ROLES_SLOT_SEED) - mstore(0x00, role) - let rootSlot := keccak256(0x00, 0x24) - let rootPacked := sload(rootSlot) - if iszero(lt(i, shr(160, shl(160, rootPacked)))) { - mstore(0x00, 0x5694da8e) // `RoleHoldersIndexOutOfBounds()`. - revert(0x1c, 0x04) - } - result := shr(96, rootPacked) - if i { result := shr(96, sload(add(rootSlot, i))) } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Set the role for holder directly without authorization guard. - function _setRole(address holder, uint256 role, bool active) internal virtual { - _validateRole(role); - /// @solidity memory-safe-assembly - assembly { - let holder_ := shl(96, holder) - if iszero(holder_) { - mstore(0x00, 0x82550143) // `RoleHolderIsZeroAddress()`. - revert(0x1c, 0x04) - } - mstore(0x18, holder) - mstore(0x04, _ENUMERABLE_ROLES_SLOT_SEED) - mstore(0x00, role) - let rootSlot := keccak256(0x00, 0x24) - let n := shr(160, shl(160, sload(rootSlot))) - let positionSlot := keccak256(0x00, 0x38) - let position := sload(positionSlot) - for {} 1 {} { - if iszero(active) { - if iszero(position) { break } - let nSub := sub(n, 1) - if iszero(eq(sub(position, 1), nSub)) { - let lastHolder_ := shl(96, shr(96, sload(add(rootSlot, nSub)))) - sstore(add(rootSlot, sub(position, 1)), lastHolder_) - sstore(add(rootSlot, nSub), 0) - mstore(0x24, lastHolder_) - sstore(keccak256(0x00, 0x38), position) - } - sstore(rootSlot, or(shl(96, shr(96, sload(rootSlot))), nSub)) - sstore(positionSlot, 0) - break - } - if iszero(position) { - sstore(add(rootSlot, n), holder_) - sstore(positionSlot, add(n, 1)) - sstore(rootSlot, add(sload(rootSlot), 1)) - } - break - } - // forgefmt: disable-next-item - log4(0x00, 0x00, _ROLE_SET_EVENT_SIGNATURE, shr(96, holder_), role, iszero(iszero(active))) - } - } - - /// @dev Requires the role is not greater than `MAX_ROLE()`. - /// If `MAX_ROLE()` is not implemented, this is an no-op. - function _validateRole(uint256 role) internal view virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xd24f19d5) // `MAX_ROLE()`. - if and( - and(gt(role, mload(0x00)), gt(returndatasize(), 0x1f)), - staticcall(gas(), address(), 0x1c, 0x04, 0x00, 0x20) - ) { - mstore(0x00, 0xd954416a) // `InvalidRole()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Checks that the caller is authorized to set the role. - function _authorizeSetRole(address holder, uint256 role, bool active) internal virtual { - if (!_enumerableRolesSenderIsContractOwner()) _revertEnumerableRolesUnauthorized(); - // Silence compiler warning on unused variables. - (holder, role, active) = (holder, role, active); - } - - /// @dev Returns if `holder` has any roles in `encodedRoles`. - /// `encodedRoles` is `abi.encode(SAMPLE_ROLE_0, SAMPLE_ROLE_1, ...)`. - function _hasAnyRoles(address holder, bytes memory encodedRoles) - internal - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x18, holder) - mstore(0x04, _ENUMERABLE_ROLES_SLOT_SEED) - let end := add(encodedRoles, shl(5, shr(5, mload(encodedRoles)))) - for {} lt(result, lt(encodedRoles, end)) {} { - encodedRoles := add(0x20, encodedRoles) - mstore(0x00, mload(encodedRoles)) - result := sload(keccak256(0x00, 0x38)) - } - result := iszero(iszero(result)) - } - } - - /// @dev Reverts if `msg.sender` does not have `role`. - function _checkRole(uint256 role) internal view virtual { - if (!hasRole(msg.sender, role)) _revertEnumerableRolesUnauthorized(); - } - - /// @dev Reverts if `msg.sender` does not have any role in `encodedRoles`. - function _checkRoles(bytes memory encodedRoles) internal view virtual { - if (!_hasAnyRoles(msg.sender, encodedRoles)) _revertEnumerableRolesUnauthorized(); - } - - /// @dev Reverts if `msg.sender` is not the contract owner and does not have `role`. - function _checkOwnerOrRole(uint256 role) internal view virtual { - if (!_enumerableRolesSenderIsContractOwner()) _checkRole(role); - } - - /// @dev Reverts if `msg.sender` is not the contract owner and - /// does not have any role in `encodedRoles`. - function _checkOwnerOrRoles(bytes memory encodedRoles) internal view virtual { - if (!_enumerableRolesSenderIsContractOwner()) _checkRoles(encodedRoles); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MODIFIERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Marks a function as only callable by an account with `role`. - modifier onlyRole(uint256 role) virtual { - _checkRole(role); - _; - } - - /// @dev Marks a function as only callable by an account with any role in `encodedRoles`. - /// `encodedRoles` is `abi.encode(SAMPLE_ROLE_0, SAMPLE_ROLE_1, ...)`. - modifier onlyRoles(bytes memory encodedRoles) virtual { - _checkRoles(encodedRoles); - _; - } - - /// @dev Marks a function as only callable by the owner or by an account with `role`. - modifier onlyOwnerOrRole(uint256 role) virtual { - _checkOwnerOrRole(role); - _; - } - - /// @dev Marks a function as only callable by the owner or - /// by an account with any role in `encodedRoles`. - /// Checks for ownership first, then checks for roles. - /// `encodedRoles` is `abi.encode(SAMPLE_ROLE_0, SAMPLE_ROLE_1, ...)`. - modifier onlyOwnerOrRoles(bytes memory encodedRoles) virtual { - _checkOwnerOrRoles(encodedRoles); - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if the `msg.sender` is equal to `owner()` on this contract. - /// If the contract does not have `owner()` implemented, returns false. - function _enumerableRolesSenderIsContractOwner() private view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x8da5cb5b) // `owner()`. - result := - and( - and(eq(caller(), mload(0x00)), gt(returndatasize(), 0x1f)), - staticcall(gas(), address(), 0x1c, 0x04, 0x00, 0x20) - ) - } - } - - /// @dev Reverts with `EnumerableRolesUnauthorized()`. - function _revertEnumerableRolesUnauthorized() private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x99152cca) // `EnumerableRolesUnauthorized()`. - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/auth/Ownable.sol b/grouperBot/lib/solady/src/auth/Ownable.sol deleted file mode 100644 index a9d3214..0000000 --- a/grouperBot/lib/solady/src/auth/Ownable.sol +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple single owner authorization mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol) -/// -/// @dev Note: -/// This implementation does NOT auto-initialize the owner to `msg.sender`. -/// You MUST call the `_initializeOwner` in the constructor / initializer. -/// -/// While the ownable portion follows -/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility, -/// the nomenclature for the 2-step ownership handover may be unique to this codebase. -abstract contract Ownable { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The caller is not authorized to call the function. - error Unauthorized(); - - /// @dev The `newOwner` cannot be the zero address. - error NewOwnerIsZeroAddress(); - - /// @dev The `pendingOwner` does not have a valid handover request. - error NoHandoverRequest(); - - /// @dev Cannot double-initialize. - error AlreadyInitialized(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ownership is transferred from `oldOwner` to `newOwner`. - /// This event is intentionally kept the same as OpenZeppelin's Ownable to be - /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), - /// despite it not being as lightweight as a single argument event. - event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); - - /// @dev An ownership handover to `pendingOwner` has been requested. - event OwnershipHandoverRequested(address indexed pendingOwner); - - /// @dev The ownership handover to `pendingOwner` has been canceled. - event OwnershipHandoverCanceled(address indexed pendingOwner); - - /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`. - uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE = - 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0; - - /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`. - uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE = - 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d; - - /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`. - uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE = - 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The owner slot is given by: - /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`. - /// It is intentionally chosen to be a high value - /// to avoid collision with lower slots. - /// The choice of manual storage layout is to enable compatibility - /// with both regular and upgradeable contracts. - bytes32 internal constant _OWNER_SLOT = - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927; - - /// The ownership handover slot of `newOwner` is given by: - /// ``` - /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED)) - /// let handoverSlot := keccak256(0x00, 0x20) - /// ``` - /// It stores the expiry timestamp of the two-step ownership handover. - uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Override to return true to make `_initializeOwner` prevent double-initialization. - function _guardInitializeOwner() internal pure virtual returns (bool guard) {} - - /// @dev Initializes the owner directly without authorization guard. - /// This function must be called upon initialization, - /// regardless of whether the contract is upgradeable or not. - /// This is to enable generalization to both regular and upgradeable contracts, - /// and to save gas in case the initial owner is not the caller. - /// For performance reasons, this function will not check if there - /// is an existing owner. - function _initializeOwner(address newOwner) internal virtual { - if (_guardInitializeOwner()) { - /// @solidity memory-safe-assembly - assembly { - let ownerSlot := _OWNER_SLOT - if sload(ownerSlot) { - mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`. - revert(0x1c, 0x04) - } - // Clean the upper 96 bits. - newOwner := shr(96, shl(96, newOwner)) - // Store the new value. - sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner)))) - // Emit the {OwnershipTransferred} event. - log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) - } - } else { - /// @solidity memory-safe-assembly - assembly { - // Clean the upper 96 bits. - newOwner := shr(96, shl(96, newOwner)) - // Store the new value. - sstore(_OWNER_SLOT, newOwner) - // Emit the {OwnershipTransferred} event. - log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) - } - } - } - - /// @dev Sets the owner directly without authorization guard. - function _setOwner(address newOwner) internal virtual { - if (_guardInitializeOwner()) { - /// @solidity memory-safe-assembly - assembly { - let ownerSlot := _OWNER_SLOT - // Clean the upper 96 bits. - newOwner := shr(96, shl(96, newOwner)) - // Emit the {OwnershipTransferred} event. - log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) - // Store the new value. - sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner)))) - } - } else { - /// @solidity memory-safe-assembly - assembly { - let ownerSlot := _OWNER_SLOT - // Clean the upper 96 bits. - newOwner := shr(96, shl(96, newOwner)) - // Emit the {OwnershipTransferred} event. - log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) - // Store the new value. - sstore(ownerSlot, newOwner) - } - } - } - - /// @dev Throws if the sender is not the owner. - function _checkOwner() internal view virtual { - /// @solidity memory-safe-assembly - assembly { - // If the caller is not the stored owner, revert. - if iszero(eq(caller(), sload(_OWNER_SLOT))) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns how long a two-step ownership handover is valid for in seconds. - /// Override to return a different value if needed. - /// Made internal to conserve bytecode. Wrap it in a public function if needed. - function _ownershipHandoverValidFor() internal view virtual returns (uint64) { - return 48 * 3600; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC UPDATE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Allows the owner to transfer the ownership to `newOwner`. - function transferOwnership(address newOwner) public payable virtual onlyOwner { - /// @solidity memory-safe-assembly - assembly { - if iszero(shl(96, newOwner)) { - mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`. - revert(0x1c, 0x04) - } - } - _setOwner(newOwner); - } - - /// @dev Allows the owner to renounce their ownership. - function renounceOwnership() public payable virtual onlyOwner { - _setOwner(address(0)); - } - - /// @dev Request a two-step ownership handover to the caller. - /// The request will automatically expire in 48 hours (172800 seconds) by default. - function requestOwnershipHandover() public payable virtual { - unchecked { - uint256 expires = block.timestamp + _ownershipHandoverValidFor(); - /// @solidity memory-safe-assembly - assembly { - // Compute and set the handover slot to `expires`. - mstore(0x0c, _HANDOVER_SLOT_SEED) - mstore(0x00, caller()) - sstore(keccak256(0x0c, 0x20), expires) - // Emit the {OwnershipHandoverRequested} event. - log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller()) - } - } - } - - /// @dev Cancels the two-step ownership handover to the caller, if any. - function cancelOwnershipHandover() public payable virtual { - /// @solidity memory-safe-assembly - assembly { - // Compute and set the handover slot to 0. - mstore(0x0c, _HANDOVER_SLOT_SEED) - mstore(0x00, caller()) - sstore(keccak256(0x0c, 0x20), 0) - // Emit the {OwnershipHandoverCanceled} event. - log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller()) - } - } - - /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`. - /// Reverts if there is no existing ownership handover requested by `pendingOwner`. - function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner { - /// @solidity memory-safe-assembly - assembly { - // Compute and set the handover slot to 0. - mstore(0x0c, _HANDOVER_SLOT_SEED) - mstore(0x00, pendingOwner) - let handoverSlot := keccak256(0x0c, 0x20) - // If the handover does not exist, or has expired. - if gt(timestamp(), sload(handoverSlot)) { - mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`. - revert(0x1c, 0x04) - } - // Set the handover slot to 0. - sstore(handoverSlot, 0) - } - _setOwner(pendingOwner); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC READ FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the owner of the contract. - function owner() public view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(_OWNER_SLOT) - } - } - - /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`. - function ownershipHandoverExpiresAt(address pendingOwner) - public - view - virtual - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - // Compute the handover slot. - mstore(0x0c, _HANDOVER_SLOT_SEED) - mstore(0x00, pendingOwner) - // Load the handover slot. - result := sload(keccak256(0x0c, 0x20)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MODIFIERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Marks a function as only callable by the owner. - modifier onlyOwner() virtual { - _checkOwner(); - _; - } -} diff --git a/grouperBot/lib/solady/src/auth/OwnableRoles.sol b/grouperBot/lib/solady/src/auth/OwnableRoles.sol deleted file mode 100644 index 18cfcbf..0000000 --- a/grouperBot/lib/solady/src/auth/OwnableRoles.sol +++ /dev/null @@ -1,535 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Ownable} from "./Ownable.sol"; - -/// @notice Simple single owner and multiroles authorization mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/OwnableRoles.sol) -/// -/// @dev Note: -/// This implementation does NOT auto-initialize the owner to `msg.sender`. -/// You MUST call the `_initializeOwner` in the constructor / initializer. -/// -/// While the ownable portion follows -/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility, -/// the nomenclature for the 2-step ownership handover may be unique to this codebase. -abstract contract OwnableRoles is Ownable { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The `user`'s roles is updated to `roles`. - /// Each bit of `roles` represents whether the role is set. - event RolesUpdated(address indexed user, uint256 indexed roles); - - /// @dev `keccak256(bytes("RolesUpdated(address,uint256)"))`. - uint256 private constant _ROLES_UPDATED_EVENT_SIGNATURE = - 0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The role slot of `user` is given by: - /// ``` - /// mstore(0x00, or(shl(96, user), _ROLE_SLOT_SEED)) - /// let roleSlot := keccak256(0x00, 0x20) - /// ``` - /// This automatically ignores the upper bits of the `user` in case - /// they are not clean, as well as keep the `keccak256` under 32-bytes. - /// - /// Note: This is equivalent to `uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))`. - uint256 private constant _ROLE_SLOT_SEED = 0x8b78c6d8; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Overwrite the roles directly without authorization guard. - function _setRoles(address user, uint256 roles) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x0c, _ROLE_SLOT_SEED) - mstore(0x00, user) - // Store the new value. - sstore(keccak256(0x0c, 0x20), roles) - // Emit the {RolesUpdated} event. - log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles) - } - } - - /// @dev Updates the roles directly without authorization guard. - /// If `on` is true, each set bit of `roles` will be turned on, - /// otherwise, each set bit of `roles` will be turned off. - function _updateRoles(address user, uint256 roles, bool on) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x0c, _ROLE_SLOT_SEED) - mstore(0x00, user) - let roleSlot := keccak256(0x0c, 0x20) - // Load the current value. - let current := sload(roleSlot) - // Compute the updated roles if `on` is true. - let updated := or(current, roles) - // Compute the updated roles if `on` is false. - // Use `and` to compute the intersection of `current` and `roles`, - // `xor` it with `current` to flip the bits in the intersection. - if iszero(on) { updated := xor(current, and(current, roles)) } - // Then, store the new value. - sstore(roleSlot, updated) - // Emit the {RolesUpdated} event. - log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), updated) - } - } - - /// @dev Grants the roles directly without authorization guard. - /// Each bit of `roles` represents the role to turn on. - function _grantRoles(address user, uint256 roles) internal virtual { - _updateRoles(user, roles, true); - } - - /// @dev Removes the roles directly without authorization guard. - /// Each bit of `roles` represents the role to turn off. - function _removeRoles(address user, uint256 roles) internal virtual { - _updateRoles(user, roles, false); - } - - /// @dev Throws if the sender does not have any of the `roles`. - function _checkRoles(uint256 roles) internal view virtual { - /// @solidity memory-safe-assembly - assembly { - // Compute the role slot. - mstore(0x0c, _ROLE_SLOT_SEED) - mstore(0x00, caller()) - // Load the stored value, and if the `and` intersection - // of the value and `roles` is zero, revert. - if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Throws if the sender is not the owner, - /// and does not have any of the `roles`. - /// Checks for ownership first, then lazily checks for roles. - function _checkOwnerOrRoles(uint256 roles) internal view virtual { - /// @solidity memory-safe-assembly - assembly { - // If the caller is not the stored owner. - // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`. - if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) { - // Compute the role slot. - mstore(0x0c, _ROLE_SLOT_SEED) - mstore(0x00, caller()) - // Load the stored value, and if the `and` intersection - // of the value and `roles` is zero, revert. - if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Throws if the sender does not have any of the `roles`, - /// and is not the owner. - /// Checks for roles first, then lazily checks for ownership. - function _checkRolesOrOwner(uint256 roles) internal view virtual { - /// @solidity memory-safe-assembly - assembly { - // Compute the role slot. - mstore(0x0c, _ROLE_SLOT_SEED) - mstore(0x00, caller()) - // Load the stored value, and if the `and` intersection - // of the value and `roles` is zero, revert. - if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) { - // If the caller is not the stored owner. - // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`. - if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Convenience function to return a `roles` bitmap from an array of `ordinals`. - /// This is meant for frontends like Etherscan, and is therefore not fully optimized. - /// Not recommended to be called on-chain. - /// Made internal to conserve bytecode. Wrap it in a public function if needed. - function _rolesFromOrdinals(uint8[] memory ordinals) internal pure returns (uint256 roles) { - /// @solidity memory-safe-assembly - assembly { - for { let i := shl(5, mload(ordinals)) } i { i := sub(i, 0x20) } { - // We don't need to mask the values of `ordinals`, as Solidity - // cleans dirty upper bits when storing variables into memory. - roles := or(shl(mload(add(ordinals, i)), 1), roles) - } - } - } - - /// @dev Convenience function to return an array of `ordinals` from the `roles` bitmap. - /// This is meant for frontends like Etherscan, and is therefore not fully optimized. - /// Not recommended to be called on-chain. - /// Made internal to conserve bytecode. Wrap it in a public function if needed. - function _ordinalsFromRoles(uint256 roles) internal pure returns (uint8[] memory ordinals) { - /// @solidity memory-safe-assembly - assembly { - // Grab the pointer to the free memory. - ordinals := mload(0x40) - let ptr := add(ordinals, 0x20) - let o := 0 - // The absence of lookup tables, De Bruijn, etc., here is intentional for - // smaller bytecode, as this function is not meant to be called on-chain. - for { let t := roles } 1 {} { - mstore(ptr, o) - // `shr` 5 is equivalent to multiplying by 0x20. - // Push back into the ordinals array if the bit is set. - ptr := add(ptr, shl(5, and(t, 1))) - o := add(o, 1) - t := shr(o, roles) - if iszero(t) { break } - } - // Store the length of `ordinals`. - mstore(ordinals, shr(5, sub(ptr, add(ordinals, 0x20)))) - // Allocate the memory. - mstore(0x40, ptr) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC UPDATE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Allows the owner to grant `user` `roles`. - /// If the `user` already has a role, then it will be an no-op for the role. - function grantRoles(address user, uint256 roles) public payable virtual onlyOwner { - _grantRoles(user, roles); - } - - /// @dev Allows the owner to remove `user` `roles`. - /// If the `user` does not have a role, then it will be an no-op for the role. - function revokeRoles(address user, uint256 roles) public payable virtual onlyOwner { - _removeRoles(user, roles); - } - - /// @dev Allow the caller to remove their own roles. - /// If the caller does not have a role, then it will be an no-op for the role. - function renounceRoles(uint256 roles) public payable virtual { - _removeRoles(msg.sender, roles); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC READ FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the roles of `user`. - function rolesOf(address user) public view virtual returns (uint256 roles) { - /// @solidity memory-safe-assembly - assembly { - // Compute the role slot. - mstore(0x0c, _ROLE_SLOT_SEED) - mstore(0x00, user) - // Load the stored value. - roles := sload(keccak256(0x0c, 0x20)) - } - } - - /// @dev Returns whether `user` has any of `roles`. - function hasAnyRole(address user, uint256 roles) public view virtual returns (bool) { - return rolesOf(user) & roles != 0; - } - - /// @dev Returns whether `user` has all of `roles`. - function hasAllRoles(address user, uint256 roles) public view virtual returns (bool) { - return rolesOf(user) & roles == roles; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MODIFIERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Marks a function as only callable by an account with `roles`. - modifier onlyRoles(uint256 roles) virtual { - _checkRoles(roles); - _; - } - - /// @dev Marks a function as only callable by the owner or by an account - /// with `roles`. Checks for ownership first, then lazily checks for roles. - modifier onlyOwnerOrRoles(uint256 roles) virtual { - _checkOwnerOrRoles(roles); - _; - } - - /// @dev Marks a function as only callable by an account with `roles` - /// or the owner. Checks for roles first, then lazily checks for ownership. - modifier onlyRolesOrOwner(uint256 roles) virtual { - _checkRolesOrOwner(roles); - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ROLE CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // IYKYK - - uint256 internal constant _ROLE_0 = 1 << 0; - uint256 internal constant _ROLE_1 = 1 << 1; - uint256 internal constant _ROLE_2 = 1 << 2; - uint256 internal constant _ROLE_3 = 1 << 3; - uint256 internal constant _ROLE_4 = 1 << 4; - uint256 internal constant _ROLE_5 = 1 << 5; - uint256 internal constant _ROLE_6 = 1 << 6; - uint256 internal constant _ROLE_7 = 1 << 7; - uint256 internal constant _ROLE_8 = 1 << 8; - uint256 internal constant _ROLE_9 = 1 << 9; - uint256 internal constant _ROLE_10 = 1 << 10; - uint256 internal constant _ROLE_11 = 1 << 11; - uint256 internal constant _ROLE_12 = 1 << 12; - uint256 internal constant _ROLE_13 = 1 << 13; - uint256 internal constant _ROLE_14 = 1 << 14; - uint256 internal constant _ROLE_15 = 1 << 15; - uint256 internal constant _ROLE_16 = 1 << 16; - uint256 internal constant _ROLE_17 = 1 << 17; - uint256 internal constant _ROLE_18 = 1 << 18; - uint256 internal constant _ROLE_19 = 1 << 19; - uint256 internal constant _ROLE_20 = 1 << 20; - uint256 internal constant _ROLE_21 = 1 << 21; - uint256 internal constant _ROLE_22 = 1 << 22; - uint256 internal constant _ROLE_23 = 1 << 23; - uint256 internal constant _ROLE_24 = 1 << 24; - uint256 internal constant _ROLE_25 = 1 << 25; - uint256 internal constant _ROLE_26 = 1 << 26; - uint256 internal constant _ROLE_27 = 1 << 27; - uint256 internal constant _ROLE_28 = 1 << 28; - uint256 internal constant _ROLE_29 = 1 << 29; - uint256 internal constant _ROLE_30 = 1 << 30; - uint256 internal constant _ROLE_31 = 1 << 31; - uint256 internal constant _ROLE_32 = 1 << 32; - uint256 internal constant _ROLE_33 = 1 << 33; - uint256 internal constant _ROLE_34 = 1 << 34; - uint256 internal constant _ROLE_35 = 1 << 35; - uint256 internal constant _ROLE_36 = 1 << 36; - uint256 internal constant _ROLE_37 = 1 << 37; - uint256 internal constant _ROLE_38 = 1 << 38; - uint256 internal constant _ROLE_39 = 1 << 39; - uint256 internal constant _ROLE_40 = 1 << 40; - uint256 internal constant _ROLE_41 = 1 << 41; - uint256 internal constant _ROLE_42 = 1 << 42; - uint256 internal constant _ROLE_43 = 1 << 43; - uint256 internal constant _ROLE_44 = 1 << 44; - uint256 internal constant _ROLE_45 = 1 << 45; - uint256 internal constant _ROLE_46 = 1 << 46; - uint256 internal constant _ROLE_47 = 1 << 47; - uint256 internal constant _ROLE_48 = 1 << 48; - uint256 internal constant _ROLE_49 = 1 << 49; - uint256 internal constant _ROLE_50 = 1 << 50; - uint256 internal constant _ROLE_51 = 1 << 51; - uint256 internal constant _ROLE_52 = 1 << 52; - uint256 internal constant _ROLE_53 = 1 << 53; - uint256 internal constant _ROLE_54 = 1 << 54; - uint256 internal constant _ROLE_55 = 1 << 55; - uint256 internal constant _ROLE_56 = 1 << 56; - uint256 internal constant _ROLE_57 = 1 << 57; - uint256 internal constant _ROLE_58 = 1 << 58; - uint256 internal constant _ROLE_59 = 1 << 59; - uint256 internal constant _ROLE_60 = 1 << 60; - uint256 internal constant _ROLE_61 = 1 << 61; - uint256 internal constant _ROLE_62 = 1 << 62; - uint256 internal constant _ROLE_63 = 1 << 63; - uint256 internal constant _ROLE_64 = 1 << 64; - uint256 internal constant _ROLE_65 = 1 << 65; - uint256 internal constant _ROLE_66 = 1 << 66; - uint256 internal constant _ROLE_67 = 1 << 67; - uint256 internal constant _ROLE_68 = 1 << 68; - uint256 internal constant _ROLE_69 = 1 << 69; - uint256 internal constant _ROLE_70 = 1 << 70; - uint256 internal constant _ROLE_71 = 1 << 71; - uint256 internal constant _ROLE_72 = 1 << 72; - uint256 internal constant _ROLE_73 = 1 << 73; - uint256 internal constant _ROLE_74 = 1 << 74; - uint256 internal constant _ROLE_75 = 1 << 75; - uint256 internal constant _ROLE_76 = 1 << 76; - uint256 internal constant _ROLE_77 = 1 << 77; - uint256 internal constant _ROLE_78 = 1 << 78; - uint256 internal constant _ROLE_79 = 1 << 79; - uint256 internal constant _ROLE_80 = 1 << 80; - uint256 internal constant _ROLE_81 = 1 << 81; - uint256 internal constant _ROLE_82 = 1 << 82; - uint256 internal constant _ROLE_83 = 1 << 83; - uint256 internal constant _ROLE_84 = 1 << 84; - uint256 internal constant _ROLE_85 = 1 << 85; - uint256 internal constant _ROLE_86 = 1 << 86; - uint256 internal constant _ROLE_87 = 1 << 87; - uint256 internal constant _ROLE_88 = 1 << 88; - uint256 internal constant _ROLE_89 = 1 << 89; - uint256 internal constant _ROLE_90 = 1 << 90; - uint256 internal constant _ROLE_91 = 1 << 91; - uint256 internal constant _ROLE_92 = 1 << 92; - uint256 internal constant _ROLE_93 = 1 << 93; - uint256 internal constant _ROLE_94 = 1 << 94; - uint256 internal constant _ROLE_95 = 1 << 95; - uint256 internal constant _ROLE_96 = 1 << 96; - uint256 internal constant _ROLE_97 = 1 << 97; - uint256 internal constant _ROLE_98 = 1 << 98; - uint256 internal constant _ROLE_99 = 1 << 99; - uint256 internal constant _ROLE_100 = 1 << 100; - uint256 internal constant _ROLE_101 = 1 << 101; - uint256 internal constant _ROLE_102 = 1 << 102; - uint256 internal constant _ROLE_103 = 1 << 103; - uint256 internal constant _ROLE_104 = 1 << 104; - uint256 internal constant _ROLE_105 = 1 << 105; - uint256 internal constant _ROLE_106 = 1 << 106; - uint256 internal constant _ROLE_107 = 1 << 107; - uint256 internal constant _ROLE_108 = 1 << 108; - uint256 internal constant _ROLE_109 = 1 << 109; - uint256 internal constant _ROLE_110 = 1 << 110; - uint256 internal constant _ROLE_111 = 1 << 111; - uint256 internal constant _ROLE_112 = 1 << 112; - uint256 internal constant _ROLE_113 = 1 << 113; - uint256 internal constant _ROLE_114 = 1 << 114; - uint256 internal constant _ROLE_115 = 1 << 115; - uint256 internal constant _ROLE_116 = 1 << 116; - uint256 internal constant _ROLE_117 = 1 << 117; - uint256 internal constant _ROLE_118 = 1 << 118; - uint256 internal constant _ROLE_119 = 1 << 119; - uint256 internal constant _ROLE_120 = 1 << 120; - uint256 internal constant _ROLE_121 = 1 << 121; - uint256 internal constant _ROLE_122 = 1 << 122; - uint256 internal constant _ROLE_123 = 1 << 123; - uint256 internal constant _ROLE_124 = 1 << 124; - uint256 internal constant _ROLE_125 = 1 << 125; - uint256 internal constant _ROLE_126 = 1 << 126; - uint256 internal constant _ROLE_127 = 1 << 127; - uint256 internal constant _ROLE_128 = 1 << 128; - uint256 internal constant _ROLE_129 = 1 << 129; - uint256 internal constant _ROLE_130 = 1 << 130; - uint256 internal constant _ROLE_131 = 1 << 131; - uint256 internal constant _ROLE_132 = 1 << 132; - uint256 internal constant _ROLE_133 = 1 << 133; - uint256 internal constant _ROLE_134 = 1 << 134; - uint256 internal constant _ROLE_135 = 1 << 135; - uint256 internal constant _ROLE_136 = 1 << 136; - uint256 internal constant _ROLE_137 = 1 << 137; - uint256 internal constant _ROLE_138 = 1 << 138; - uint256 internal constant _ROLE_139 = 1 << 139; - uint256 internal constant _ROLE_140 = 1 << 140; - uint256 internal constant _ROLE_141 = 1 << 141; - uint256 internal constant _ROLE_142 = 1 << 142; - uint256 internal constant _ROLE_143 = 1 << 143; - uint256 internal constant _ROLE_144 = 1 << 144; - uint256 internal constant _ROLE_145 = 1 << 145; - uint256 internal constant _ROLE_146 = 1 << 146; - uint256 internal constant _ROLE_147 = 1 << 147; - uint256 internal constant _ROLE_148 = 1 << 148; - uint256 internal constant _ROLE_149 = 1 << 149; - uint256 internal constant _ROLE_150 = 1 << 150; - uint256 internal constant _ROLE_151 = 1 << 151; - uint256 internal constant _ROLE_152 = 1 << 152; - uint256 internal constant _ROLE_153 = 1 << 153; - uint256 internal constant _ROLE_154 = 1 << 154; - uint256 internal constant _ROLE_155 = 1 << 155; - uint256 internal constant _ROLE_156 = 1 << 156; - uint256 internal constant _ROLE_157 = 1 << 157; - uint256 internal constant _ROLE_158 = 1 << 158; - uint256 internal constant _ROLE_159 = 1 << 159; - uint256 internal constant _ROLE_160 = 1 << 160; - uint256 internal constant _ROLE_161 = 1 << 161; - uint256 internal constant _ROLE_162 = 1 << 162; - uint256 internal constant _ROLE_163 = 1 << 163; - uint256 internal constant _ROLE_164 = 1 << 164; - uint256 internal constant _ROLE_165 = 1 << 165; - uint256 internal constant _ROLE_166 = 1 << 166; - uint256 internal constant _ROLE_167 = 1 << 167; - uint256 internal constant _ROLE_168 = 1 << 168; - uint256 internal constant _ROLE_169 = 1 << 169; - uint256 internal constant _ROLE_170 = 1 << 170; - uint256 internal constant _ROLE_171 = 1 << 171; - uint256 internal constant _ROLE_172 = 1 << 172; - uint256 internal constant _ROLE_173 = 1 << 173; - uint256 internal constant _ROLE_174 = 1 << 174; - uint256 internal constant _ROLE_175 = 1 << 175; - uint256 internal constant _ROLE_176 = 1 << 176; - uint256 internal constant _ROLE_177 = 1 << 177; - uint256 internal constant _ROLE_178 = 1 << 178; - uint256 internal constant _ROLE_179 = 1 << 179; - uint256 internal constant _ROLE_180 = 1 << 180; - uint256 internal constant _ROLE_181 = 1 << 181; - uint256 internal constant _ROLE_182 = 1 << 182; - uint256 internal constant _ROLE_183 = 1 << 183; - uint256 internal constant _ROLE_184 = 1 << 184; - uint256 internal constant _ROLE_185 = 1 << 185; - uint256 internal constant _ROLE_186 = 1 << 186; - uint256 internal constant _ROLE_187 = 1 << 187; - uint256 internal constant _ROLE_188 = 1 << 188; - uint256 internal constant _ROLE_189 = 1 << 189; - uint256 internal constant _ROLE_190 = 1 << 190; - uint256 internal constant _ROLE_191 = 1 << 191; - uint256 internal constant _ROLE_192 = 1 << 192; - uint256 internal constant _ROLE_193 = 1 << 193; - uint256 internal constant _ROLE_194 = 1 << 194; - uint256 internal constant _ROLE_195 = 1 << 195; - uint256 internal constant _ROLE_196 = 1 << 196; - uint256 internal constant _ROLE_197 = 1 << 197; - uint256 internal constant _ROLE_198 = 1 << 198; - uint256 internal constant _ROLE_199 = 1 << 199; - uint256 internal constant _ROLE_200 = 1 << 200; - uint256 internal constant _ROLE_201 = 1 << 201; - uint256 internal constant _ROLE_202 = 1 << 202; - uint256 internal constant _ROLE_203 = 1 << 203; - uint256 internal constant _ROLE_204 = 1 << 204; - uint256 internal constant _ROLE_205 = 1 << 205; - uint256 internal constant _ROLE_206 = 1 << 206; - uint256 internal constant _ROLE_207 = 1 << 207; - uint256 internal constant _ROLE_208 = 1 << 208; - uint256 internal constant _ROLE_209 = 1 << 209; - uint256 internal constant _ROLE_210 = 1 << 210; - uint256 internal constant _ROLE_211 = 1 << 211; - uint256 internal constant _ROLE_212 = 1 << 212; - uint256 internal constant _ROLE_213 = 1 << 213; - uint256 internal constant _ROLE_214 = 1 << 214; - uint256 internal constant _ROLE_215 = 1 << 215; - uint256 internal constant _ROLE_216 = 1 << 216; - uint256 internal constant _ROLE_217 = 1 << 217; - uint256 internal constant _ROLE_218 = 1 << 218; - uint256 internal constant _ROLE_219 = 1 << 219; - uint256 internal constant _ROLE_220 = 1 << 220; - uint256 internal constant _ROLE_221 = 1 << 221; - uint256 internal constant _ROLE_222 = 1 << 222; - uint256 internal constant _ROLE_223 = 1 << 223; - uint256 internal constant _ROLE_224 = 1 << 224; - uint256 internal constant _ROLE_225 = 1 << 225; - uint256 internal constant _ROLE_226 = 1 << 226; - uint256 internal constant _ROLE_227 = 1 << 227; - uint256 internal constant _ROLE_228 = 1 << 228; - uint256 internal constant _ROLE_229 = 1 << 229; - uint256 internal constant _ROLE_230 = 1 << 230; - uint256 internal constant _ROLE_231 = 1 << 231; - uint256 internal constant _ROLE_232 = 1 << 232; - uint256 internal constant _ROLE_233 = 1 << 233; - uint256 internal constant _ROLE_234 = 1 << 234; - uint256 internal constant _ROLE_235 = 1 << 235; - uint256 internal constant _ROLE_236 = 1 << 236; - uint256 internal constant _ROLE_237 = 1 << 237; - uint256 internal constant _ROLE_238 = 1 << 238; - uint256 internal constant _ROLE_239 = 1 << 239; - uint256 internal constant _ROLE_240 = 1 << 240; - uint256 internal constant _ROLE_241 = 1 << 241; - uint256 internal constant _ROLE_242 = 1 << 242; - uint256 internal constant _ROLE_243 = 1 << 243; - uint256 internal constant _ROLE_244 = 1 << 244; - uint256 internal constant _ROLE_245 = 1 << 245; - uint256 internal constant _ROLE_246 = 1 << 246; - uint256 internal constant _ROLE_247 = 1 << 247; - uint256 internal constant _ROLE_248 = 1 << 248; - uint256 internal constant _ROLE_249 = 1 << 249; - uint256 internal constant _ROLE_250 = 1 << 250; - uint256 internal constant _ROLE_251 = 1 << 251; - uint256 internal constant _ROLE_252 = 1 << 252; - uint256 internal constant _ROLE_253 = 1 << 253; - uint256 internal constant _ROLE_254 = 1 << 254; - uint256 internal constant _ROLE_255 = 1 << 255; -} diff --git a/grouperBot/lib/solady/src/auth/TimedRoles.sol b/grouperBot/lib/solady/src/auth/TimedRoles.sol deleted file mode 100644 index cc0f68b..0000000 --- a/grouperBot/lib/solady/src/auth/TimedRoles.sol +++ /dev/null @@ -1,282 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Timed multiroles authorization mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/TimedRoles.sol) -/// -/// @dev Note: -/// This implementation is agnostic to the Ownable that the contract inherits from. -/// It performs a self-staticcall to the `owner()` function to determine the owner. -/// This is useful for situations where the contract inherits from -/// OpenZeppelin's Ownable, such as in LayerZero's OApp contracts. -/// -/// This implementation performs a self-staticcall to `MAX_TIMED_ROLE()` to determine -/// the maximum timed role that can be set/unset. If the inheriting contract does not -/// have `MAX_TIMED_ROLE()`, then any timed role can be set/unset. -/// -/// This implementation allows for any uint256 role, -/// it does NOT take in a bitmask of roles. -/// This is to accommodate teams that are allergic to bitwise flags. -/// -/// By default, the `owner()` is the only account that is authorized to set timed roles. -/// This behavior can be changed via overrides. -/// -/// This implementation is compatible with any Ownable. -/// This implementation is NOT compatible with OwnableRoles. -/// -/// As timed roles can turn active or inactive anytime, enumeration is omitted here. -/// Querying the number of active timed roles will cost `O(n)` instead of `O(1)`. -/// -/// Names are deliberately prefixed with "Timed", so that this contract -/// can be used in conjunction with EnumerableRoles without collisions. -abstract contract TimedRoles { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The active time range of the timed role has been set. - event TimedRoleSet( - address indexed holder, uint256 indexed timedRole, uint40 start, uint40 expires - ); - - /// @dev `keccak256(bytes("TimedRoleSet(address,uint256,uint40,uint40)"))`. - uint256 private constant _TIMED_ROLE_SET_EVENT_SIGNATURE = - 0xf7b5bcd44281f9bd7dfe7227dbb5c96dafa8587339fe558592433e9d02ade7d7; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Cannot set the timed role of the zero address. - error TimedRoleHolderIsZeroAddress(); - - /// @dev The timed role has exceeded the maximum timed role. - error InvalidTimedRole(); - - /// @dev Unauthorized to perform the action. - error TimedRolesUnauthorized(); - - /// @dev The `expires` cannot be less than the `start`. - error InvalidTimedRoleRange(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage layout of the mapping is given by: - /// ``` - /// mstore(0x18, holder) - /// mstore(0x04, _TIMED_ROLES_SLOT_SEED) - /// mstore(0x00, timedRole) - /// let activeTimeRangeSlot := keccak256(0x00, 0x38) - /// ``` - /// Bits Layout: - /// - [0..39] `expires`. - /// - [216..255] `start`. - uint256 private constant _TIMED_ROLES_SLOT_SEED = 0x28900261; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC UPDATE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the active time range of `timedRole` of `holder` to [`start`, `expires`]. - /// The `timedRole` is active when `start <= block.timestamp && block.timestamp <= expires`. - function setTimedRole(address holder, uint256 timedRole, uint40 start, uint40 expires) - public - payable - virtual - { - _authorizeSetTimedRole(holder, timedRole, start, expires); - _setTimedRole(holder, timedRole, start, expires); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC READ FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether the `timedRole` is active for `holder` and the active time range. - function timedRoleActive(address holder, uint256 timedRole) - public - view - virtual - returns (bool isActive, uint40 start, uint40 expires) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x18, holder) - mstore(0x04, _TIMED_ROLES_SLOT_SEED) - mstore(0x00, timedRole) - let p := sload(keccak256(0x00, 0x38)) - start := shr(216, p) - expires := and(0xffffffffff, p) - isActive := iszero(or(lt(timestamp(), start), gt(timestamp(), expires))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Set the timed role for holder directly without authorization guard. - function _setTimedRole(address holder, uint256 timedRole, uint40 start, uint40 expires) - internal - virtual - { - _validateTimedRole(timedRole); - /// @solidity memory-safe-assembly - assembly { - let holder_ := shl(96, holder) - if iszero(holder_) { - mstore(0x00, 0x093a136f) // `TimedRoleHolderIsZeroAddress()`. - revert(0x1c, 0x04) - } - // Clean the upper bits. - start := and(0xffffffffff, start) - expires := and(0xffffffffff, expires) - // Validate the range. - if lt(expires, start) { - mstore(0x00, 0x3304dd8c) // `InvalidTimedRoleRange()`. - revert(0x1c, 0x04) - } - // Store the range. - mstore(0x18, holder) - mstore(0x04, _TIMED_ROLES_SLOT_SEED) - mstore(0x00, timedRole) - sstore(keccak256(0x00, 0x38), or(shl(216, start), expires)) - // Emit the {TimedRoleSet} event. - mstore(0x00, start) - mstore(0x20, expires) - log3(0x00, 0x40, _TIMED_ROLE_SET_EVENT_SIGNATURE, shr(96, holder_), timedRole) - } - } - - /// @dev Requires the timedRole is not greater than `MAX_TIMED_ROLE()`. - /// If `MAX_TIMED_ROLE()` is not implemented, this is an no-op. - function _validateTimedRole(uint256 timedRole) internal view virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x32bc6439) // `MAX_TIMED_ROLE()`. - if and( - and(gt(timedRole, mload(0x00)), gt(returndatasize(), 0x1f)), - staticcall(gas(), address(), 0x1c, 0x04, 0x00, 0x20) - ) { - mstore(0x00, 0x802ee27f) // `InvalidTimedRole()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Checks that the caller is authorized to set the timed role. - function _authorizeSetTimedRole(address holder, uint256 timedRole, uint40 start, uint40 expires) - internal - virtual - { - if (!_timedRolesSenderIsContractOwner()) _revertTimedRolesUnauthorized(); - // Silence compiler warning on unused variables. - (holder, timedRole, start, expires) = (holder, timedRole, start, expires); - } - - /// @dev Returns if `holder` has any roles in `encodedTimeRoles`. - /// `encodedTimeRoles` is `abi.encode(SAMPLE_TIMED_ROLE_0, SAMPLE_TIMED_ROLE_1, ...)`. - function _hasAnyTimedRoles(address holder, bytes memory encodedTimeRoles) - internal - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x18, holder) - mstore(0x04, _TIMED_ROLES_SLOT_SEED) - let end := add(encodedTimeRoles, shl(5, shr(5, mload(encodedTimeRoles)))) - for {} lt(result, lt(encodedTimeRoles, end)) {} { - encodedTimeRoles := add(0x20, encodedTimeRoles) - mstore(0x00, mload(encodedTimeRoles)) - let p := sload(keccak256(0x00, 0x38)) - result := - iszero(or(lt(timestamp(), shr(216, p)), gt(timestamp(), and(0xffffffffff, p)))) - } - } - } - - /// @dev Reverts if `msg.sender` does not have `timedRole`. - function _checkTimedRole(uint256 timedRole) internal view virtual { - (bool isActive,,) = timedRoleActive(msg.sender, timedRole); - if (!isActive) _revertTimedRolesUnauthorized(); - } - - /// @dev Reverts if `msg.sender` does not have any timed role in `encodedTimedRoles`. - function _checkTimedRoles(bytes memory encodedTimedRoles) internal view virtual { - if (!_hasAnyTimedRoles(msg.sender, encodedTimedRoles)) _revertTimedRolesUnauthorized(); - } - - /// @dev Reverts if `msg.sender` is not the contract owner and does not have `timedRole`. - function _checkOwnerOrTimedRole(uint256 timedRole) internal view virtual { - if (!_timedRolesSenderIsContractOwner()) _checkTimedRole(timedRole); - } - - /// @dev Reverts if `msg.sender` is not the contract owner and - /// does not have any timed role in `encodedTimedRoles`. - function _checkOwnerOrTimedRoles(bytes memory encodedTimedRoles) internal view virtual { - if (!_timedRolesSenderIsContractOwner()) _checkTimedRoles(encodedTimedRoles); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MODIFIERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Marks a function as only callable by an account with `timedRole`. - modifier onlyTimedRole(uint256 timedRole) virtual { - _checkTimedRole(timedRole); - _; - } - - /// @dev Marks a function as only callable by an account with any role in `encodedTimedRoles`. - /// `encodedTimedRoles` is `abi.encode(SAMPLE_TIMED_ROLE_0, SAMPLE_TIMED_ROLE_1, ...)`. - modifier onlyTimedRoles(bytes memory encodedTimedRoles) virtual { - _checkTimedRoles(encodedTimedRoles); - _; - } - - /// @dev Marks a function as only callable by the owner or by an account with `timedRole`. - modifier onlyOwnerOrTimedRole(uint256 timedRole) virtual { - _checkOwnerOrTimedRole(timedRole); - _; - } - - /// @dev Marks a function as only callable by the owner or - /// by an account with any role in `encodedTimedRoles`. - /// Checks for ownership first, then checks for roles. - /// `encodedTimedRoles` is `abi.encode(SAMPLE_TIMED_ROLE_0, SAMPLE_TIMED_ROLE_1, ...)`. - modifier onlyOwnerOrTimedRoles(bytes memory encodedTimedRoles) virtual { - _checkOwnerOrTimedRoles(encodedTimedRoles); - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if the `msg.sender` is equal to `owner()` on this contract. - /// If the contract does not have `owner()` implemented, returns false. - function _timedRolesSenderIsContractOwner() private view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x8da5cb5b) // `owner()`. - result := - and( - and(eq(caller(), mload(0x00)), gt(returndatasize(), 0x1f)), - staticcall(gas(), address(), 0x1c, 0x04, 0x00, 0x20) - ) - } - } - - /// @dev Reverts with `TimedRolesUnauthorized()`. - function _revertTimedRolesUnauthorized() private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xb0c7b036) // `TimedRolesUnauthorized()`. - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/tokens/ERC1155.sol b/grouperBot/lib/solady/src/tokens/ERC1155.sol deleted file mode 100644 index 3f045b4..0000000 --- a/grouperBot/lib/solady/src/tokens/ERC1155.sol +++ /dev/null @@ -1,1120 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple ERC1155 implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC1155.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC1155/ERC1155.sol) -/// -/// @dev Note: -/// - The ERC1155 standard allows for self-approvals. -/// For performance, this implementation WILL NOT revert for such actions. -/// Please add any checks with overrides if desired. -/// - The transfer functions use the identity precompile (0x4) -/// to copy memory internally. -/// -/// If you are overriding: -/// - Make sure all variables written to storage are properly cleaned -// (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood). -/// - Check that the overridden function is actually used in the function you want to -/// change the behavior of. Much of the code has been manually inlined for performance. -abstract contract ERC1155 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The lengths of the input arrays are not the same. - error ArrayLengthsMismatch(); - - /// @dev Cannot mint or transfer to the zero address. - error TransferToZeroAddress(); - - /// @dev The recipient's balance has overflowed. - error AccountBalanceOverflow(); - - /// @dev Insufficient balance. - error InsufficientBalance(); - - /// @dev Only the token owner or an approved account can manage the tokens. - error NotOwnerNorApproved(); - - /// @dev Cannot safely transfer to a contract that does not implement - /// the ERC1155Receiver interface. - error TransferToNonERC1155ReceiverImplementer(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when `amount` of token `id` is transferred - /// from `from` to `to` by `operator`. - event TransferSingle( - address indexed operator, - address indexed from, - address indexed to, - uint256 id, - uint256 amount - ); - - /// @dev Emitted when `amounts` of token `ids` are transferred - /// from `from` to `to` by `operator`. - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] amounts - ); - - /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. - event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); - - /// @dev Emitted when the Uniform Resource Identifier (URI) for token `id` - /// is updated to `value`. This event is not used in the base contract. - /// You may need to emit this event depending on your URI logic. - /// - /// See: https://eips.ethereum.org/EIPS/eip-1155#metadata - event URI(string value, uint256 indexed id); - - /// @dev `keccak256(bytes("TransferSingle(address,address,address,uint256,uint256)"))`. - uint256 private constant _TRANSFER_SINGLE_EVENT_SIGNATURE = - 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62; - - /// @dev `keccak256(bytes("TransferBatch(address,address,address,uint256[],uint256[])"))`. - uint256 private constant _TRANSFER_BATCH_EVENT_SIGNATURE = - 0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb; - - /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. - uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = - 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The `ownerSlotSeed` of a given owner is given by. - /// ``` - /// let ownerSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner)) - /// ``` - /// - /// The balance slot of `owner` is given by. - /// ``` - /// mstore(0x20, ownerSlotSeed) - /// mstore(0x00, id) - /// let balanceSlot := keccak256(0x00, 0x40) - /// ``` - /// - /// The operator approval slot of `owner` is given by. - /// ``` - /// mstore(0x20, ownerSlotSeed) - /// mstore(0x00, operator) - /// let operatorApprovalSlot := keccak256(0x0c, 0x34) - /// ``` - uint256 private constant _ERC1155_MASTER_SLOT_SEED = 0x9a31110384e0b0c9; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1155 METADATA */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the URI for token `id`. - /// - /// You can either return the same templated URI for all token IDs, - /// (e.g. "https://example.com/api/{id}.json"), - /// or return a unique URI for each `id`. - /// - /// See: https://eips.ethereum.org/EIPS/eip-1155#metadata - function uri(uint256 id) public view virtual returns (string memory); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1155 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the amount of `id` owned by `owner`. - function balanceOf(address owner, uint256 id) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, owner) - mstore(0x00, id) - result := sload(keccak256(0x00, 0x40)) - } - } - - /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. - function isApprovedForAll(address owner, address operator) - public - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, owner) - mstore(0x00, operator) - result := sload(keccak256(0x0c, 0x34)) - } - } - - /// @dev Sets whether `operator` is approved to manage the tokens of the caller. - /// - /// Emits a {ApprovalForAll} event. - function setApprovalForAll(address operator, bool isApproved) public virtual { - /// @solidity memory-safe-assembly - assembly { - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`msg.sender`, `operator`). - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, caller()) - mstore(0x00, operator) - sstore(keccak256(0x0c, 0x34), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - // forgefmt: disable-next-line - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))) - } - } - - /// @dev Transfers `amount` of `id` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `from` must have at least `amount` of `id`. - /// - If the caller is not `from`, - /// it must be approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155Received}, which is called upon a batch transfer. - /// - /// Emits a {TransferSingle} event. - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) public virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) - let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) - mstore(0x20, fromSlotSeed) - // Clear the upper 96 bits. - from := shr(96, fromSlotSeed) - to := shr(96, toSlotSeed) - // Revert if `to` is the zero address. - if iszero(to) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // If the caller is not `from`, do the authorization check. - if iszero(eq(caller(), from)) { - mstore(0x00, caller()) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Subtract and store the updated balance of `from`. - { - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, toSlotSeed) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), from, to) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - // Do the {onERC1155Received} check if `to` is a smart contract. - if extcodesize(to) { - // Prepare the calldata. - let m := mload(0x40) - // `onERC1155Received(address,address,uint256,uint256,bytes)`. - mstore(m, 0xf23a6e61) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), from) - mstore(add(m, 0x60), id) - mstore(add(m, 0x80), amount) - mstore(add(m, 0xa0), 0xa0) - mstore(add(m, 0xc0), data.length) - calldatacopy(add(m, 0xe0), data.offset, data.length) - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), add(0xc4, data.length), m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xf23a6e61))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Transfers `amounts` of `ids` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `from` must have at least `amount` of `id`. - /// - `ids` and `amounts` must have the same length. - /// - If the caller is not `from`, - /// it must be approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155BatchReceived}, which is called upon a batch transfer. - /// - /// Emits a {TransferBatch} event. - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) public virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(ids.length, amounts.length)) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) - let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) - mstore(0x20, fromSlotSeed) - // Clear the upper 96 bits. - from := shr(96, fromSlotSeed) - to := shr(96, toSlotSeed) - // Revert if `to` is the zero address. - if iszero(to) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // If the caller is not `from`, do the authorization check. - if iszero(eq(caller(), from)) { - mstore(0x00, caller()) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Loop through all the `ids` and update the balances. - { - for { let i := shl(5, ids.length) } i {} { - i := sub(i, 0x20) - let amount := calldataload(add(amounts.offset, i)) - // Subtract and store the updated balance of `from`. - { - mstore(0x20, fromSlotSeed) - mstore(0x00, calldataload(add(ids.offset, i))) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, toSlotSeed) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := shl(5, ids.length) - mstore(add(m, 0x40), ids.length) - calldatacopy(add(m, 0x60), ids.offset, n) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x60, n)) - let o := add(add(m, n), 0x60) - mstore(o, ids.length) - calldatacopy(add(o, 0x20), amounts.offset, n) - // Do the emit. - log4(m, add(add(n, n), 0x80), _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), from, to) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransferCalldata(from, to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - // Do the {onERC1155BatchReceived} check if `to` is a smart contract. - if extcodesize(to) { - mstore(0x00, to) // Cache `to` to prevent stack too deep. - let m := mload(0x40) - // Prepare the calldata. - // `onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)`. - mstore(m, 0xbc197c81) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), from) - // Copy the `ids`. - mstore(add(m, 0x60), 0xa0) - let n := shl(5, ids.length) - mstore(add(m, 0xc0), ids.length) - calldatacopy(add(m, 0xe0), ids.offset, n) - // Copy the `amounts`. - mstore(add(m, 0x80), add(0xc0, n)) - let o := add(add(m, n), 0xe0) - mstore(o, ids.length) - calldatacopy(add(o, 0x20), amounts.offset, n) - // Copy the `data`. - mstore(add(m, 0xa0), add(add(0xe0, n), n)) - o := add(add(o, n), 0x20) - mstore(o, data.length) - calldatacopy(add(o, 0x20), data.offset, data.length) - let nAll := add(0x104, add(data.length, add(n, n))) - // Revert if the call reverts. - if iszero(call(gas(), mload(0x00), 0, add(mload(0x40), 0x1c), nAll, m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xbc197c81))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Returns the amounts of `ids` for `owners. - /// - /// Requirements: - /// - `owners` and `ids` must have the same length. - function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) - public - view - virtual - returns (uint256[] memory balances) - { - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(ids.length, owners.length)) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - balances := mload(0x40) - mstore(balances, ids.length) - let o := add(balances, 0x20) - let i := shl(5, ids.length) - mstore(0x40, add(i, o)) - // Loop through all the `ids` and load the balances. - for {} i {} { - i := sub(i, 0x20) - let owner := calldataload(add(owners.offset, i)) - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner))) - mstore(0x00, calldataload(add(ids.offset, i))) - mstore(add(o, i), sload(keccak256(0x00, 0x40))) - } - } - } - - /// @dev Returns true if this contract implements the interface defined by `interfaceId`. - /// See: https://eips.ethereum.org/EIPS/eip-165 - /// This function call must use less than 30000 gas. - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, interfaceId) - // ERC165: 0x01ffc9a7, ERC1155: 0xd9b67a26, ERC1155MetadataURI: 0x0e89341c. - result := or(or(eq(s, 0x01ffc9a7), eq(s, 0xd9b67a26)), eq(s, 0x0e89341c)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL MINT FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Mints `amount` of `id` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155Received}, which is called upon a batch transfer. - /// - /// Emits a {TransferSingle} event. - function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(address(0), to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, to) - mstore(0x00, id) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), 0, shr(96, to_)) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(address(0), to, _single(id), _single(amount), data); - } - if (_hasCode(to)) _checkOnERC1155Received(address(0), to, id, amount, data); - } - - /// @dev Mints `amounts` of `ids` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `ids` and `amounts` must have the same length. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155BatchReceived}, which is called upon a batch transfer. - /// - /// Emits a {TransferBatch} event. - function _batchMint( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(address(0), to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(mload(ids), mload(amounts))) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // Loop through all the `ids` and update the balances. - { - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, to_)) - for { let i := shl(5, mload(ids)) } i { i := sub(i, 0x20) } { - let amount := mload(add(amounts, i)) - // Increase and store the updated balance of `to`. - { - mstore(0x00, mload(add(ids, i))) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0x40) - pop(staticcall(gas(), 4, ids, n, o, n)) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x40, returndatasize())) - o := add(o, returndatasize()) - n := add(0x20, shl(5, mload(amounts))) - pop(staticcall(gas(), 4, amounts, n, o, n)) - n := sub(add(o, returndatasize()), m) - // Do the emit. - log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), 0, shr(96, to_)) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(address(0), to, ids, amounts, data); - } - if (_hasCode(to)) _checkOnERC1155BatchReceived(address(0), to, ids, amounts, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL BURN FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_burn(address(0), from, id, amount)`. - function _burn(address from, uint256 id, uint256 amount) internal virtual { - _burn(address(0), from, id, amount); - } - - /// @dev Destroys `amount` of `id` from `from`. - /// - /// Requirements: - /// - `from` must have at least `amount` of `id`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - /// Emits a {TransferSingle} event. - function _burn(address by, address from, uint256 id, uint256 amount) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, address(0), _single(id), _single(amount), ""); - } - /// @solidity memory-safe-assembly - assembly { - let from_ := shl(96, from) - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, from_)) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - if iszero(or(iszero(shl(96, by)), eq(shl(96, by), from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Decrease and store the updated balance of `from`. - { - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), shr(96, from_), 0) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, address(0), _single(id), _single(amount), ""); - } - } - - /// @dev Equivalent to `_batchBurn(address(0), from, ids, amounts)`. - function _batchBurn(address from, uint256[] memory ids, uint256[] memory amounts) - internal - virtual - { - _batchBurn(address(0), from, ids, amounts); - } - - /// @dev Destroys `amounts` of `ids` from `from`. - /// - /// Requirements: - /// - `ids` and `amounts` must have the same length. - /// - `from` must have at least `amounts` of `ids`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - /// Emits a {TransferBatch} event. - function _batchBurn(address by, address from, uint256[] memory ids, uint256[] memory amounts) - internal - virtual - { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, address(0), ids, amounts, ""); - } - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(mload(ids), mload(amounts))) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let from_ := shl(96, from) - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, from_)) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - let by_ := shl(96, by) - if iszero(or(iszero(by_), eq(by_, from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Loop through all the `ids` and update the balances. - { - for { let i := shl(5, mload(ids)) } i { i := sub(i, 0x20) } { - let amount := mload(add(amounts, i)) - // Decrease and store the updated balance of `from`. - { - mstore(0x00, mload(add(ids, i))) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0x40) - pop(staticcall(gas(), 4, ids, n, o, n)) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x40, returndatasize())) - o := add(o, returndatasize()) - n := add(0x20, shl(5, mload(amounts))) - pop(staticcall(gas(), 4, amounts, n, o, n)) - n := sub(add(o, returndatasize()), m) - // Do the emit. - log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), shr(96, from_), 0) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, address(0), ids, amounts, ""); - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL APPROVAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Approve or remove the `operator` as an operator for `by`, - /// without authorization checks. - /// - /// Emits a {ApprovalForAll} event. - function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { - /// @solidity memory-safe-assembly - assembly { - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`by`, `operator`). - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, by) - mstore(0x00, operator) - sstore(keccak256(0x0c, 0x34), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - let m := shr(96, not(0)) - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, and(m, by), and(m, operator)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL TRANSFER FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_safeTransfer(address(0), from, to, id, amount, data)`. - function _safeTransfer(address from, address to, uint256 id, uint256 amount, bytes memory data) - internal - virtual - { - _safeTransfer(address(0), from, to, id, amount, data); - } - - /// @dev Transfers `amount` of `id` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `from` must have at least `amount` of `id`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155Received}, which is called upon a batch transfer. - /// - /// Emits a {TransferSingle} event. - function _safeTransfer( - address by, - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - let from_ := shl(96, from) - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, from_)) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - let by_ := shl(96, by) - if iszero(or(iszero(by_), eq(by_, from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Subtract and store the updated balance of `from`. - { - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, to_)) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - // forgefmt: disable-next-line - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), shr(96, from_), shr(96, to_)) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, _single(id), _single(amount), data); - } - if (_hasCode(to)) _checkOnERC1155Received(from, to, id, amount, data); - } - - /// @dev Equivalent to `_safeBatchTransfer(address(0), from, to, ids, amounts, data)`. - function _safeBatchTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - _safeBatchTransfer(address(0), from, to, ids, amounts, data); - } - - /// @dev Transfers `amounts` of `ids` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `ids` and `amounts` must have the same length. - /// - `from` must have at least `amounts` of `ids`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155BatchReceived}, which is called upon a batch transfer. - /// - /// Emits a {TransferBatch} event. - function _safeBatchTransfer( - address by, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(mload(ids), mload(amounts))) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let from_ := shl(96, from) - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, from_) - let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, to_) - mstore(0x20, fromSlotSeed) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - let by_ := shl(96, by) - if iszero(or(iszero(by_), eq(by_, from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Loop through all the `ids` and update the balances. - { - for { let i := shl(5, mload(ids)) } i { i := sub(i, 0x20) } { - let amount := mload(add(amounts, i)) - // Subtract and store the updated balance of `from`. - { - mstore(0x20, fromSlotSeed) - mstore(0x00, mload(add(ids, i))) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, toSlotSeed) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0x40) - pop(staticcall(gas(), 4, ids, n, o, n)) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x40, returndatasize())) - o := add(o, returndatasize()) - n := add(0x20, shl(5, mload(amounts))) - pop(staticcall(gas(), 4, amounts, n, o, n)) - n := sub(add(o, returndatasize()), m) - // Do the emit. - log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), shr(96, from_), shr(96, to_)) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, ids, amounts, data); - } - if (_hasCode(to)) _checkOnERC1155BatchReceived(from, to, ids, amounts, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HOOKS FOR OVERRIDING */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Override this function to return true if `_beforeTokenTransfer` is used. - /// This is to help the compiler avoid producing dead bytecode. - function _useBeforeTokenTransfer() internal view virtual returns (bool) { - return false; - } - - /// @dev Hook that is called before any token transfer. - /// This includes minting and burning, as well as batched variants. - /// - /// The same hook is called on both single and batched variants. - /// For single transfers, the length of the `id` and `amount` arrays are 1. - function _beforeTokenTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - /// @dev Override this function to return true if `_afterTokenTransfer` is used. - /// This is to help the compiler avoid producing dead bytecode. - function _useAfterTokenTransfer() internal view virtual returns (bool) { - return false; - } - - /// @dev Hook that is called after any token transfer. - /// This includes minting and burning, as well as batched variants. - /// - /// The same hook is called on both single and batched variants. - /// For single transfers, the length of the `id` and `amount` arrays are 1. - function _afterTokenTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper for calling the `_afterTokenTransfer` hook. - /// This is to help the compiler avoid producing dead bytecode. - function _afterTokenTransferCalldata( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) private { - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, ids, amounts, data); - } - } - - /// @dev Returns if `a` has bytecode of non-zero length. - function _hasCode(address a) private view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := extcodesize(a) // Can handle dirty upper bits. - } - } - - /// @dev Perform a call to invoke {IERC1155Receiver-onERC1155Received} on `to`. - /// Reverts if the target does not support the function correctly. - function _checkOnERC1155Received( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) private { - /// @solidity memory-safe-assembly - assembly { - // Prepare the calldata. - let m := mload(0x40) - // `onERC1155Received(address,address,uint256,uint256,bytes)`. - mstore(m, 0xf23a6e61) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), shr(96, shl(96, from))) - mstore(add(m, 0x60), id) - mstore(add(m, 0x80), amount) - mstore(add(m, 0xa0), 0xa0) - let n := mload(data) - mstore(add(m, 0xc0), n) - if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xe0), n)) } - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), add(0xc4, n), m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xf23a6e61))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Perform a call to invoke {IERC1155Receiver-onERC1155BatchReceived} on `to`. - /// Reverts if the target does not support the function correctly. - function _checkOnERC1155BatchReceived( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) private { - /// @solidity memory-safe-assembly - assembly { - // Prepare the calldata. - let m := mload(0x40) - // `onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)`. - mstore(m, 0xbc197c81) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), shr(96, shl(96, from))) - // Copy the `ids`. - mstore(add(m, 0x60), 0xa0) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0xc0) - pop(staticcall(gas(), 4, ids, n, o, n)) - // Copy the `amounts`. - let s := add(0xa0, returndatasize()) - mstore(add(m, 0x80), s) - o := add(o, returndatasize()) - n := add(0x20, shl(5, mload(amounts))) - pop(staticcall(gas(), 4, amounts, n, o, n)) - // Copy the `data`. - mstore(add(m, 0xa0), add(s, returndatasize())) - o := add(o, returndatasize()) - n := add(0x20, mload(data)) - pop(staticcall(gas(), 4, data, n, o, n)) - n := sub(add(o, returndatasize()), add(m, 0x1c)) - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), n, m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xbc197c81))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns `x` in an array with a single element. - function _single(uint256 x) private pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x40, add(result, 0x40)) - mstore(result, 1) - mstore(add(result, 0x20), x) - } - } -} diff --git a/grouperBot/lib/solady/src/tokens/ERC20.sol b/grouperBot/lib/solady/src/tokens/ERC20.sol deleted file mode 100644 index 8f4534f..0000000 --- a/grouperBot/lib/solady/src/tokens/ERC20.sol +++ /dev/null @@ -1,670 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple ERC20 + EIP-2612 implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC20.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) -/// -/// @dev Note: -/// - The ERC20 standard allows minting and transferring to and from the zero address, -/// minting and transferring zero tokens, as well as self-approvals. -/// For performance, this implementation WILL NOT revert for such actions. -/// Please add any checks with overrides if desired. -/// - The `permit` function uses the ecrecover precompile (0x1). -/// -/// If you are overriding: -/// - NEVER violate the ERC20 invariant: -/// the total sum of all balances must be equal to `totalSupply()`. -/// - Check that the overridden function is actually used in the function you want to -/// change the behavior of. Much of the code has been manually inlined for performance. -abstract contract ERC20 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The total supply has overflowed. - error TotalSupplyOverflow(); - - /// @dev The allowance has overflowed. - error AllowanceOverflow(); - - /// @dev The allowance has underflowed. - error AllowanceUnderflow(); - - /// @dev Insufficient balance. - error InsufficientBalance(); - - /// @dev Insufficient allowance. - error InsufficientAllowance(); - - /// @dev The permit is invalid. - error InvalidPermit(); - - /// @dev The permit has expired. - error PermitExpired(); - - /// @dev The allowance of Permit2 is fixed at infinity. - error Permit2AllowanceIsFixedAtInfinity(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when `amount` tokens is transferred from `from` to `to`. - event Transfer(address indexed from, address indexed to, uint256 amount); - - /// @dev Emitted when `amount` tokens is approved by `owner` to be used by `spender`. - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`. - uint256 private constant _TRANSFER_EVENT_SIGNATURE = - 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; - - /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`. - uint256 private constant _APPROVAL_EVENT_SIGNATURE = - 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage slot for the total supply. - uint256 private constant _TOTAL_SUPPLY_SLOT = 0x05345cdf77eb68f44c; - - /// @dev The balance slot of `owner` is given by: - /// ``` - /// mstore(0x0c, _BALANCE_SLOT_SEED) - /// mstore(0x00, owner) - /// let balanceSlot := keccak256(0x0c, 0x20) - /// ``` - uint256 private constant _BALANCE_SLOT_SEED = 0x87a211a2; - - /// @dev The allowance slot of (`owner`, `spender`) is given by: - /// ``` - /// mstore(0x20, spender) - /// mstore(0x0c, _ALLOWANCE_SLOT_SEED) - /// mstore(0x00, owner) - /// let allowanceSlot := keccak256(0x0c, 0x34) - /// ``` - uint256 private constant _ALLOWANCE_SLOT_SEED = 0x7f5e9f20; - - /// @dev The nonce slot of `owner` is given by: - /// ``` - /// mstore(0x0c, _NONCES_SLOT_SEED) - /// mstore(0x00, owner) - /// let nonceSlot := keccak256(0x0c, 0x20) - /// ``` - uint256 private constant _NONCES_SLOT_SEED = 0x38377508; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev `(_NONCES_SLOT_SEED << 16) | 0x1901`. - uint256 private constant _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX = 0x383775081901; - - /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. - bytes32 private constant _DOMAIN_TYPEHASH = - 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; - - /// @dev `keccak256("1")`. - /// If you need to use a different version, override `_versionHash`. - bytes32 private constant _DEFAULT_VERSION_HASH = - 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6; - - /// @dev `keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")`. - bytes32 private constant _PERMIT_TYPEHASH = - 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; - - /// @dev The canonical Permit2 address. - /// For signature-based allowance granting for single transaction ERC20 `transferFrom`. - /// Enabled by default. To disable, override `_givePermit2InfiniteAllowance()`. - /// [Github](https://github.com/Uniswap/permit2) - /// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) - address internal constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC20 METADATA */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the name of the token. - function name() public view virtual returns (string memory); - - /// @dev Returns the symbol of the token. - function symbol() public view virtual returns (string memory); - - /// @dev Returns the decimals places of the token. - function decimals() public view virtual returns (uint8) { - return 18; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC20 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the amount of tokens in existence. - function totalSupply() public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(_TOTAL_SUPPLY_SLOT) - } - } - - /// @dev Returns the amount of tokens owned by `owner`. - function balanceOf(address owner) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x0c, _BALANCE_SLOT_SEED) - mstore(0x00, owner) - result := sload(keccak256(0x0c, 0x20)) - } - } - - /// @dev Returns the amount of tokens that `spender` can spend on behalf of `owner`. - function allowance(address owner, address spender) - public - view - virtual - returns (uint256 result) - { - if (_givePermit2InfiniteAllowance()) { - if (spender == _PERMIT2) return type(uint256).max; - } - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, spender) - mstore(0x0c, _ALLOWANCE_SLOT_SEED) - mstore(0x00, owner) - result := sload(keccak256(0x0c, 0x34)) - } - } - - /// @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - /// - /// Emits a {Approval} event. - function approve(address spender, uint256 amount) public virtual returns (bool) { - if (_givePermit2InfiniteAllowance()) { - /// @solidity memory-safe-assembly - assembly { - // If `spender == _PERMIT2 && amount != type(uint256).max`. - if iszero(or(xor(shr(96, shl(96, spender)), _PERMIT2), iszero(not(amount)))) { - mstore(0x00, 0x3f68539a) // `Permit2AllowanceIsFixedAtInfinity()`. - revert(0x1c, 0x04) - } - } - } - /// @solidity memory-safe-assembly - assembly { - // Compute the allowance slot and store the amount. - mstore(0x20, spender) - mstore(0x0c, _ALLOWANCE_SLOT_SEED) - mstore(0x00, caller()) - sstore(keccak256(0x0c, 0x34), amount) - // Emit the {Approval} event. - mstore(0x00, amount) - log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, caller(), shr(96, mload(0x2c))) - } - return true; - } - - /// @dev Transfer `amount` tokens from the caller to `to`. - /// - /// Requirements: - /// - `from` must at least have `amount`. - /// - /// Emits a {Transfer} event. - function transfer(address to, uint256 amount) public virtual returns (bool) { - _beforeTokenTransfer(msg.sender, to, amount); - /// @solidity memory-safe-assembly - assembly { - // Compute the balance slot and load its value. - mstore(0x0c, _BALANCE_SLOT_SEED) - mstore(0x00, caller()) - let fromBalanceSlot := keccak256(0x0c, 0x20) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Compute the balance slot of `to`. - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x20) - // Add and store the updated balance of `to`. - // Will not overflow because the sum of all user balances - // cannot exceed the maximum uint256 value. - sstore(toBalanceSlot, add(sload(toBalanceSlot), amount)) - // Emit the {Transfer} event. - mstore(0x20, amount) - log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, caller(), shr(96, mload(0x0c))) - } - _afterTokenTransfer(msg.sender, to, amount); - return true; - } - - /// @dev Transfers `amount` tokens from `from` to `to`. - /// - /// Note: Does not update the allowance if it is the maximum uint256 value. - /// - /// Requirements: - /// - `from` must at least have `amount`. - /// - The caller must have at least `amount` of allowance to transfer the tokens of `from`. - /// - /// Emits a {Transfer} event. - function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) { - _beforeTokenTransfer(from, to, amount); - // Code duplication is for zero-cost abstraction if possible. - if (_givePermit2InfiniteAllowance()) { - /// @solidity memory-safe-assembly - assembly { - let from_ := shl(96, from) - if iszero(eq(caller(), _PERMIT2)) { - // Compute the allowance slot and load its value. - mstore(0x20, caller()) - mstore(0x0c, or(from_, _ALLOWANCE_SLOT_SEED)) - let allowanceSlot := keccak256(0x0c, 0x34) - let allowance_ := sload(allowanceSlot) - // If the allowance is not the maximum uint256 value. - if not(allowance_) { - // Revert if the amount to be transferred exceeds the allowance. - if gt(amount, allowance_) { - mstore(0x00, 0x13be252b) // `InsufficientAllowance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated allowance. - sstore(allowanceSlot, sub(allowance_, amount)) - } - } - // Compute the balance slot and load its value. - mstore(0x0c, or(from_, _BALANCE_SLOT_SEED)) - let fromBalanceSlot := keccak256(0x0c, 0x20) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Compute the balance slot of `to`. - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x20) - // Add and store the updated balance of `to`. - // Will not overflow because the sum of all user balances - // cannot exceed the maximum uint256 value. - sstore(toBalanceSlot, add(sload(toBalanceSlot), amount)) - // Emit the {Transfer} event. - mstore(0x20, amount) - log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c))) - } - } else { - /// @solidity memory-safe-assembly - assembly { - let from_ := shl(96, from) - // Compute the allowance slot and load its value. - mstore(0x20, caller()) - mstore(0x0c, or(from_, _ALLOWANCE_SLOT_SEED)) - let allowanceSlot := keccak256(0x0c, 0x34) - let allowance_ := sload(allowanceSlot) - // If the allowance is not the maximum uint256 value. - if not(allowance_) { - // Revert if the amount to be transferred exceeds the allowance. - if gt(amount, allowance_) { - mstore(0x00, 0x13be252b) // `InsufficientAllowance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated allowance. - sstore(allowanceSlot, sub(allowance_, amount)) - } - // Compute the balance slot and load its value. - mstore(0x0c, or(from_, _BALANCE_SLOT_SEED)) - let fromBalanceSlot := keccak256(0x0c, 0x20) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Compute the balance slot of `to`. - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x20) - // Add and store the updated balance of `to`. - // Will not overflow because the sum of all user balances - // cannot exceed the maximum uint256 value. - sstore(toBalanceSlot, add(sload(toBalanceSlot), amount)) - // Emit the {Transfer} event. - mstore(0x20, amount) - log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c))) - } - } - _afterTokenTransfer(from, to, amount); - return true; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EIP-2612 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For more performance, override to return the constant value - /// of `keccak256(bytes(name()))` if `name()` will never change. - function _constantNameHash() internal view virtual returns (bytes32 result) {} - - /// @dev If you need a different value, override this function. - function _versionHash() internal view virtual returns (bytes32 result) { - result = _DEFAULT_VERSION_HASH; - } - - /// @dev For inheriting contracts to increment the nonce. - function _incrementNonce(address owner) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x0c, _NONCES_SLOT_SEED) - mstore(0x00, owner) - let nonceSlot := keccak256(0x0c, 0x20) - sstore(nonceSlot, add(1, sload(nonceSlot))) - } - } - - /// @dev Returns the current nonce for `owner`. - /// This value is used to compute the signature for EIP-2612 permit. - function nonces(address owner) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - // Compute the nonce slot and load its value. - mstore(0x0c, _NONCES_SLOT_SEED) - mstore(0x00, owner) - result := sload(keccak256(0x0c, 0x20)) - } - } - - /// @dev Sets `value` as the allowance of `spender` over the tokens of `owner`, - /// authorized by a signed approval by `owner`. - /// - /// Emits a {Approval} event. - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - if (_givePermit2InfiniteAllowance()) { - /// @solidity memory-safe-assembly - assembly { - // If `spender == _PERMIT2 && value != type(uint256).max`. - if iszero(or(xor(shr(96, shl(96, spender)), _PERMIT2), iszero(not(value)))) { - mstore(0x00, 0x3f68539a) // `Permit2AllowanceIsFixedAtInfinity()`. - revert(0x1c, 0x04) - } - } - } - bytes32 nameHash = _constantNameHash(); - // We simply calculate it on-the-fly to allow for cases where the `name` may change. - if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name())); - bytes32 versionHash = _versionHash(); - /// @solidity memory-safe-assembly - assembly { - // Revert if the block timestamp is greater than `deadline`. - if gt(timestamp(), deadline) { - mstore(0x00, 0x1a15a3cc) // `PermitExpired()`. - revert(0x1c, 0x04) - } - let m := mload(0x40) // Grab the free memory pointer. - // Clean the upper 96 bits. - owner := shr(96, shl(96, owner)) - spender := shr(96, shl(96, spender)) - // Compute the nonce slot and load its value. - mstore(0x0e, _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX) - mstore(0x00, owner) - let nonceSlot := keccak256(0x0c, 0x20) - let nonceValue := sload(nonceSlot) - // Prepare the domain separator. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), nameHash) - mstore(add(m, 0x40), versionHash) - mstore(add(m, 0x60), chainid()) - mstore(add(m, 0x80), address()) - mstore(0x2e, keccak256(m, 0xa0)) - // Prepare the struct hash. - mstore(m, _PERMIT_TYPEHASH) - mstore(add(m, 0x20), owner) - mstore(add(m, 0x40), spender) - mstore(add(m, 0x60), value) - mstore(add(m, 0x80), nonceValue) - mstore(add(m, 0xa0), deadline) - mstore(0x4e, keccak256(m, 0xc0)) - // Prepare the ecrecover calldata. - mstore(0x00, keccak256(0x2c, 0x42)) - mstore(0x20, and(0xff, v)) - mstore(0x40, r) - mstore(0x60, s) - let t := staticcall(gas(), 1, 0x00, 0x80, 0x20, 0x20) - // If the ecrecover fails, the returndatasize will be 0x00, - // `owner` will be checked if it equals the hash at 0x00, - // which evaluates to false (i.e. 0), and we will revert. - // If the ecrecover succeeds, the returndatasize will be 0x20, - // `owner` will be compared against the returned address at 0x20. - if iszero(eq(mload(returndatasize()), owner)) { - mstore(0x00, 0xddafbaef) // `InvalidPermit()`. - revert(0x1c, 0x04) - } - // Increment and store the updated nonce. - sstore(nonceSlot, add(nonceValue, t)) // `t` is 1 if ecrecover succeeds. - // Compute the allowance slot and store the value. - // The `owner` is already at slot 0x20. - mstore(0x40, or(shl(160, _ALLOWANCE_SLOT_SEED), spender)) - sstore(keccak256(0x2c, 0x34), value) - // Emit the {Approval} event. - log3(add(m, 0x60), 0x20, _APPROVAL_EVENT_SIGNATURE, owner, spender) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /// @dev Returns the EIP-712 domain separator for the EIP-2612 permit. - function DOMAIN_SEPARATOR() public view virtual returns (bytes32 result) { - bytes32 nameHash = _constantNameHash(); - // We simply calculate it on-the-fly to allow for cases where the `name` may change. - if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name())); - bytes32 versionHash = _versionHash(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Grab the free memory pointer. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), nameHash) - mstore(add(m, 0x40), versionHash) - mstore(add(m, 0x60), chainid()) - mstore(add(m, 0x80), address()) - result := keccak256(m, 0xa0) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL MINT FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Mints `amount` tokens to `to`, increasing the total supply. - /// - /// Emits a {Transfer} event. - function _mint(address to, uint256 amount) internal virtual { - _beforeTokenTransfer(address(0), to, amount); - /// @solidity memory-safe-assembly - assembly { - let totalSupplyBefore := sload(_TOTAL_SUPPLY_SLOT) - let totalSupplyAfter := add(totalSupplyBefore, amount) - // Revert if the total supply overflows. - if lt(totalSupplyAfter, totalSupplyBefore) { - mstore(0x00, 0xe5cfe957) // `TotalSupplyOverflow()`. - revert(0x1c, 0x04) - } - // Store the updated total supply. - sstore(_TOTAL_SUPPLY_SLOT, totalSupplyAfter) - // Compute the balance slot and load its value. - mstore(0x0c, _BALANCE_SLOT_SEED) - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x20) - // Add and store the updated balance. - sstore(toBalanceSlot, add(sload(toBalanceSlot), amount)) - // Emit the {Transfer} event. - mstore(0x20, amount) - log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, 0, shr(96, mload(0x0c))) - } - _afterTokenTransfer(address(0), to, amount); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL BURN FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Burns `amount` tokens from `from`, reducing the total supply. - /// - /// Emits a {Transfer} event. - function _burn(address from, uint256 amount) internal virtual { - _beforeTokenTransfer(from, address(0), amount); - /// @solidity memory-safe-assembly - assembly { - // Compute the balance slot and load its value. - mstore(0x0c, _BALANCE_SLOT_SEED) - mstore(0x00, from) - let fromBalanceSlot := keccak256(0x0c, 0x20) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Subtract and store the updated total supply. - sstore(_TOTAL_SUPPLY_SLOT, sub(sload(_TOTAL_SUPPLY_SLOT), amount)) - // Emit the {Transfer} event. - mstore(0x00, amount) - log3(0x00, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), 0) - } - _afterTokenTransfer(from, address(0), amount); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL TRANSFER FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Moves `amount` of tokens from `from` to `to`. - function _transfer(address from, address to, uint256 amount) internal virtual { - _beforeTokenTransfer(from, to, amount); - /// @solidity memory-safe-assembly - assembly { - let from_ := shl(96, from) - // Compute the balance slot and load its value. - mstore(0x0c, or(from_, _BALANCE_SLOT_SEED)) - let fromBalanceSlot := keccak256(0x0c, 0x20) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Compute the balance slot of `to`. - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x20) - // Add and store the updated balance of `to`. - // Will not overflow because the sum of all user balances - // cannot exceed the maximum uint256 value. - sstore(toBalanceSlot, add(sload(toBalanceSlot), amount)) - // Emit the {Transfer} event. - mstore(0x20, amount) - log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c))) - } - _afterTokenTransfer(from, to, amount); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL ALLOWANCE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Updates the allowance of `owner` for `spender` based on spent `amount`. - function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { - if (_givePermit2InfiniteAllowance()) { - if (spender == _PERMIT2) return; // Do nothing, as allowance is infinite. - } - /// @solidity memory-safe-assembly - assembly { - // Compute the allowance slot and load its value. - mstore(0x20, spender) - mstore(0x0c, _ALLOWANCE_SLOT_SEED) - mstore(0x00, owner) - let allowanceSlot := keccak256(0x0c, 0x34) - let allowance_ := sload(allowanceSlot) - // If the allowance is not the maximum uint256 value. - if not(allowance_) { - // Revert if the amount to be transferred exceeds the allowance. - if gt(amount, allowance_) { - mstore(0x00, 0x13be252b) // `InsufficientAllowance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated allowance. - sstore(allowanceSlot, sub(allowance_, amount)) - } - } - } - - /// @dev Sets `amount` as the allowance of `spender` over the tokens of `owner`. - /// - /// Emits a {Approval} event. - function _approve(address owner, address spender, uint256 amount) internal virtual { - if (_givePermit2InfiniteAllowance()) { - /// @solidity memory-safe-assembly - assembly { - // If `spender == _PERMIT2 && amount != type(uint256).max`. - if iszero(or(xor(shr(96, shl(96, spender)), _PERMIT2), iszero(not(amount)))) { - mstore(0x00, 0x3f68539a) // `Permit2AllowanceIsFixedAtInfinity()`. - revert(0x1c, 0x04) - } - } - } - /// @solidity memory-safe-assembly - assembly { - let owner_ := shl(96, owner) - // Compute the allowance slot and store the amount. - mstore(0x20, spender) - mstore(0x0c, or(owner_, _ALLOWANCE_SLOT_SEED)) - sstore(keccak256(0x0c, 0x34), amount) - // Emit the {Approval} event. - mstore(0x00, amount) - log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, shr(96, owner_), shr(96, mload(0x2c))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HOOKS TO OVERRIDE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Hook that is called before any transfer of tokens. - /// This includes minting and burning. - function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} - - /// @dev Hook that is called after any transfer of tokens. - /// This includes minting and burning. - function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PERMIT2 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether to fix the Permit2 contract's allowance at infinity. - /// - /// This value should be kept constant after contract initialization, - /// or else the actual allowance values may not match with the {Approval} events. - /// For best performance, return a compile-time constant for zero-cost abstraction. - function _givePermit2InfiniteAllowance() internal view virtual returns (bool) { - return true; - } -} diff --git a/grouperBot/lib/solady/src/tokens/ERC20Votes.sol b/grouperBot/lib/solady/src/tokens/ERC20Votes.sol deleted file mode 100644 index eb249ce..0000000 --- a/grouperBot/lib/solady/src/tokens/ERC20Votes.sol +++ /dev/null @@ -1,458 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC20} from "./ERC20.sol"; - -/// @notice ERC20 with votes based on ERC5805 and ERC6372. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC20Votes.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Votes.sol) -abstract contract ERC20Votes is ERC20 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The timepoint is in the future. - error ERC5805FutureLookup(); - - /// @dev The ERC5805 signature to set a delegate has expired. - error ERC5805DelegateSignatureExpired(); - - /// @dev The ERC5805 signature to set a delegate is invalid. - error ERC5805DelegateInvalidSignature(); - - /// @dev Out-of-bounds access for the checkpoints. - error ERC5805CheckpointIndexOutOfBounds(); - - /// @dev Arithmetic overflow when pushing a new checkpoint. - error ERC5805CheckpointValueOverflow(); - - /// @dev Arithmetic underflow when pushing a new checkpoint. - error ERC5805CheckpointValueUnderflow(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The delegate of `delegator` is changed from `from` to `to`. - event DelegateChanged(address indexed delegator, address indexed from, address indexed to); - - /// @dev The votes balance of `delegate` is changed from `oldValue` to `newValue`. - event DelegateVotesChanged(address indexed delegate, uint256 oldValue, uint256 newValue); - - /// @dev `keccak256(bytes("DelegateChanged(address,address,address)"))`. - uint256 private constant _DELEGATE_CHANGED_EVENT_SIGNATURE = - 0x3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f; - - /// @dev `keccak256(bytes("DelegateVotesChanged(address,uint256,uint256)"))`. - uint256 private constant _DELEGATE_VOTES_CHANGED_EVENT_SIGNATURE = - 0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. - bytes32 private constant _DOMAIN_TYPEHASH = - 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; - - /// @dev `keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)")`. - bytes32 private constant _ERC5805_DELEGATION_TYPEHASH = - 0xe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The slot of a delegate is given by: - /// ``` - /// mstore(0x04, _ERC20_VOTES_MASTER_SLOT_SEED) - /// mstore(0x00, account) - /// let delegateSlot := keccak256(0x0c, 0x18) - /// ``` - /// The checkpoints length slot of a delegate is given by: - /// ``` - /// mstore(0x04, _ERC20_VOTES_MASTER_SLOT_SEED) - /// mstore(0x00, delegate) - /// let lengthSlot := keccak256(0x0c, 0x17) - /// let length := and(0xffffffffffff, shr(48, sload(lengthSlot))) - /// ``` - /// The total checkpoints length slot is `_ERC20_VOTES_MASTER_SLOT_SEED << 96`. - /// - /// The `i`-th checkpoint slot is given by: - /// ``` - /// let checkpointSlot := add(i, lengthSlot) - /// let key := and(sload(checkpointSlot), 0xffffffffffff) - /// let value := shr(96, sload(checkpointSlot)) - /// if eq(value, address()) { value := sload(not(checkpointSlot)) } - /// ``` - uint256 private constant _ERC20_VOTES_MASTER_SLOT_SEED = 0xff466c9f; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC6372 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the clock mode. - function CLOCK_MODE() public view virtual returns (string memory) { - return "mode=blocknumber&from=default"; - } - - /// @dev Returns the current clock. - function clock() public view virtual returns (uint48 result) { - /// @solidity memory-safe-assembly - assembly { - result := number() - // Branch-less out-of-gas revert if `block.number >= 2 ** 48`. - returndatacopy(returndatasize(), returndatasize(), sub(0, shr(48, number()))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC5805 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the latest amount of voting units for `account`. - function getVotes(address account) public view virtual returns (uint256) { - return _checkpointLatest(_delegateCheckpointsSlot(account)); - } - - /// @dev Returns the latest amount of voting units `account` has before or during `timepoint`. - function getPastVotes(address account, uint256 timepoint) - public - view - virtual - returns (uint256) - { - if (timepoint >= clock()) _revertERC5805FutureLookup(); - return _checkpointUpperLookupRecent(_delegateCheckpointsSlot(account), timepoint); - } - - /// @dev Returns the current voting delegate of `delegator`. - function delegates(address delegator) public view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ERC20_VOTES_MASTER_SLOT_SEED) - mstore(0x00, delegator) - result := sload(keccak256(0x0c, 0x18)) - } - } - - /// @dev Set the voting delegate of the caller to `delegatee`. - function delegate(address delegatee) public virtual { - _delegate(msg.sender, delegatee); - } - - /// @dev Sets the voting delegate of the signature signer to `delegatee`. - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - address signer; - bytes32 nameHash = _constantNameHash(); - // We simply calculate it on-the-fly to allow for cases where the `name` may change. - if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name())); - bytes32 versionHash = _versionHash(); - /// @solidity memory-safe-assembly - assembly { - if gt(timestamp(), expiry) { - mstore(0x00, 0x3480e9e1) // `ERC5805DelegateSignatureExpired()`. - revert(0x1c, 0x04) - } - let m := mload(0x40) - // Prepare the struct hash. - mstore(0x00, _ERC5805_DELEGATION_TYPEHASH) - mstore(0x20, shr(96, shl(96, delegatee))) - mstore(0x40, nonce) - mstore(0x60, expiry) - mstore(0x40, keccak256(0x00, 0x80)) - mstore(0x00, 0x1901) // Store "\x19\x01". - // Prepare the domain separator. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), nameHash) - mstore(add(m, 0x40), versionHash) - mstore(add(m, 0x60), chainid()) - mstore(add(m, 0x80), address()) - mstore(0x20, keccak256(m, 0xa0)) - // Prepare the ecrecover calldata. - mstore(0x00, keccak256(0x1e, 0x42)) - mstore(0x20, and(0xff, v)) - mstore(0x40, r) - mstore(0x60, s) - signer := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - expiry := iszero(returndatasize()) // Reuse `expiry` to denote `ecrecover` failure. - } - if ((nonces(signer) ^ nonce) | expiry != 0) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x1838d95c) // `ERC5805DelegateInvalidSignature()`. - revert(0x1c, 0x04) - } - } - _incrementNonce(signer); - _delegate(signer, delegatee); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER VOTE PUBLIC VIEW FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of checkpoints for `account`. - function checkpointCount(address account) public view virtual returns (uint256 result) { - result = _delegateCheckpointsSlot(account); - /// @solidity memory-safe-assembly - assembly { - result := shr(208, shl(160, sload(result))) - } - } - - /// @dev Returns the voting checkpoint for `account` at index `i`. - function checkpointAt(address account, uint256 i) - public - view - virtual - returns (uint48 checkpointClock, uint256 checkpointValue) - { - uint256 lengthSlot = _delegateCheckpointsSlot(account); - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(i, shr(208, shl(160, sload(lengthSlot))))) { - mstore(0x00, 0x86df9d10) // `ERC5805CheckpointIndexOutOfBounds()`. - revert(0x1c, 0x04) - } - let checkpointPacked := sload(add(i, lengthSlot)) - checkpointClock := and(0xffffffffffff, checkpointPacked) - checkpointValue := shr(96, checkpointPacked) - if eq(checkpointValue, address()) { checkpointValue := sload(not(add(i, lengthSlot))) } - } - } - - /// @dev Returns the latest amount of total voting units. - function getVotesTotalSupply() public view virtual returns (uint256) { - return _checkpointLatest(_ERC20_VOTES_MASTER_SLOT_SEED << 96); - } - - /// @dev Returns the latest amount of total voting units before or during `timepoint`. - function getPastVotesTotalSupply(uint256 timepoint) public view virtual returns (uint256) { - if (timepoint >= clock()) _revertERC5805FutureLookup(); - return _checkpointUpperLookupRecent(_ERC20_VOTES_MASTER_SLOT_SEED << 96, timepoint); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the amount of voting units `delegator` has control over. - /// Override if you need a different formula. - function _getVotingUnits(address delegator) internal view virtual returns (uint256) { - return balanceOf(delegator); - } - - /// @dev ERC20 after token transfer internal hook. - function _afterTokenTransfer(address from, address to, uint256 amount) - internal - virtual - override - { - _transferVotingUnits(from, to, amount); - } - - /// @dev Used in `_afterTokenTransfer(address from, address to, uint256 amount)`. - function _transferVotingUnits(address from, address to, uint256 amount) internal virtual { - if (from == address(0)) { - _checkpointPushDiff(_ERC20_VOTES_MASTER_SLOT_SEED << 96, clock(), amount, true); - } - if (to == address(0)) { - _checkpointPushDiff(_ERC20_VOTES_MASTER_SLOT_SEED << 96, clock(), amount, false); - } - _moveDelegateVotes(delegates(from), delegates(to), amount); - } - - /// @dev Transfer `amount` of delegated votes from `from` to `to`. - /// Emits a {DelegateVotesChanged} event for each change of delegated votes. - function _moveDelegateVotes(address from, address to, uint256 amount) internal virtual { - if (amount == uint256(0)) return; - (uint256 fromCleaned, uint256 toCleaned) = (uint256(uint160(from)), uint256(uint160(to))); - if (fromCleaned == toCleaned) return; - if (fromCleaned != 0) { - (uint256 oldValue, uint256 newValue) = - _checkpointPushDiff(_delegateCheckpointsSlot(from), clock(), amount, false); - /// @solidity memory-safe-assembly - assembly { - // Emit the {DelegateVotesChanged} event. - mstore(0x00, oldValue) - mstore(0x20, newValue) - log2(0x00, 0x40, _DELEGATE_VOTES_CHANGED_EVENT_SIGNATURE, fromCleaned) - } - } - if (toCleaned != 0) { - (uint256 oldValue, uint256 newValue) = - _checkpointPushDiff(_delegateCheckpointsSlot(to), clock(), amount, true); - /// @solidity memory-safe-assembly - assembly { - // Emit the {DelegateVotesChanged} event. - mstore(0x00, oldValue) - mstore(0x20, newValue) - log2(0x00, 0x40, _DELEGATE_VOTES_CHANGED_EVENT_SIGNATURE, toCleaned) - } - } - } - - /// @dev Delegates all of `account`'s voting units to `delegatee`. - /// Emits the {DelegateChanged} and {DelegateVotesChanged} events. - function _delegate(address account, address delegatee) internal virtual { - address from; - /// @solidity memory-safe-assembly - assembly { - let to := shr(96, shl(96, delegatee)) - mstore(0x04, _ERC20_VOTES_MASTER_SLOT_SEED) - mstore(0x00, account) - let delegateSlot := keccak256(0x0c, 0x18) - from := sload(delegateSlot) - sstore(delegateSlot, to) - // Emit the {DelegateChanged} event. - log4(0x00, 0x00, _DELEGATE_CHANGED_EVENT_SIGNATURE, shr(96, mload(0x0c)), from, to) - } - _moveDelegateVotes(from, delegatee, _getVotingUnits(account)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the delegate checkpoints slot for `account`. - function _delegateCheckpointsSlot(address account) private pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ERC20_VOTES_MASTER_SLOT_SEED) - mstore(0x00, account) - result := keccak256(0x0c, 0x17) - } - } - - /// @dev Pushes a checkpoint. - function _checkpointPushDiff(uint256 lengthSlot, uint256 key, uint256 amount, bool isAdd) - private - returns (uint256 oldValue, uint256 newValue) - { - /// @solidity memory-safe-assembly - assembly { - let lengthSlotPacked := sload(lengthSlot) - for { let n := shr(208, shl(160, lengthSlotPacked)) } 1 {} { - if iszero(n) { - if iszero(or(isAdd, iszero(amount))) { - mstore(0x00, 0x5915f686) // `ERC5805CheckpointValueUnderflow()`. - revert(0x1c, 0x04) - } - newValue := amount - if iszero(or(eq(newValue, address()), shr(160, newValue))) { - sstore(lengthSlot, or(or(key, shl(48, 1)), shl(96, newValue))) - break - } - sstore(lengthSlot, or(or(key, shl(48, 1)), shl(96, address()))) - sstore(not(lengthSlot), newValue) - break - } - let checkpointSlot := add(sub(n, 1), lengthSlot) - let lastPacked := sload(checkpointSlot) - oldValue := shr(96, lastPacked) - if eq(oldValue, address()) { oldValue := sload(not(checkpointSlot)) } - for {} 1 {} { - if iszero(isAdd) { - newValue := sub(oldValue, amount) - if iszero(gt(newValue, oldValue)) { break } - mstore(0x00, 0x5915f686) // `ERC5805CheckpointValueUnderflow()`. - revert(0x1c, 0x04) - } - newValue := add(oldValue, amount) - if iszero(lt(newValue, oldValue)) { break } - mstore(0x00, 0x9dbbeb75) // `ERC5805CheckpointValueOverflow()`. - revert(0x1c, 0x04) - } - let lastKey := and(0xffffffffffff, lastPacked) - if iszero(eq(lastKey, key)) { - n := add(1, n) - checkpointSlot := add(1, checkpointSlot) - sstore(lengthSlot, add(shl(48, 1), lengthSlotPacked)) - } - if or(gt(lastKey, key), shr(48, n)) { invalid() } - if iszero(or(eq(newValue, address()), shr(160, newValue))) { - sstore(checkpointSlot, or(or(key, shl(48, n)), shl(96, newValue))) - break - } - sstore(checkpointSlot, or(or(key, shl(48, n)), shl(96, address()))) - sstore(not(checkpointSlot), newValue) - break - } - } - } - - /// @dev Returns the latest value in the checkpoints. - function _checkpointLatest(uint256 lengthSlot) private view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(208, shl(160, sload(lengthSlot))) - if result { - lengthSlot := add(sub(result, 1), lengthSlot) // Reuse for `checkpointSlot`. - result := shr(96, sload(lengthSlot)) - if eq(result, address()) { result := sload(not(lengthSlot)) } - } - } - } - - /// @dev Returns checkpoint value with the largest key that is less than or equal to `key`. - function _checkpointUpperLookupRecent(uint256 lengthSlot, uint256 key) - private - view - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - let l := 0 // Low. - let h := shr(208, shl(160, sload(lengthSlot))) // High. - // Start the binary search nearer to the right to optimize for recent checkpoints. - for {} iszero(lt(h, 6)) {} { - let m := shl(4, lt(0xffff, h)) - m := shl(shr(1, or(m, shl(3, lt(0xff, shr(m, h))))), 16) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := sub(h, shr(1, add(m, div(h, m)))) // Approx `h - sqrt(h)`. - if iszero(lt(key, and(sload(add(m, lengthSlot)), 0xffffffffffff))) { - l := add(1, m) - break - } - h := m - break - } - // Binary search. - for {} lt(l, h) {} { - let m := shr(1, add(l, h)) // Won't overflow in practice. - if iszero(lt(key, and(sload(add(m, lengthSlot)), 0xffffffffffff))) { - l := add(1, m) - continue - } - h := m - } - let checkpointSlot := add(sub(h, 1), lengthSlot) - result := mul(iszero(iszero(h)), shr(96, sload(checkpointSlot))) - if eq(result, address()) { result := sload(not(checkpointSlot)) } - } - } - - /// @dev Reverts with `ERC5805FutureLookup()`. - function _revertERC5805FutureLookup() private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xf9874464) // `ERC5805FutureLookup()`. - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/tokens/ERC2981.sol b/grouperBot/lib/solady/src/tokens/ERC2981.sol deleted file mode 100644 index be1c7a7..0000000 --- a/grouperBot/lib/solady/src/tokens/ERC2981.sol +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple ERC2981 NFT Royalty Standard implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC2981.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/common/ERC2981.sol) -abstract contract ERC2981 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The royalty fee numerator exceeds the fee denominator. - error RoyaltyOverflow(); - - /// @dev The royalty receiver cannot be the zero address. - error RoyaltyReceiverIsZeroAddress(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The default royalty info is given by: - /// ``` - /// let packed := sload(_ERC2981_MASTER_SLOT_SEED) - /// let receiver := shr(96, packed) - /// let royaltyFraction := xor(packed, shl(96, receiver)) - /// ``` - /// - /// The per token royalty info is given by. - /// ``` - /// mstore(0x00, tokenId) - /// mstore(0x20, _ERC2981_MASTER_SLOT_SEED) - /// let packed := sload(keccak256(0x00, 0x40)) - /// let receiver := shr(96, packed) - /// let royaltyFraction := xor(packed, shl(96, receiver)) - /// ``` - uint256 private constant _ERC2981_MASTER_SLOT_SEED = 0xaa4ec00224afccfdb7; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC2981 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Checks that `_feeDenominator` is non-zero. - constructor() { - require(_feeDenominator() != 0, "Fee denominator cannot be zero."); - } - - /// @dev Returns the denominator for the royalty amount. - /// Defaults to 10000, which represents fees in basis points. - /// Override this function to return a custom amount if needed. - function _feeDenominator() internal pure virtual returns (uint96) { - return 10000; - } - - /// @dev Returns true if this contract implements the interface defined by `interfaceId`. - /// See: https://eips.ethereum.org/EIPS/eip-165 - /// This function call must use less than 30000 gas. - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, interfaceId) - // ERC165: 0x01ffc9a7, ERC2981: 0x2a55205a. - result := or(eq(s, 0x01ffc9a7), eq(s, 0x2a55205a)) - } - } - - /// @dev Returns the `receiver` and `royaltyAmount` for `tokenId` sold at `salePrice`. - function royaltyInfo(uint256 tokenId, uint256 salePrice) - public - view - virtual - returns (address receiver, uint256 royaltyAmount) - { - uint256 feeDenominator = _feeDenominator(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, tokenId) - mstore(0x20, _ERC2981_MASTER_SLOT_SEED) - let packed := sload(keccak256(0x00, 0x40)) - receiver := shr(96, packed) - if iszero(receiver) { - packed := sload(mload(0x20)) - receiver := shr(96, packed) - } - let x := salePrice - let y := xor(packed, shl(96, receiver)) // `feeNumerator`. - // Overflow check, equivalent to `require(y == 0 || x <= type(uint256).max / y)`. - // Out-of-gas revert. Should not be triggered in practice, but included for safety. - returndatacopy(returndatasize(), returndatasize(), mul(y, gt(x, div(not(0), y)))) - royaltyAmount := div(mul(x, y), feeDenominator) - } - } - - /// @dev Sets the default royalty `receiver` and `feeNumerator`. - /// - /// Requirements: - /// - `receiver` must not be the zero address. - /// - `feeNumerator` must not be greater than the fee denominator. - function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { - uint256 feeDenominator = _feeDenominator(); - /// @solidity memory-safe-assembly - assembly { - feeNumerator := shr(160, shl(160, feeNumerator)) - if gt(feeNumerator, feeDenominator) { - mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`. - revert(0x1c, 0x04) - } - let packed := shl(96, receiver) - if iszero(packed) { - mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`. - revert(0x1c, 0x04) - } - sstore(_ERC2981_MASTER_SLOT_SEED, or(packed, feeNumerator)) - } - } - - /// @dev Sets the default royalty `receiver` and `feeNumerator` to zero. - function _deleteDefaultRoyalty() internal virtual { - /// @solidity memory-safe-assembly - assembly { - sstore(_ERC2981_MASTER_SLOT_SEED, 0) - } - } - - /// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId`. - /// - /// Requirements: - /// - `receiver` must not be the zero address. - /// - `feeNumerator` must not be greater than the fee denominator. - function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) - internal - virtual - { - uint256 feeDenominator = _feeDenominator(); - /// @solidity memory-safe-assembly - assembly { - feeNumerator := shr(160, shl(160, feeNumerator)) - if gt(feeNumerator, feeDenominator) { - mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`. - revert(0x1c, 0x04) - } - let packed := shl(96, receiver) - if iszero(packed) { - mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`. - revert(0x1c, 0x04) - } - mstore(0x00, tokenId) - mstore(0x20, _ERC2981_MASTER_SLOT_SEED) - sstore(keccak256(0x00, 0x40), or(packed, feeNumerator)) - } - } - - /// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId` to zero. - function _resetTokenRoyalty(uint256 tokenId) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, tokenId) - mstore(0x20, _ERC2981_MASTER_SLOT_SEED) - sstore(keccak256(0x00, 0x40), 0) - } - } -} diff --git a/grouperBot/lib/solady/src/tokens/ERC4626.sol b/grouperBot/lib/solady/src/tokens/ERC4626.sol deleted file mode 100644 index 6860882..0000000 --- a/grouperBot/lib/solady/src/tokens/ERC4626.sol +++ /dev/null @@ -1,527 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC20} from "./ERC20.sol"; -import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; -import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; - -/// @notice Simple ERC4626 tokenized Vault implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC4626.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol) -abstract contract ERC4626 is ERC20 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The default underlying decimals. - uint8 internal constant _DEFAULT_UNDERLYING_DECIMALS = 18; - - /// @dev The default decimals offset. - uint8 internal constant _DEFAULT_DECIMALS_OFFSET = 0; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Cannot deposit more than the max limit. - error DepositMoreThanMax(); - - /// @dev Cannot mint more than the max limit. - error MintMoreThanMax(); - - /// @dev Cannot withdraw more than the max limit. - error WithdrawMoreThanMax(); - - /// @dev Cannot redeem more than the max limit. - error RedeemMoreThanMax(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted during a mint call or deposit call. - event Deposit(address indexed by, address indexed owner, uint256 assets, uint256 shares); - - /// @dev Emitted during a withdraw call or redeem call. - event Withdraw( - address indexed by, - address indexed to, - address indexed owner, - uint256 assets, - uint256 shares - ); - - /// @dev `keccak256(bytes("Deposit(address,address,uint256,uint256)"))`. - uint256 private constant _DEPOSIT_EVENT_SIGNATURE = - 0xdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7; - - /// @dev `keccak256(bytes("Withdraw(address,address,address,uint256,uint256)"))`. - uint256 private constant _WITHDRAW_EVENT_SIGNATURE = - 0xfbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC4626 CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev To be overridden to return the address of the underlying asset. - /// - /// - MUST be an ERC20 token contract. - /// - MUST NOT revert. - function asset() public view virtual returns (address); - - /// @dev To be overridden to return the number of decimals of the underlying asset. - /// Default: 18. - /// - /// - MUST NOT revert. - function _underlyingDecimals() internal view virtual returns (uint8) { - return _DEFAULT_UNDERLYING_DECIMALS; - } - - /// @dev Override to return a non-zero value to make the inflation attack even more unfeasible. - /// Only used when {_useVirtualShares} returns true. - /// Default: 0. - /// - /// - MUST NOT revert. - function _decimalsOffset() internal view virtual returns (uint8) { - return _DEFAULT_DECIMALS_OFFSET; - } - - /// @dev Returns whether virtual shares will be used to mitigate the inflation attack. - /// See: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/3706 - /// Override to return true or false. - /// Default: true. - /// - /// - MUST NOT revert. - function _useVirtualShares() internal view virtual returns (bool) { - return true; - } - - /// @dev Returns the decimals places of the token. - /// - /// - MUST NOT revert. - function decimals() public view virtual override(ERC20) returns (uint8) { - if (!_useVirtualShares()) return _underlyingDecimals(); - return _underlyingDecimals() + _decimalsOffset(); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ASSET DECIMALS GETTER HELPER */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper function to get the decimals of the underlying asset. - /// Useful for setting the return value of `_underlyingDecimals` during initialization. - /// If the retrieval succeeds, `success` will be true, and `result` will hold the result. - /// Otherwise, `success` will be false, and `result` will be zero. - /// - /// Example usage: - /// ``` - /// (bool success, uint8 result) = _tryGetAssetDecimals(underlying); - /// _decimals = success ? result : _DEFAULT_UNDERLYING_DECIMALS; - /// ``` - function _tryGetAssetDecimals(address underlying) - internal - view - returns (bool success, uint8 result) - { - /// @solidity memory-safe-assembly - assembly { - // Store the function selector of `decimals()`. - mstore(0x00, 0x313ce567) - // Arguments are evaluated last to first. - success := - and( - // Returned value is less than 256, at left-padded to 32 bytes. - and(lt(mload(0x00), 0x100), gt(returndatasize(), 0x1f)), - // The staticcall succeeds. - staticcall(gas(), underlying, 0x1c, 0x04, 0x00, 0x20) - ) - result := mul(mload(0x00), success) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ACCOUNTING LOGIC */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the total amount of the underlying asset managed by the Vault. - /// - /// - SHOULD include any compounding that occurs from the yield. - /// - MUST be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT revert. - function totalAssets() public view virtual returns (uint256 assets) { - assets = SafeTransferLib.balanceOf(asset(), address(this)); - } - - /// @dev Returns the amount of shares that the Vault will exchange for the amount of - /// assets provided, in an ideal scenario where all conditions are met. - /// - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, during the actual exchange. - /// - MUST NOT revert. - /// - /// Note: This calculation MAY NOT reflect the "per-user" price-per-share, and instead - /// should reflect the "average-user's" price-per-share, i.e. what the average user should - /// expect to see when exchanging to and from. - function convertToShares(uint256 assets) public view virtual returns (uint256 shares) { - if (!_useVirtualShares()) { - uint256 supply = totalSupply(); - return _eitherIsZero(assets, supply) - ? _initialConvertToShares(assets) - : FixedPointMathLib.fullMulDiv(assets, supply, totalAssets()); - } - uint256 o = _decimalsOffset(); - if (o == uint256(0)) { - return FixedPointMathLib.fullMulDiv(assets, totalSupply() + 1, _inc(totalAssets())); - } - return FixedPointMathLib.fullMulDiv(assets, totalSupply() + 10 ** o, _inc(totalAssets())); - } - - /// @dev Returns the amount of assets that the Vault will exchange for the amount of - /// shares provided, in an ideal scenario where all conditions are met. - /// - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, during the actual exchange. - /// - MUST NOT revert. - /// - /// Note: This calculation MAY NOT reflect the "per-user" price-per-share, and instead - /// should reflect the "average-user's" price-per-share, i.e. what the average user should - /// expect to see when exchanging to and from. - function convertToAssets(uint256 shares) public view virtual returns (uint256 assets) { - if (!_useVirtualShares()) { - uint256 supply = totalSupply(); - return supply == uint256(0) - ? _initialConvertToAssets(shares) - : FixedPointMathLib.fullMulDiv(shares, totalAssets(), supply); - } - uint256 o = _decimalsOffset(); - if (o == uint256(0)) { - return FixedPointMathLib.fullMulDiv(shares, totalAssets() + 1, _inc(totalSupply())); - } - return FixedPointMathLib.fullMulDiv(shares, totalAssets() + 1, totalSupply() + 10 ** o); - } - - /// @dev Allows an on-chain or off-chain user to simulate the effects of their deposit - /// at the current block, given current on-chain conditions. - /// - /// - MUST return as close to and no more than the exact amount of Vault shares that - /// will be minted in a deposit call in the same transaction, i.e. deposit should - /// return the same or more shares as `previewDeposit` if call in the same transaction. - /// - MUST NOT account for deposit limits like those returned from `maxDeposit` and should - /// always act as if the deposit will be accepted, regardless of approvals, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of this. - /// - MUST not revert. - /// - /// Note: Any unfavorable discrepancy between `convertToShares` and `previewDeposit` SHOULD - /// be considered slippage in share price or some other type of condition, meaning - /// the depositor will lose assets by depositing. - function previewDeposit(uint256 assets) public view virtual returns (uint256 shares) { - shares = convertToShares(assets); - } - - /// @dev Allows an on-chain or off-chain user to simulate the effects of their mint - /// at the current block, given current on-chain conditions. - /// - /// - MUST return as close to and no fewer than the exact amount of assets that - /// will be deposited in a mint call in the same transaction, i.e. mint should - /// return the same or fewer assets as `previewMint` if called in the same transaction. - /// - MUST NOT account for mint limits like those returned from `maxMint` and should - /// always act as if the mint will be accepted, regardless of approvals, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of this. - /// - MUST not revert. - /// - /// Note: Any unfavorable discrepancy between `convertToAssets` and `previewMint` SHOULD - /// be considered slippage in share price or some other type of condition, - /// meaning the depositor will lose assets by minting. - function previewMint(uint256 shares) public view virtual returns (uint256 assets) { - if (!_useVirtualShares()) { - uint256 supply = totalSupply(); - return supply == uint256(0) - ? _initialConvertToAssets(shares) - : FixedPointMathLib.fullMulDivUp(shares, totalAssets(), supply); - } - uint256 o = _decimalsOffset(); - if (o == uint256(0)) { - return FixedPointMathLib.fullMulDivUp(shares, totalAssets() + 1, _inc(totalSupply())); - } - return FixedPointMathLib.fullMulDivUp(shares, totalAssets() + 1, totalSupply() + 10 ** o); - } - - /// @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal - /// at the current block, given the current on-chain conditions. - /// - /// - MUST return as close to and no fewer than the exact amount of Vault shares that - /// will be burned in a withdraw call in the same transaction, i.e. withdraw should - /// return the same or fewer shares as `previewWithdraw` if call in the same transaction. - /// - MUST NOT account for withdrawal limits like those returned from `maxWithdraw` and should - /// always act as if the withdrawal will be accepted, regardless of share balance, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of this. - /// - MUST not revert. - /// - /// Note: Any unfavorable discrepancy between `convertToShares` and `previewWithdraw` SHOULD - /// be considered slippage in share price or some other type of condition, - /// meaning the depositor will lose assets by depositing. - function previewWithdraw(uint256 assets) public view virtual returns (uint256 shares) { - if (!_useVirtualShares()) { - uint256 supply = totalSupply(); - return _eitherIsZero(assets, supply) - ? _initialConvertToShares(assets) - : FixedPointMathLib.fullMulDivUp(assets, supply, totalAssets()); - } - uint256 o = _decimalsOffset(); - if (o == uint256(0)) { - return FixedPointMathLib.fullMulDivUp(assets, totalSupply() + 1, _inc(totalAssets())); - } - return FixedPointMathLib.fullMulDivUp(assets, totalSupply() + 10 ** o, _inc(totalAssets())); - } - - /// @dev Allows an on-chain or off-chain user to simulate the effects of their redemption - /// at the current block, given current on-chain conditions. - /// - /// - MUST return as close to and no more than the exact amount of assets that - /// will be withdrawn in a redeem call in the same transaction, i.e. redeem should - /// return the same or more assets as `previewRedeem` if called in the same transaction. - /// - MUST NOT account for redemption limits like those returned from `maxRedeem` and should - /// always act as if the redemption will be accepted, regardless of approvals, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of this. - /// - MUST NOT revert. - /// - /// Note: Any unfavorable discrepancy between `convertToAssets` and `previewRedeem` SHOULD - /// be considered slippage in share price or some other type of condition, - /// meaning the depositor will lose assets by depositing. - function previewRedeem(uint256 shares) public view virtual returns (uint256 assets) { - assets = convertToAssets(shares); - } - - /// @dev Private helper to return if either value is zero. - function _eitherIsZero(uint256 a, uint256 b) private pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := or(iszero(a), iszero(b)) - } - } - - /// @dev Private helper to return `x + 1` without the overflow check. - /// Used for computing the denominator input to `FixedPointMathLib.fullMulDiv(a, b, x + 1)`. - /// When `x == type(uint256).max`, we get `x + 1 == 0` (mod 2**256 - 1), - /// and `FixedPointMathLib.fullMulDiv` will revert as the denominator is zero. - function _inc(uint256 x) private pure returns (uint256) { - unchecked { - return x + 1; - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DEPOSIT / WITHDRAWAL LIMIT LOGIC */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the maximum amount of the underlying asset that can be deposited - /// into the Vault for `to`, via a deposit call. - /// - /// - MUST return a limited value if `to` is subject to some deposit limit. - /// - MUST return `2**256-1` if there is no maximum limit. - /// - MUST NOT revert. - function maxDeposit(address to) public view virtual returns (uint256 maxAssets) { - to = to; // Silence unused variable warning. - maxAssets = type(uint256).max; - } - - /// @dev Returns the maximum amount of the Vault shares that can be minter for `to`, - /// via a mint call. - /// - /// - MUST return a limited value if `to` is subject to some mint limit. - /// - MUST return `2**256-1` if there is no maximum limit. - /// - MUST NOT revert. - function maxMint(address to) public view virtual returns (uint256 maxShares) { - to = to; // Silence unused variable warning. - maxShares = type(uint256).max; - } - - /// @dev Returns the maximum amount of the underlying asset that can be withdrawn - /// from the `owner`'s balance in the Vault, via a withdraw call. - /// - /// - MUST return a limited value if `owner` is subject to some withdrawal limit or timelock. - /// - MUST NOT revert. - function maxWithdraw(address owner) public view virtual returns (uint256 maxAssets) { - maxAssets = convertToAssets(balanceOf(owner)); - } - - /// @dev Returns the maximum amount of Vault shares that can be redeemed - /// from the `owner`'s balance in the Vault, via a redeem call. - /// - /// - MUST return a limited value if `owner` is subject to some withdrawal limit or timelock. - /// - MUST return `balanceOf(owner)` otherwise. - /// - MUST NOT revert. - function maxRedeem(address owner) public view virtual returns (uint256 maxShares) { - maxShares = balanceOf(owner); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DEPOSIT / WITHDRAWAL LOGIC */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Mints `shares` Vault shares to `to` by depositing exactly `assets` - /// of underlying tokens. - /// - /// - MUST emit the {Deposit} event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault - /// contract before the deposit execution, and are accounted for during deposit. - /// - MUST revert if all of `assets` cannot be deposited, such as due to deposit limit, - /// slippage, insufficient approval, etc. - /// - /// Note: Most implementations will require pre-approval of the Vault with the - /// Vault's underlying `asset` token. - function deposit(uint256 assets, address to) public virtual returns (uint256 shares) { - if (assets > maxDeposit(to)) _revert(0xb3c61a83); // `DepositMoreThanMax()`. - shares = previewDeposit(assets); - _deposit(msg.sender, to, assets, shares); - } - - /// @dev Mints exactly `shares` Vault shares to `to` by depositing `assets` - /// of underlying tokens. - /// - /// - MUST emit the {Deposit} event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault - /// contract before the mint execution, and are accounted for during mint. - /// - MUST revert if all of `shares` cannot be deposited, such as due to deposit limit, - /// slippage, insufficient approval, etc. - /// - /// Note: Most implementations will require pre-approval of the Vault with the - /// Vault's underlying `asset` token. - function mint(uint256 shares, address to) public virtual returns (uint256 assets) { - if (shares > maxMint(to)) _revert(0x6a695959); // `MintMoreThanMax()`. - assets = previewMint(shares); - _deposit(msg.sender, to, assets, shares); - } - - /// @dev Burns `shares` from `owner` and sends exactly `assets` of underlying tokens to `to`. - /// - /// - MUST emit the {Withdraw} event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault - /// contract before the withdraw execution, and are accounted for during withdraw. - /// - MUST revert if all of `assets` cannot be withdrawn, such as due to withdrawal limit, - /// slippage, insufficient balance, etc. - /// - /// Note: Some implementations will require pre-requesting to the Vault before a withdrawal - /// may be performed. Those methods should be performed separately. - function withdraw(uint256 assets, address to, address owner) - public - virtual - returns (uint256 shares) - { - if (assets > maxWithdraw(owner)) _revert(0x936941fc); // `WithdrawMoreThanMax()`. - shares = previewWithdraw(assets); - _withdraw(msg.sender, to, owner, assets, shares); - } - - /// @dev Burns exactly `shares` from `owner` and sends `assets` of underlying tokens to `to`. - /// - /// - MUST emit the {Withdraw} event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault - /// contract before the redeem execution, and are accounted for during redeem. - /// - MUST revert if all of shares cannot be redeemed, such as due to withdrawal limit, - /// slippage, insufficient balance, etc. - /// - /// Note: Some implementations will require pre-requesting to the Vault before a redeem - /// may be performed. Those methods should be performed separately. - function redeem(uint256 shares, address to, address owner) - public - virtual - returns (uint256 assets) - { - if (shares > maxRedeem(owner)) _revert(0x4656425a); // `RedeemMoreThanMax()`. - assets = previewRedeem(shares); - _withdraw(msg.sender, to, owner, assets, shares); - } - - /// @dev Internal helper for reverting efficiently. - function _revert(uint256 s) private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, s) - revert(0x1c, 0x04) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For deposits and mints. - /// - /// Emits a {Deposit} event. - function _deposit(address by, address to, uint256 assets, uint256 shares) internal virtual { - SafeTransferLib.safeTransferFrom(asset(), by, address(this), assets); - _mint(to, shares); - /// @solidity memory-safe-assembly - assembly { - // Emit the {Deposit} event. - mstore(0x00, assets) - mstore(0x20, shares) - let m := shr(96, not(0)) - log3(0x00, 0x40, _DEPOSIT_EVENT_SIGNATURE, and(m, by), and(m, to)) - } - _afterDeposit(assets, shares); - } - - /// @dev For withdrawals and redemptions. - /// - /// Emits a {Withdraw} event. - function _withdraw(address by, address to, address owner, uint256 assets, uint256 shares) - internal - virtual - { - if (by != owner) _spendAllowance(owner, by, shares); - _beforeWithdraw(assets, shares); - _burn(owner, shares); - SafeTransferLib.safeTransfer(asset(), to, assets); - /// @solidity memory-safe-assembly - assembly { - // Emit the {Withdraw} event. - mstore(0x00, assets) - mstore(0x20, shares) - let m := shr(96, not(0)) - log4(0x00, 0x40, _WITHDRAW_EVENT_SIGNATURE, and(m, by), and(m, to), and(m, owner)) - } - } - - /// @dev Internal conversion function (from assets to shares) to apply when the Vault is empty. - /// Only used when {_useVirtualShares} returns false. - /// - /// Note: Make sure to keep this function consistent with {_initialConvertToAssets} - /// when overriding it. - function _initialConvertToShares(uint256 assets) - internal - view - virtual - returns (uint256 shares) - { - shares = assets; - } - - /// @dev Internal conversion function (from shares to assets) to apply when the Vault is empty. - /// Only used when {_useVirtualShares} returns false. - /// - /// Note: Make sure to keep this function consistent with {_initialConvertToShares} - /// when overriding it. - function _initialConvertToAssets(uint256 shares) - internal - view - virtual - returns (uint256 assets) - { - assets = shares; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HOOKS TO OVERRIDE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Hook that is called before any withdrawal or redemption. - function _beforeWithdraw(uint256 assets, uint256 shares) internal virtual {} - - /// @dev Hook that is called after any deposit or mint. - function _afterDeposit(uint256 assets, uint256 shares) internal virtual {} -} diff --git a/grouperBot/lib/solady/src/tokens/ERC6909.sol b/grouperBot/lib/solady/src/tokens/ERC6909.sol deleted file mode 100644 index 39940cf..0000000 --- a/grouperBot/lib/solady/src/tokens/ERC6909.sol +++ /dev/null @@ -1,547 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple EIP-6909 implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC6909.sol) -/// -/// @dev Note: -/// The ERC6909 standard allows minting and transferring to and from the zero address, -/// minting and transferring zero tokens, as well as self-approvals. -/// For performance, this implementation WILL NOT revert for such actions. -/// Please add any checks with overrides if desired. -/// -/// If you are overriding: -/// - Make sure all variables written to storage are properly cleaned -// (e.g. the bool value for `isOperator` MUST be either 1 or 0 under the hood). -/// - Check that the overridden function is actually used in the function you want to -/// change the behavior of. Much of the code has been manually inlined for performance. -abstract contract ERC6909 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Insufficient balance. - error InsufficientBalance(); - - /// @dev Insufficient permission to perform the action. - error InsufficientPermission(); - - /// @dev The balance has overflowed. - error BalanceOverflow(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when `by` transfers `amount` of token `id` from `from` to `to`. - event Transfer( - address by, address indexed from, address indexed to, uint256 indexed id, uint256 amount - ); - - /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. - event OperatorSet(address indexed owner, address indexed operator, bool approved); - - /// @dev Emitted when `owner` approves `spender` to use `amount` of `id` token. - event Approval( - address indexed owner, address indexed spender, uint256 indexed id, uint256 amount - ); - - /// @dev `keccak256(bytes("Transfer(address,address,address,uint256,uint256)"))`. - uint256 private constant _TRANSFER_EVENT_SIGNATURE = - 0x1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac728859; - - /// @dev `keccak256(bytes("OperatorSet(address,address,bool)"))`. - uint256 private constant _OPERATOR_SET_EVENT_SIGNATURE = - 0xceb576d9f15e4e200fdb5096d64d5dfd667e16def20c1eefd14256d8e3faa267; - - /// @dev `keccak256(bytes("Approval(address,address,uint256,uint256)"))`. - uint256 private constant _APPROVAL_EVENT_SIGNATURE = - 0xb3fd5071835887567a0671151121894ddccc2842f1d10bedad13e0d17cace9a7; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The `ownerSlotSeed` of a given owner is given by. - /// ``` - /// let ownerSlotSeed := or(_ERC6909_MASTER_SLOT_SEED, shl(96, owner)) - /// ``` - /// - /// The balance slot of `owner` is given by. - /// ``` - /// mstore(0x20, ownerSlotSeed) - /// mstore(0x00, id) - /// let balanceSlot := keccak256(0x00, 0x40) - /// ``` - /// - /// The operator approval slot of `owner` is given by. - /// ``` - /// mstore(0x20, ownerSlotSeed) - /// mstore(0x00, operator) - /// let operatorApprovalSlot := keccak256(0x0c, 0x34) - /// ``` - /// - /// The allowance slot of (`owner`, `spender`, `id`) is given by: - /// ``` - /// mstore(0x34, ownerSlotSeed) - /// mstore(0x14, spender) - /// mstore(0x00, id) - /// let allowanceSlot := keccak256(0x00, 0x54) - /// ``` - uint256 private constant _ERC6909_MASTER_SLOT_SEED = 0xedcaa89a82293940; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC6909 METADATA */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the name for token `id`. - function name(uint256 id) public view virtual returns (string memory); - - /// @dev Returns the symbol for token `id`. - function symbol(uint256 id) public view virtual returns (string memory); - - /// @dev Returns the number of decimals for token `id`. - /// Returns 18 by default. - /// Please override this function if you need to return a custom value. - function decimals(uint256 id) public view virtual returns (uint8) { - id = id; // Silence compiler warning. - return 18; - } - - /// @dev Returns the Uniform Resource Identifier (URI) for token `id`. - function tokenURI(uint256 id) public view virtual returns (string memory); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC6909 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the amount of token `id` owned by `owner`. - function balanceOf(address owner, uint256 id) public view virtual returns (uint256 amount) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, _ERC6909_MASTER_SLOT_SEED) - mstore(0x14, owner) - mstore(0x00, id) - amount := sload(keccak256(0x00, 0x40)) - } - } - - /// @dev Returns the amount of token `id` that `spender` can spend on behalf of `owner`. - function allowance(address owner, address spender, uint256 id) - public - view - virtual - returns (uint256 amount) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x34, _ERC6909_MASTER_SLOT_SEED) - mstore(0x28, owner) - mstore(0x14, spender) - mstore(0x00, id) - amount := sload(keccak256(0x00, 0x54)) - // Restore the part of the free memory pointer that has been overwritten. - mstore(0x34, 0x00) - } - } - - /// @dev Checks if a `spender` is approved by `owner` to manage all of their tokens. - function isOperator(address owner, address spender) public view virtual returns (bool status) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, _ERC6909_MASTER_SLOT_SEED) - mstore(0x14, owner) - mstore(0x00, spender) - status := sload(keccak256(0x0c, 0x34)) - } - } - - /// @dev Transfers `amount` of token `id` from the caller to `to`. - /// - /// Requirements: - /// - caller must at least have `amount`. - /// - /// Emits a {Transfer} event. - function transfer(address to, uint256 id, uint256 amount) - public - payable - virtual - returns (bool) - { - _beforeTokenTransfer(msg.sender, to, id, amount); - /// @solidity memory-safe-assembly - assembly { - /// Compute the balance slot and load its value. - mstore(0x20, _ERC6909_MASTER_SLOT_SEED) - mstore(0x14, caller()) - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Compute the balance slot of `to`. - mstore(0x14, to) - mstore(0x00, id) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - // Revert if the balance overflows. - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x89560ca1) // `BalanceOverflow()`. - revert(0x1c, 0x04) - } - // Store the updated balance of `to`. - sstore(toBalanceSlot, toBalanceAfter) - // Emit the {Transfer} event. - mstore(0x00, caller()) - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, caller(), shr(96, shl(96, to)), id) - } - _afterTokenTransfer(msg.sender, to, id, amount); - return true; - } - - /// @dev Transfers `amount` of token `id` from `from` to `to`. - /// - /// Note: - /// - Allowance is NOT deducted if it is `type(uint256).max`. - /// - Allowance is NOT deducted if `from` is an operator. - /// - For efficiency, allowance is deducted even if `from` is the caller. - /// - /// Requirements: - /// - `from` must at least have `amount` of token `id`. - /// - The caller must have at least `amount` of allowance to transfer the - /// tokens of `from` or approved as an operator. - /// - /// Emits a {Transfer} event. - function transferFrom(address from, address to, uint256 id, uint256 amount) - public - payable - virtual - returns (bool) - { - _beforeTokenTransfer(from, to, id, amount); - /// @solidity memory-safe-assembly - assembly { - // Compute the operator slot and load its value. - mstore(0x34, _ERC6909_MASTER_SLOT_SEED) - mstore(0x28, from) - mstore(0x14, caller()) - // Check if the caller is an operator. - if iszero(sload(keccak256(0x20, 0x34))) { - // Compute the allowance slot and load its value. - mstore(0x00, id) - let allowanceSlot := keccak256(0x00, 0x54) - let allowance_ := sload(allowanceSlot) - // If the allowance is not the maximum uint256 value. - if add(allowance_, 1) { - // Revert if the amount to be transferred exceeds the allowance. - if gt(amount, allowance_) { - mstore(0x00, 0xdeda9030) // `InsufficientPermission()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated allowance. - sstore(allowanceSlot, sub(allowance_, amount)) - } - } - // Compute the balance slot and load its value. - mstore(0x14, id) - let fromBalanceSlot := keccak256(0x14, 0x40) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Compute the balance slot of `to`. - mstore(0x28, to) - mstore(0x14, id) - let toBalanceSlot := keccak256(0x14, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - // Revert if the balance overflows. - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x89560ca1) // `BalanceOverflow()`. - revert(0x1c, 0x04) - } - // Store the updated balance of `to`. - sstore(toBalanceSlot, toBalanceAfter) - // Emit the {Transfer} event. - mstore(0x00, caller()) - mstore(0x20, amount) - // forgefmt: disable-next-line - log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), shr(96, shl(96, to)), id) - // Restore the part of the free memory pointer that has been overwritten. - mstore(0x34, 0x00) - } - _afterTokenTransfer(from, to, id, amount); - return true; - } - - /// @dev Sets `amount` as the allowance of `spender` for the caller for token `id`. - /// - /// Emits a {Approval} event. - function approve(address spender, uint256 id, uint256 amount) - public - payable - virtual - returns (bool) - { - /// @solidity memory-safe-assembly - assembly { - // Compute the allowance slot and store the amount. - mstore(0x34, _ERC6909_MASTER_SLOT_SEED) - mstore(0x28, caller()) - mstore(0x14, spender) - mstore(0x00, id) - sstore(keccak256(0x00, 0x54), amount) - // Emit the {Approval} event. - mstore(0x00, amount) - log4(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, caller(), shr(96, mload(0x20)), id) - // Restore the part of the free memory pointer that has been overwritten. - mstore(0x34, 0x00) - } - return true; - } - - /// @dev Sets whether `operator` is approved to manage the tokens of the caller. - /// - /// Emits {OperatorSet} event. - function setOperator(address operator, bool approved) public payable virtual returns (bool) { - /// @solidity memory-safe-assembly - assembly { - // Convert `approved` to `0` or `1`. - let approvedCleaned := iszero(iszero(approved)) - // Compute the operator slot and store the approved. - mstore(0x20, _ERC6909_MASTER_SLOT_SEED) - mstore(0x14, caller()) - mstore(0x00, operator) - sstore(keccak256(0x0c, 0x34), approvedCleaned) - // Emit the {OperatorSet} event. - mstore(0x20, approvedCleaned) - log3(0x20, 0x20, _OPERATOR_SET_EVENT_SIGNATURE, caller(), shr(96, mload(0x0c))) - } - return true; - } - - /// @dev Returns true if this contract implements the interface defined by `interfaceId`. - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, interfaceId) - // ERC165: 0x01ffc9a7, ERC6909: 0x0f632fb3. - result := or(eq(s, 0x01ffc9a7), eq(s, 0x0f632fb3)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Mints `amount` of token `id` to `to`. - /// - /// Emits a {Transfer} event. - function _mint(address to, uint256 id, uint256 amount) internal virtual { - _beforeTokenTransfer(address(0), to, id, amount); - /// @solidity memory-safe-assembly - assembly { - // Compute the balance slot. - mstore(0x20, _ERC6909_MASTER_SLOT_SEED) - mstore(0x14, to) - mstore(0x00, id) - let toBalanceSlot := keccak256(0x00, 0x40) - // Add and store the updated balance - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - // Revert if the balance overflows. - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x89560ca1) // `BalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - // Emit the {Transfer} event. - mstore(0x00, caller()) - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, 0, shr(96, shl(96, to)), id) - } - _afterTokenTransfer(address(0), to, id, amount); - } - - /// @dev Burns `amount` token `id` from `from`. - /// - /// Emits a {Transfer} event. - function _burn(address from, uint256 id, uint256 amount) internal virtual { - _beforeTokenTransfer(from, address(0), id, amount); - /// @solidity memory-safe-assembly - assembly { - // Compute the balance slot. - mstore(0x20, _ERC6909_MASTER_SLOT_SEED) - mstore(0x14, from) - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Emit the {Transfer} event. - mstore(0x00, caller()) - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), 0, id) - } - _afterTokenTransfer(from, address(0), id, amount); - } - - /// @dev Transfers `amount` of token `id` from `from` to `to`. - /// - /// Note: - /// - Allowance is NOT deducted if it is `type(uint256).max`. - /// - Allowance is NOT deducted if `from` is an operator. - /// - For efficiency, allowance is deducted even if `from` is `by`. - /// - /// Requirements: - /// - `from` must at least have `amount` of token `id`. - /// - If `by` is not the zero address, - /// it must have at least `amount` of allowance to transfer the - /// tokens of `from` or approved as an operator. - /// - /// Emits a {Transfer} event. - function _transfer(address by, address from, address to, uint256 id, uint256 amount) - internal - virtual - { - _beforeTokenTransfer(from, to, id, amount); - /// @solidity memory-safe-assembly - assembly { - let bitmaskAddress := 0xffffffffffffffffffffffffffffffffffffffff - // Compute the operator slot and load its value. - mstore(0x34, _ERC6909_MASTER_SLOT_SEED) - mstore(0x28, from) - // If `by` is not the zero address. - if and(bitmaskAddress, by) { - mstore(0x14, by) - // Check if the `by` is an operator. - if iszero(sload(keccak256(0x20, 0x34))) { - // Compute the allowance slot and load its value. - mstore(0x00, id) - let allowanceSlot := keccak256(0x00, 0x54) - let allowance_ := sload(allowanceSlot) - // If the allowance is not the maximum uint256 value. - if add(allowance_, 1) { - // Revert if the amount to be transferred exceeds the allowance. - if gt(amount, allowance_) { - mstore(0x00, 0xdeda9030) // `InsufficientPermission()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated allowance. - sstore(allowanceSlot, sub(allowance_, amount)) - } - } - } - // Compute the balance slot and load its value. - mstore(0x14, id) - let fromBalanceSlot := keccak256(0x14, 0x40) - let fromBalance := sload(fromBalanceSlot) - // Revert if insufficient balance. - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - // Subtract and store the updated balance. - sstore(fromBalanceSlot, sub(fromBalance, amount)) - // Compute the balance slot of `to`. - mstore(0x28, to) - mstore(0x14, id) - let toBalanceSlot := keccak256(0x14, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - // Revert if the balance overflows. - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x89560ca1) // `BalanceOverflow()`. - revert(0x1c, 0x04) - } - // Store the updated balance of `to`. - sstore(toBalanceSlot, toBalanceAfter) - // Emit the {Transfer} event. - mstore(0x00, and(bitmaskAddress, by)) - mstore(0x20, amount) - // forgefmt: disable-next-line - log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, and(bitmaskAddress, from), and(bitmaskAddress, to), id) - // Restore the part of the free memory pointer that has been overwritten. - mstore(0x34, 0x00) - } - _afterTokenTransfer(from, to, id, amount); - } - - /// @dev Sets `amount` as the allowance of `spender` for `owner` for token `id`. - /// - /// Emits a {Approval} event. - function _approve(address owner, address spender, uint256 id, uint256 amount) - internal - virtual - { - /// @solidity memory-safe-assembly - assembly { - // Compute the allowance slot and store the amount. - mstore(0x34, _ERC6909_MASTER_SLOT_SEED) - mstore(0x28, owner) - mstore(0x14, spender) - mstore(0x00, id) - sstore(keccak256(0x00, 0x54), amount) - // Emit the {Approval} event. - mstore(0x00, amount) - // forgefmt: disable-next-line - log4(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, shr(96, mload(0x34)), shr(96, mload(0x20)), id) - // Restore the part of the free memory pointer that has been overwritten. - mstore(0x34, 0x00) - } - } - - /// @dev Sets whether `operator` is approved to manage the tokens of `owner`. - /// - /// Emits {OperatorSet} event. - function _setOperator(address owner, address operator, bool approved) internal virtual { - /// @solidity memory-safe-assembly - assembly { - // Convert `approved` to `0` or `1`. - let approvedCleaned := iszero(iszero(approved)) - // Compute the operator slot and store the approved. - mstore(0x20, _ERC6909_MASTER_SLOT_SEED) - mstore(0x14, owner) - mstore(0x00, operator) - sstore(keccak256(0x0c, 0x34), approvedCleaned) - // Emit the {OperatorSet} event. - mstore(0x20, approvedCleaned) - // forgefmt: disable-next-line - log3(0x20, 0x20, _OPERATOR_SET_EVENT_SIGNATURE, shr(96, shl(96, owner)), shr(96, mload(0x0c))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HOOKS TO OVERRIDE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Hook that is called before any transfer of tokens. - /// This includes minting and burning. - function _beforeTokenTransfer(address from, address to, uint256 id, uint256 amount) - internal - virtual - {} - - /// @dev Hook that is called after any transfer of tokens. - /// This includes minting and burning. - function _afterTokenTransfer(address from, address to, uint256 id, uint256 amount) - internal - virtual - {} -} diff --git a/grouperBot/lib/solady/src/tokens/ERC721.sol b/grouperBot/lib/solady/src/tokens/ERC721.sol deleted file mode 100644 index 19bcc0b..0000000 --- a/grouperBot/lib/solady/src/tokens/ERC721.sol +++ /dev/null @@ -1,913 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple ERC721 implementation with storage hitchhiking. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol) -/// -/// @dev Note: -/// - The ERC721 standard allows for self-approvals. -/// For performance, this implementation WILL NOT revert for such actions. -/// Please add any checks with overrides if desired. -/// - For performance, methods are made payable where permitted by the ERC721 standard. -/// - The `safeTransfer` functions use the identity precompile (0x4) -/// to copy memory internally. -/// -/// If you are overriding: -/// - NEVER violate the ERC721 invariant: -/// the balance of an owner MUST always be equal to their number of ownership slots. -/// The transfer functions do not have an underflow guard for user token balances. -/// - Make sure all variables written to storage are properly cleaned -/// (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood). -/// - Check that the overridden function is actually used in the function you want to -/// change the behavior of. Much of the code has been manually inlined for performance. -abstract contract ERC721 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev An account can hold up to 4294967295 tokens. - uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Only the token owner or an approved account can manage the token. - error NotOwnerNorApproved(); - - /// @dev The token does not exist. - error TokenDoesNotExist(); - - /// @dev The token already exists. - error TokenAlreadyExists(); - - /// @dev Cannot query the balance for the zero address. - error BalanceQueryForZeroAddress(); - - /// @dev Cannot mint or transfer to the zero address. - error TransferToZeroAddress(); - - /// @dev The token must be owned by `from`. - error TransferFromIncorrectOwner(); - - /// @dev The recipient's balance has overflowed. - error AccountBalanceOverflow(); - - /// @dev Cannot safely transfer to a contract that does not implement - /// the ERC721Receiver interface. - error TransferToNonERC721ReceiverImplementer(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when token `id` is transferred from `from` to `to`. - event Transfer(address indexed from, address indexed to, uint256 indexed id); - - /// @dev Emitted when `owner` enables `account` to manage the `id` token. - event Approval(address indexed owner, address indexed account, uint256 indexed id); - - /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. - event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); - - /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`. - uint256 private constant _TRANSFER_EVENT_SIGNATURE = - 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; - - /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`. - uint256 private constant _APPROVAL_EVENT_SIGNATURE = - 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925; - - /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. - uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = - 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ownership data slot of `id` is given by: - /// ``` - /// mstore(0x00, id) - /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - /// let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - /// ``` - /// Bits Layout: - /// - [0..159] `addr` - /// - [160..255] `extraData` - /// - /// The approved address slot is given by: `add(1, ownershipSlot)`. - /// - /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip - /// - /// The balance slot of `owner` is given by: - /// ``` - /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - /// mstore(0x00, owner) - /// let balanceSlot := keccak256(0x0c, 0x1c) - /// ``` - /// Bits Layout: - /// - [0..31] `balance` - /// - [32..255] `aux` - /// - /// The `operator` approval slot of `owner` is given by: - /// ``` - /// mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) - /// mstore(0x00, owner) - /// let operatorApprovalSlot := keccak256(0x0c, 0x30) - /// ``` - uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; - - /// @dev Pre-shifted and pre-masked constant. - uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC721 METADATA */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the token collection name. - function name() public view virtual returns (string memory); - - /// @dev Returns the token collection symbol. - function symbol() public view virtual returns (string memory); - - /// @dev Returns the Uniform Resource Identifier (URI) for token `id`. - function tokenURI(uint256 id) public view virtual returns (string memory); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC721 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the owner of token `id`. - /// - /// Requirements: - /// - Token `id` must exist. - function ownerOf(uint256 id) public view virtual returns (address result) { - result = _ownerOf(id); - /// @solidity memory-safe-assembly - assembly { - if iszero(result) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns the number of tokens owned by `owner`. - /// - /// Requirements: - /// - `owner` must not be the zero address. - function balanceOf(address owner) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - // Revert if the `owner` is the zero address. - if iszero(owner) { - mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`. - revert(0x1c, 0x04) - } - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE) - } - } - - /// @dev Returns the account approved to manage token `id`. - /// - /// Requirements: - /// - Token `id` must exist. - function getApproved(uint256 id) public view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - if iszero(shl(96, sload(ownershipSlot))) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - result := sload(add(1, ownershipSlot)) - } - } - - /// @dev Sets `account` as the approved account to manage token `id`. - /// - /// Requirements: - /// - Token `id` must exist. - /// - The caller must be the owner of the token, - /// or an approved operator for the token owner. - /// - /// Emits an {Approval} event. - function approve(address account, uint256 id) public payable virtual { - _approve(msg.sender, account, id); - } - - /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. - function isApprovedForAll(address owner, address operator) - public - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, operator) - mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) - mstore(0x00, owner) - result := sload(keccak256(0x0c, 0x30)) - } - } - - /// @dev Sets whether `operator` is approved to manage the tokens of the caller. - /// - /// Emits an {ApprovalForAll} event. - function setApprovalForAll(address operator, bool isApproved) public virtual { - /// @solidity memory-safe-assembly - assembly { - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`msg.sender`, `operator`). - mstore(0x1c, operator) - mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) - mstore(0x00, caller()) - sstore(keccak256(0x0c, 0x30), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - // forgefmt: disable-next-item - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))) - } - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - The caller must be the owner of the token, or be approved to manage the token. - /// - /// Emits a {Transfer} event. - function transferFrom(address from, address to, uint256 id) public payable virtual { - _beforeTokenTransfer(from, to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - let bitmaskAddress := shr(96, not(0)) - from := and(bitmaskAddress, from) - to := and(bitmaskAddress, to) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller())) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - let owner := and(bitmaskAddress, ownershipPacked) - // Revert if the token does not exist, or if `from` is not the owner. - if iszero(mul(owner, eq(owner, from))) { - // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`. - mstore(shl(2, iszero(owner)), 0xceea21b6a1148100) - revert(0x1c, 0x04) - } - // Load, check, and update the token approval. - { - mstore(0x00, from) - let approvedAddress := sload(add(1, ownershipSlot)) - // Revert if the caller is not the owner, nor approved. - if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) { - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Delete the approved address if any. - if approvedAddress { sstore(add(1, ownershipSlot), 0) } - } - // Update with the new owner. - sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) - // Decrement the balance of `from`. - { - let fromBalanceSlot := keccak256(0x0c, 0x1c) - sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) - } - // Increment the balance of `to`. - { - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x1c) - let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) - } - _afterTokenTransfer(from, to, id); - } - - /// @dev Equivalent to `safeTransferFrom(from, to, id, "")`. - function safeTransferFrom(address from, address to, uint256 id) public payable virtual { - transferFrom(from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, ""); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - The caller must be the owner of the token, or be approved to manage the token. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function safeTransferFrom(address from, address to, uint256 id, bytes calldata data) - public - payable - virtual - { - transferFrom(from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); - } - - /// @dev Returns true if this contract implements the interface defined by `interfaceId`. - /// See: https://eips.ethereum.org/EIPS/eip-165 - /// This function call must use less than 30000 gas. - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, interfaceId) - // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f. - result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL QUERY FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if token `id` exists. - function _exists(uint256 id) internal view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := iszero(iszero(shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))) - } - } - - /// @dev Returns the owner of token `id`. - /// Returns the zero address instead of reverting if the token does not exist. - function _ownerOf(uint256 id) internal view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL DATA HITCHHIKING FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // For performance, no events are emitted for the hitchhiking setters. - // Please emit your own events if required. - - /// @dev Returns the auxiliary data for `owner`. - /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. - /// Auxiliary data can be set for any address, even if it does not have any tokens. - function _getAux(address owner) internal view virtual returns (uint224 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - result := shr(32, sload(keccak256(0x0c, 0x1c))) - } - } - - /// @dev Set the auxiliary data for `owner` to `value`. - /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. - /// Auxiliary data can be set for any address, even if it does not have any tokens. - function _setAux(address owner, uint224 value) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - let balanceSlot := keccak256(0x0c, 0x1c) - let packed := sload(balanceSlot) - sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed))))) - } - } - - /// @dev Returns the extra data for token `id`. - /// Minting, transferring, burning a token will not change the extra data. - /// The extra data can be set on a non-existent token. - function _getExtraData(uint256 id) internal view virtual returns (uint96 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20))))) - } - } - - /// @dev Sets the extra data for token `id` to `value`. - /// Minting, transferring, burning a token will not change the extra data. - /// The extra data can be set on a non-existent token. - function _setExtraData(uint256 id, uint96 value) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let packed := sload(ownershipSlot) - sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed))))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL MINT FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Mints token `id` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must not exist. - /// - `to` cannot be the zero address. - /// - /// Emits a {Transfer} event. - function _mint(address to, uint256 id) internal virtual { - _beforeTokenTransfer(address(0), to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - to := shr(96, shl(96, to)) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - // Revert if the token already exists. - if shl(96, ownershipPacked) { - mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`. - revert(0x1c, 0x04) - } - // Update with the owner. - sstore(ownershipSlot, or(ownershipPacked, to)) - // Increment the balance of the owner. - { - mstore(0x00, to) - let balanceSlot := keccak256(0x0c, 0x1c) - let balanceSlotPacked := add(sload(balanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(balanceSlot, balanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) - } - _afterTokenTransfer(address(0), to, id); - } - - /// @dev Mints token `id` to `to`, and updates the extra data for token `id` to `value`. - /// Does NOT check if token `id` already exists (assumes `id` is auto-incrementing). - /// - /// Requirements: - /// - /// - `to` cannot be the zero address. - /// - /// Emits a {Transfer} event. - function _mintAndSetExtraDataUnchecked(address to, uint256 id, uint96 value) internal virtual { - _beforeTokenTransfer(address(0), to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - to := shr(96, shl(96, to)) - // Update with the owner and extra data. - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - sstore(add(id, add(id, keccak256(0x00, 0x20))), or(shl(160, value), to)) - // Increment the balance of the owner. - { - mstore(0x00, to) - let balanceSlot := keccak256(0x0c, 0x1c) - let balanceSlotPacked := add(sload(balanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(balanceSlot, balanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) - } - _afterTokenTransfer(address(0), to, id); - } - - /// @dev Equivalent to `_safeMint(to, id, "")`. - function _safeMint(address to, uint256 id) internal virtual { - _safeMint(to, id, ""); - } - - /// @dev Mints token `id` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must not exist. - /// - `to` cannot be the zero address. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function _safeMint(address to, uint256 id, bytes memory data) internal virtual { - _mint(to, id); - if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL BURN FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_burn(address(0), id)`. - function _burn(uint256 id) internal virtual { - _burn(address(0), id); - } - - /// @dev Destroys token `id`, using `by`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - If `by` is not the zero address, - /// it must be the owner of the token, or be approved to manage the token. - /// - /// Emits a {Transfer} event. - function _burn(address by, uint256 id) internal virtual { - address owner = ownerOf(id); - _beforeTokenTransfer(owner, address(0), id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - by := shr(96, shl(96, by)) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - // Reload the owner in case it is changed in `_beforeTokenTransfer`. - owner := shr(96, shl(96, ownershipPacked)) - // Revert if the token does not exist. - if iszero(owner) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - // Load and check the token approval. - { - mstore(0x00, owner) - let approvedAddress := sload(add(1, ownershipSlot)) - // If `by` is not the zero address, do the authorization check. - // Revert if the `by` is not the owner, nor approved. - if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) { - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Delete the approved address if any. - if approvedAddress { sstore(add(1, ownershipSlot), 0) } - } - // Clear the owner. - sstore(ownershipSlot, xor(ownershipPacked, owner)) - // Decrement the balance of `owner`. - { - let balanceSlot := keccak256(0x0c, 0x1c) - sstore(balanceSlot, sub(sload(balanceSlot), 1)) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id) - } - _afterTokenTransfer(owner, address(0), id); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL APPROVAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether `account` is the owner of token `id`, or is approved to manage it. - /// - /// Requirements: - /// - Token `id` must exist. - function _isApprovedOrOwner(address account, uint256 id) - internal - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - result := 1 - // Clear the upper 96 bits. - account := shr(96, shl(96, account)) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let owner := shr(96, shl(96, sload(ownershipSlot))) - // Revert if the token does not exist. - if iszero(owner) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - // Check if `account` is the `owner`. - if iszero(eq(account, owner)) { - mstore(0x00, owner) - // Check if `account` is approved to manage the token. - if iszero(sload(keccak256(0x0c, 0x30))) { - result := eq(account, sload(add(1, ownershipSlot))) - } - } - } - } - - /// @dev Returns the account approved to manage token `id`. - /// Returns the zero address instead of reverting if the token does not exist. - function _getApproved(uint256 id) internal view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20))))) - } - } - - /// @dev Equivalent to `_approve(address(0), account, id)`. - function _approve(address account, uint256 id) internal virtual { - _approve(address(0), account, id); - } - - /// @dev Sets `account` as the approved account to manage token `id`, using `by`. - /// - /// Requirements: - /// - Token `id` must exist. - /// - If `by` is not the zero address, `by` must be the owner - /// or an approved operator for the token owner. - /// - /// Emits a {Approval} event. - function _approve(address by, address account, uint256 id) internal virtual { - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - let bitmaskAddress := shr(96, not(0)) - account := and(bitmaskAddress, account) - by := and(bitmaskAddress, by) - // Load the owner of the token. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let owner := and(bitmaskAddress, sload(ownershipSlot)) - // Revert if the token does not exist. - if iszero(owner) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - // If `by` is not the zero address, do the authorization check. - // Revert if `by` is not the owner, nor approved. - if iszero(or(iszero(by), eq(by, owner))) { - mstore(0x00, owner) - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Sets `account` as the approved account to manage `id`. - sstore(add(1, ownershipSlot), account) - // Emit the {Approval} event. - log4(codesize(), 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id) - } - } - - /// @dev Approve or remove the `operator` as an operator for `by`, - /// without authorization checks. - /// - /// Emits an {ApprovalForAll} event. - function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - by := shr(96, shl(96, by)) - operator := shr(96, shl(96, operator)) - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`by`, `operator`). - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) - mstore(0x00, by) - sstore(keccak256(0x0c, 0x30), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL TRANSFER FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_transfer(address(0), from, to, id)`. - function _transfer(address from, address to, uint256 id) internal virtual { - _transfer(address(0), from, to, id); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - If `by` is not the zero address, - /// it must be the owner of the token, or be approved to manage the token. - /// - /// Emits a {Transfer} event. - function _transfer(address by, address from, address to, uint256 id) internal virtual { - _beforeTokenTransfer(from, to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - let bitmaskAddress := shr(96, not(0)) - from := and(bitmaskAddress, from) - to := and(bitmaskAddress, to) - by := and(bitmaskAddress, by) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - let owner := and(bitmaskAddress, ownershipPacked) - // Revert if the token does not exist, or if `from` is not the owner. - if iszero(mul(owner, eq(owner, from))) { - // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`. - mstore(shl(2, iszero(owner)), 0xceea21b6a1148100) - revert(0x1c, 0x04) - } - // Load, check, and update the token approval. - { - mstore(0x00, from) - let approvedAddress := sload(add(1, ownershipSlot)) - // If `by` is not the zero address, do the authorization check. - // Revert if the `by` is not the owner, nor approved. - if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) { - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Delete the approved address if any. - if approvedAddress { sstore(add(1, ownershipSlot), 0) } - } - // Update with the new owner. - sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) - // Decrement the balance of `from`. - { - let fromBalanceSlot := keccak256(0x0c, 0x1c) - sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) - } - // Increment the balance of `to`. - { - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x1c) - let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) - } - _afterTokenTransfer(from, to, id); - } - - /// @dev Equivalent to `_safeTransfer(from, to, id, "")`. - function _safeTransfer(address from, address to, uint256 id) internal virtual { - _safeTransfer(from, to, id, ""); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - The caller must be the owner of the token, or be approved to manage the token. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function _safeTransfer(address from, address to, uint256 id, bytes memory data) - internal - virtual - { - _transfer(address(0), from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); - } - - /// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`. - function _safeTransfer(address by, address from, address to, uint256 id) internal virtual { - _safeTransfer(by, from, to, id, ""); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - If `by` is not the zero address, - /// it must be the owner of the token, or be approved to manage the token. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data) - internal - virtual - { - _transfer(by, from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HOOKS FOR OVERRIDING */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Hook that is called before any token transfers, including minting and burning. - function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {} - - /// @dev Hook that is called after any token transfers, including minting and burning. - function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {} - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if `a` has bytecode of non-zero length. - function _hasCode(address a) private view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := extcodesize(a) // Can handle dirty upper bits. - } - } - - /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`. - /// Reverts if the target does not support the function correctly. - function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data) - private - { - /// @solidity memory-safe-assembly - assembly { - // Prepare the calldata. - let m := mload(0x40) - let onERC721ReceivedSelector := 0x150b7a02 - mstore(m, onERC721ReceivedSelector) - mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`. - mstore(add(m, 0x40), shr(96, shl(96, from))) - mstore(add(m, 0x60), id) - mstore(add(m, 0x80), 0x80) - let n := mload(data) - mstore(add(m, 0xa0), n) - if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) } - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it. - if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) { - mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } -} diff --git a/grouperBot/lib/solady/src/tokens/WETH.sol b/grouperBot/lib/solady/src/tokens/WETH.sol deleted file mode 100644 index b80b5ba..0000000 --- a/grouperBot/lib/solady/src/tokens/WETH.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC20} from "./ERC20.sol"; - -/// @notice Simple Wrapped Ether implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/WETH.sol) -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/WETH.sol) -/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol) -contract WETH is ERC20 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ETH transfer has failed. - error ETHTransferFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC20 METADATA */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the name of the token. - function name() public view virtual override returns (string memory) { - return "Wrapped Ether"; - } - - /// @dev Returns the symbol of the token. - function symbol() public view virtual override returns (string memory) { - return "WETH"; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* WETH */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deposits `amount` ETH of the caller and mints `amount` WETH to the caller. - function deposit() public payable virtual { - _mint(msg.sender, msg.value); - } - - /// @dev Burns `amount` WETH of the caller and sends `amount` ETH to the caller. - function withdraw(uint256 amount) public virtual { - _burn(msg.sender, amount); - /// @solidity memory-safe-assembly - assembly { - // Transfer the ETH and check if it succeeded or not. - if iszero(call(gas(), caller(), amount, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Equivalent to `deposit()`. - receive() external payable virtual { - deposit(); - } -} diff --git a/grouperBot/lib/solady/src/tokens/ext/zksync/ERC1155.sol b/grouperBot/lib/solady/src/tokens/ext/zksync/ERC1155.sol deleted file mode 100644 index 7b16b54..0000000 --- a/grouperBot/lib/solady/src/tokens/ext/zksync/ERC1155.sol +++ /dev/null @@ -1,1143 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple ERC1155 implementation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ext/zksync/ERC1155.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC1155/ERC1155.sol) -/// -/// @dev Note: -/// - The ERC1155 standard allows for self-approvals. -/// For performance, this implementation WILL NOT revert for such actions. -/// Please add any checks with overrides if desired. -/// -/// If you are overriding: -/// - Make sure all variables written to storage are properly cleaned -// (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood). -/// - Check that the overridden function is actually used in the function you want to -/// change the behavior of. Much of the code has been manually inlined for performance. -abstract contract ERC1155 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The lengths of the input arrays are not the same. - error ArrayLengthsMismatch(); - - /// @dev Cannot mint or transfer to the zero address. - error TransferToZeroAddress(); - - /// @dev The recipient's balance has overflowed. - error AccountBalanceOverflow(); - - /// @dev Insufficient balance. - error InsufficientBalance(); - - /// @dev Only the token owner or an approved account can manage the tokens. - error NotOwnerNorApproved(); - - /// @dev Cannot safely transfer to a contract that does not implement - /// the ERC1155Receiver interface. - error TransferToNonERC1155ReceiverImplementer(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when `amount` of token `id` is transferred - /// from `from` to `to` by `operator`. - event TransferSingle( - address indexed operator, - address indexed from, - address indexed to, - uint256 id, - uint256 amount - ); - - /// @dev Emitted when `amounts` of token `ids` are transferred - /// from `from` to `to` by `operator`. - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] amounts - ); - - /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. - event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); - - /// @dev Emitted when the Uniform Resource Identifier (URI) for token `id` - /// is updated to `value`. This event is not used in the base contract. - /// You may need to emit this event depending on your URI logic. - /// - /// See: https://eips.ethereum.org/EIPS/eip-1155#metadata - event URI(string value, uint256 indexed id); - - /// @dev `keccak256(bytes("TransferSingle(address,address,address,uint256,uint256)"))`. - uint256 private constant _TRANSFER_SINGLE_EVENT_SIGNATURE = - 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62; - - /// @dev `keccak256(bytes("TransferBatch(address,address,address,uint256[],uint256[])"))`. - uint256 private constant _TRANSFER_BATCH_EVENT_SIGNATURE = - 0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb; - - /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. - uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = - 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The `ownerSlotSeed` of a given owner is given by. - /// ``` - /// let ownerSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner)) - /// ``` - /// - /// The balance slot of `owner` is given by. - /// ``` - /// mstore(0x20, ownerSlotSeed) - /// mstore(0x00, id) - /// let balanceSlot := keccak256(0x00, 0x40) - /// ``` - /// - /// The operator approval slot of `owner` is given by. - /// ``` - /// mstore(0x20, ownerSlotSeed) - /// mstore(0x00, operator) - /// let operatorApprovalSlot := keccak256(0x0c, 0x34) - /// ``` - uint256 private constant _ERC1155_MASTER_SLOT_SEED = 0x9a31110384e0b0c9; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1155 METADATA */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the URI for token `id`. - /// - /// You can either return the same templated URI for all token IDs, - /// (e.g. "https://example.com/api/{id}.json"), - /// or return a unique URI for each `id`. - /// - /// See: https://eips.ethereum.org/EIPS/eip-1155#metadata - function uri(uint256 id) public view virtual returns (string memory); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1155 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the amount of `id` owned by `owner`. - function balanceOf(address owner, uint256 id) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, owner) - mstore(0x00, id) - result := sload(keccak256(0x00, 0x40)) - } - } - - /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. - function isApprovedForAll(address owner, address operator) - public - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, owner) - mstore(0x00, operator) - result := sload(keccak256(0x0c, 0x34)) - } - } - - /// @dev Sets whether `operator` is approved to manage the tokens of the caller. - /// - /// Emits a {ApprovalForAll} event. - function setApprovalForAll(address operator, bool isApproved) public virtual { - /// @solidity memory-safe-assembly - assembly { - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`msg.sender`, `operator`). - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, caller()) - mstore(0x00, operator) - sstore(keccak256(0x0c, 0x34), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - // forgefmt: disable-next-line - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))) - } - } - - /// @dev Transfers `amount` of `id` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `from` must have at least `amount` of `id`. - /// - If the caller is not `from`, - /// it must be approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155Received}, which is called upon a batch transfer. - /// - /// Emits a {TransferSingle} event. - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) public virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) - let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) - mstore(0x20, fromSlotSeed) - // Clear the upper 96 bits. - from := shr(96, fromSlotSeed) - to := shr(96, toSlotSeed) - // Revert if `to` is the zero address. - if iszero(to) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // If the caller is not `from`, do the authorization check. - if iszero(eq(caller(), from)) { - mstore(0x00, caller()) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Subtract and store the updated balance of `from`. - { - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, toSlotSeed) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), from, to) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - // Do the {onERC1155Received} check if `to` is a smart contract. - if extcodesize(to) { - // Prepare the calldata. - let m := mload(0x40) - // `onERC1155Received(address,address,uint256,uint256,bytes)`. - mstore(m, 0xf23a6e61) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), from) - mstore(add(m, 0x60), id) - mstore(add(m, 0x80), amount) - mstore(add(m, 0xa0), 0xa0) - mstore(add(m, 0xc0), data.length) - calldatacopy(add(m, 0xe0), data.offset, data.length) - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), add(0xc4, data.length), m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xf23a6e61))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Transfers `amounts` of `ids` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `from` must have at least `amount` of `id`. - /// - `ids` and `amounts` must have the same length. - /// - If the caller is not `from`, - /// it must be approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155BatchReceived}, which is called upon a batch transfer. - /// - /// Emits a {TransferBatch} event. - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) public virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(ids.length, amounts.length)) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, from)) - let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, shl(96, to)) - mstore(0x20, fromSlotSeed) - // Clear the upper 96 bits. - from := shr(96, fromSlotSeed) - to := shr(96, toSlotSeed) - // Revert if `to` is the zero address. - if iszero(to) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // If the caller is not `from`, do the authorization check. - if iszero(eq(caller(), from)) { - mstore(0x00, caller()) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Loop through all the `ids` and update the balances. - { - for { let i := shl(5, ids.length) } i {} { - i := sub(i, 0x20) - let amount := calldataload(add(amounts.offset, i)) - // Subtract and store the updated balance of `from`. - { - mstore(0x20, fromSlotSeed) - mstore(0x00, calldataload(add(ids.offset, i))) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, toSlotSeed) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := shl(5, ids.length) - mstore(add(m, 0x40), ids.length) - calldatacopy(add(m, 0x60), ids.offset, n) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x60, n)) - let o := add(add(m, n), 0x60) - mstore(o, ids.length) - calldatacopy(add(o, 0x20), amounts.offset, n) - // Do the emit. - log4(m, add(add(n, n), 0x80), _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), from, to) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransferCalldata(from, to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - // Do the {onERC1155BatchReceived} check if `to` is a smart contract. - if extcodesize(to) { - mstore(0x00, to) // Cache `to` to prevent stack too deep. - let m := mload(0x40) - // Prepare the calldata. - // `onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)`. - mstore(m, 0xbc197c81) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), from) - // Copy the `ids`. - mstore(add(m, 0x60), 0xa0) - let n := shl(5, ids.length) - mstore(add(m, 0xc0), ids.length) - calldatacopy(add(m, 0xe0), ids.offset, n) - // Copy the `amounts`. - mstore(add(m, 0x80), add(0xc0, n)) - let o := add(add(m, n), 0xe0) - mstore(o, ids.length) - calldatacopy(add(o, 0x20), amounts.offset, n) - // Copy the `data`. - mstore(add(m, 0xa0), add(add(0xe0, n), n)) - o := add(add(o, n), 0x20) - mstore(o, data.length) - calldatacopy(add(o, 0x20), data.offset, data.length) - let nAll := add(0x104, add(data.length, add(n, n))) - // Revert if the call reverts. - if iszero(call(gas(), mload(0x00), 0, add(mload(0x40), 0x1c), nAll, m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xbc197c81))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Returns the amounts of `ids` for `owners. - /// - /// Requirements: - /// - `owners` and `ids` must have the same length. - function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) - public - view - virtual - returns (uint256[] memory balances) - { - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(ids.length, owners.length)) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - balances := mload(0x40) - mstore(balances, ids.length) - let o := add(balances, 0x20) - let i := shl(5, ids.length) - mstore(0x40, add(i, o)) - // Loop through all the `ids` and load the balances. - for {} i {} { - i := sub(i, 0x20) - let owner := calldataload(add(owners.offset, i)) - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, shl(96, owner))) - mstore(0x00, calldataload(add(ids.offset, i))) - mstore(add(o, i), sload(keccak256(0x00, 0x40))) - } - } - } - - /// @dev Returns true if this contract implements the interface defined by `interfaceId`. - /// See: https://eips.ethereum.org/EIPS/eip-165 - /// This function call must use less than 30000 gas. - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, interfaceId) - // ERC165: 0x01ffc9a7, ERC1155: 0xd9b67a26, ERC1155MetadataURI: 0x0e89341c. - result := or(or(eq(s, 0x01ffc9a7), eq(s, 0xd9b67a26)), eq(s, 0x0e89341c)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL MINT FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Mints `amount` of `id` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155Received}, which is called upon a batch transfer. - /// - /// Emits a {TransferSingle} event. - function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(address(0), to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, to) - mstore(0x00, id) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), 0, shr(96, to_)) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(address(0), to, _single(id), _single(amount), data); - } - if (_hasCode(to)) _checkOnERC1155Received(address(0), to, id, amount, data); - } - - /// @dev Mints `amounts` of `ids` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `ids` and `amounts` must have the same length. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155BatchReceived}, which is called upon a batch transfer. - /// - /// Emits a {TransferBatch} event. - function _batchMint( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(address(0), to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - if iszero(eq(mload(ids), mload(amounts))) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - // Loop through all the `ids` and update the balances. - { - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, to_)) - for { let i := shl(5, mload(ids)) } i { i := sub(i, 0x20) } { - let amount := mload(add(amounts, i)) - // Increase and store the updated balance of `to`. - { - mstore(0x00, mload(add(ids, i))) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0x40) - copy(o, ids, n) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x40, n)) - o := add(o, n) - n := add(0x20, shl(5, mload(amounts))) - copy(o, amounts, n) - n := sub(add(o, n), m) - // Do the emit. - log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), 0, shr(96, to_)) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(address(0), to, ids, amounts, data); - } - if (_hasCode(to)) _checkOnERC1155BatchReceived(address(0), to, ids, amounts, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL BURN FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_burn(address(0), from, id, amount)`. - function _burn(address from, uint256 id, uint256 amount) internal virtual { - _burn(address(0), from, id, amount); - } - - /// @dev Destroys `amount` of `id` from `from`. - /// - /// Requirements: - /// - `from` must have at least `amount` of `id`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - /// Emits a {TransferSingle} event. - function _burn(address by, address from, uint256 id, uint256 amount) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, address(0), _single(id), _single(amount), ""); - } - /// @solidity memory-safe-assembly - assembly { - let from_ := shl(96, from) - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, from_)) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - if iszero(or(iszero(shl(96, by)), eq(shl(96, by), from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Decrease and store the updated balance of `from`. - { - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), shr(96, from_), 0) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, address(0), _single(id), _single(amount), ""); - } - } - - /// @dev Equivalent to `_batchBurn(address(0), from, ids, amounts)`. - function _batchBurn(address from, uint256[] memory ids, uint256[] memory amounts) - internal - virtual - { - _batchBurn(address(0), from, ids, amounts); - } - - /// @dev Destroys `amounts` of `ids` from `from`. - /// - /// Requirements: - /// - `ids` and `amounts` must have the same length. - /// - `from` must have at least `amounts` of `ids`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - /// Emits a {TransferBatch} event. - function _batchBurn(address by, address from, uint256[] memory ids, uint256[] memory amounts) - internal - virtual - { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, address(0), ids, amounts, ""); - } - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - if iszero(eq(mload(ids), mload(amounts))) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let from_ := shl(96, from) - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, from_)) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - let by_ := shl(96, by) - if iszero(or(iszero(by_), eq(by_, from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Loop through all the `ids` and update the balances. - { - for { let i := shl(5, mload(ids)) } i { i := sub(i, 0x20) } { - let amount := mload(add(amounts, i)) - // Decrease and store the updated balance of `from`. - { - mstore(0x00, mload(add(ids, i))) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0x40) - copy(o, ids, n) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x40, n)) - o := add(o, n) - n := add(0x20, shl(5, mload(amounts))) - copy(o, amounts, n) - n := sub(add(o, n), m) - // Do the emit. - log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), shr(96, from_), 0) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, address(0), ids, amounts, ""); - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL APPROVAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Approve or remove the `operator` as an operator for `by`, - /// without authorization checks. - /// - /// Emits a {ApprovalForAll} event. - function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { - /// @solidity memory-safe-assembly - assembly { - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`by`, `operator`). - mstore(0x20, _ERC1155_MASTER_SLOT_SEED) - mstore(0x14, by) - mstore(0x00, operator) - sstore(keccak256(0x0c, 0x34), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - let m := shr(96, not(0)) - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, and(m, by), and(m, operator)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL TRANSFER FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_safeTransfer(address(0), from, to, id, amount, data)`. - function _safeTransfer(address from, address to, uint256 id, uint256 amount, bytes memory data) - internal - virtual - { - _safeTransfer(address(0), from, to, id, amount, data); - } - - /// @dev Transfers `amount` of `id` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `from` must have at least `amount` of `id`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155Received}, which is called upon a batch transfer. - /// - /// Emits a {TransferSingle} event. - function _safeTransfer( - address by, - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, _single(id), _single(amount), data); - } - /// @solidity memory-safe-assembly - assembly { - let from_ := shl(96, from) - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, from_)) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - let by_ := shl(96, by) - if iszero(or(iszero(by_), eq(by_, from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Subtract and store the updated balance of `from`. - { - mstore(0x00, id) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, or(_ERC1155_MASTER_SLOT_SEED, to_)) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - // Emit a {TransferSingle} event. - mstore(0x20, amount) - // forgefmt: disable-next-line - log4(0x00, 0x40, _TRANSFER_SINGLE_EVENT_SIGNATURE, caller(), shr(96, from_), shr(96, to_)) - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, _single(id), _single(amount), data); - } - if (_hasCode(to)) _checkOnERC1155Received(from, to, id, amount, data); - } - - /// @dev Equivalent to `_safeBatchTransfer(address(0), from, to, ids, amounts, data)`. - function _safeBatchTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - _safeBatchTransfer(address(0), from, to, ids, amounts, data); - } - - /// @dev Transfers `amounts` of `ids` from `from` to `to`. - /// - /// Requirements: - /// - `to` cannot be the zero address. - /// - `ids` and `amounts` must have the same length. - /// - `from` must have at least `amounts` of `ids`. - /// - If `by` is not the zero address, it must be either `from`, - /// or approved to manage the tokens of `from`. - /// - If `to` refers to a smart contract, it must implement - /// {ERC1155-onERC1155BatchReceived}, which is called upon a batch transfer. - /// - /// Emits a {TransferBatch} event. - function _safeBatchTransfer( - address by, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - if (_useBeforeTokenTransfer()) { - _beforeTokenTransfer(from, to, ids, amounts, data); - } - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - if iszero(eq(mload(ids), mload(amounts))) { - mstore(0x00, 0x3b800a46) // `ArrayLengthsMismatch()`. - revert(0x1c, 0x04) - } - let from_ := shl(96, from) - let to_ := shl(96, to) - // Revert if `to` is the zero address. - if iszero(to_) { - mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. - revert(0x1c, 0x04) - } - let fromSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, from_) - let toSlotSeed := or(_ERC1155_MASTER_SLOT_SEED, to_) - mstore(0x20, fromSlotSeed) - // If `by` is not the zero address, and not equal to `from`, - // check if it is approved to manage all the tokens of `from`. - let by_ := shl(96, by) - if iszero(or(iszero(by_), eq(by_, from_))) { - mstore(0x00, by) - if iszero(sload(keccak256(0x0c, 0x34))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Loop through all the `ids` and update the balances. - { - for { let i := shl(5, mload(ids)) } i { i := sub(i, 0x20) } { - let amount := mload(add(amounts, i)) - // Subtract and store the updated balance of `from`. - { - mstore(0x20, fromSlotSeed) - mstore(0x00, mload(add(ids, i))) - let fromBalanceSlot := keccak256(0x00, 0x40) - let fromBalance := sload(fromBalanceSlot) - if gt(amount, fromBalance) { - mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`. - revert(0x1c, 0x04) - } - sstore(fromBalanceSlot, sub(fromBalance, amount)) - } - // Increase and store the updated balance of `to`. - { - mstore(0x20, toSlotSeed) - let toBalanceSlot := keccak256(0x00, 0x40) - let toBalanceBefore := sload(toBalanceSlot) - let toBalanceAfter := add(toBalanceBefore, amount) - if lt(toBalanceAfter, toBalanceBefore) { - mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceAfter) - } - } - } - // Emit a {TransferBatch} event. - { - let m := mload(0x40) - // Copy the `ids`. - mstore(m, 0x40) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0x40) - copy(o, ids, n) - // Copy the `amounts`. - mstore(add(m, 0x20), add(0x40, n)) - o := add(o, n) - n := add(0x20, shl(5, mload(amounts))) - copy(o, amounts, n) - n := sub(add(o, n), m) - // Do the emit. - log4(m, n, _TRANSFER_BATCH_EVENT_SIGNATURE, caller(), shr(96, from_), shr(96, to_)) - } - } - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, ids, amounts, data); - } - if (_hasCode(to)) _checkOnERC1155BatchReceived(from, to, ids, amounts, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HOOKS FOR OVERRIDING */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Override this function to return true if `_beforeTokenTransfer` is used. - /// This is to help the compiler avoid producing dead bytecode. - function _useBeforeTokenTransfer() internal view virtual returns (bool) { - return false; - } - - /// @dev Hook that is called before any token transfer. - /// This includes minting and burning, as well as batched variants. - /// - /// The same hook is called on both single and batched variants. - /// For single transfers, the length of the `id` and `amount` arrays are 1. - function _beforeTokenTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - /// @dev Override this function to return true if `_afterTokenTransfer` is used. - /// This is to help the compiler avoid producing dead bytecode. - function _useAfterTokenTransfer() internal view virtual returns (bool) { - return false; - } - - /// @dev Hook that is called after any token transfer. - /// This includes minting and burning, as well as batched variants. - /// - /// The same hook is called on both single and batched variants. - /// For single transfers, the length of the `id` and `amount` arrays are 1. - function _afterTokenTransfer( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper for calling the `_afterTokenTransfer` hook. - /// This is to help the compiler avoid producing dead bytecode. - function _afterTokenTransferCalldata( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) private { - if (_useAfterTokenTransfer()) { - _afterTokenTransfer(from, to, ids, amounts, data); - } - } - - /// @dev Returns if `a` has bytecode of non-zero length. - function _hasCode(address a) private view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := extcodesize(a) // Can handle dirty upper bits. - } - } - - /// @dev Perform a call to invoke {IERC1155Receiver-onERC1155Received} on `to`. - /// Reverts if the target does not support the function correctly. - function _checkOnERC1155Received( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) private { - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - // Prepare the calldata. - let m := mload(0x40) - // `onERC1155Received(address,address,uint256,uint256,bytes)`. - mstore(m, 0xf23a6e61) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), shr(96, shl(96, from))) - mstore(add(m, 0x60), id) - mstore(add(m, 0x80), amount) - mstore(add(m, 0xa0), 0xa0) - let n := mload(data) - mstore(add(m, 0xc0), n) - copy(add(m, 0xe0), add(data, 0x20), n) - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), add(0xc4, n), m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xf23a6e61))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Perform a call to invoke {IERC1155Receiver-onERC1155BatchReceived} on `to`. - /// Reverts if the target does not support the function correctly. - function _checkOnERC1155BatchReceived( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) private { - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - // Prepare the calldata. - let m := mload(0x40) - // `onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)`. - mstore(m, 0xbc197c81) - mstore(add(m, 0x20), caller()) - mstore(add(m, 0x40), shr(96, shl(96, from))) - // Copy the `ids`. - mstore(add(m, 0x60), 0xa0) - let n := add(0x20, shl(5, mload(ids))) - let o := add(m, 0xc0) - copy(o, ids, n) - // Copy the `amounts`. - let s := add(0xa0, n) - mstore(add(m, 0x80), s) - o := add(o, n) - n := add(0x20, shl(5, mload(amounts))) - copy(o, amounts, n) - // Copy the `data`. - mstore(add(m, 0xa0), add(s, n)) - o := add(o, n) - n := add(0x20, mload(data)) - copy(o, data, n) - n := sub(add(o, n), add(m, 0x1c)) - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), n, m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it with the function selector. - if iszero(eq(mload(m), shl(224, 0xbc197c81))) { - mstore(0x00, 0x9c05499b) // `TransferToNonERC1155ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns `x` in an array with a single element. - function _single(uint256 x) private pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x40, add(result, 0x40)) - mstore(result, 1) - mstore(add(result, 0x20), x) - } - } -} diff --git a/grouperBot/lib/solady/src/tokens/ext/zksync/ERC721.sol b/grouperBot/lib/solady/src/tokens/ext/zksync/ERC721.sol deleted file mode 100644 index d736848..0000000 --- a/grouperBot/lib/solady/src/tokens/ext/zksync/ERC721.sol +++ /dev/null @@ -1,916 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Simple ERC721 implementation with storage hitchhiking. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ext/zksync/ERC721.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol) -/// -/// @dev Note: -/// - The ERC721 standard allows for self-approvals. -/// For performance, this implementation WILL NOT revert for such actions. -/// Please add any checks with overrides if desired. -/// - For performance, methods are made payable where permitted by the ERC721 standard. -/// -/// If you are overriding: -/// - NEVER violate the ERC721 invariant: -/// the balance of an owner MUST always be equal to their number of ownership slots. -/// The transfer functions do not have an underflow guard for user token balances. -/// - Make sure all variables written to storage are properly cleaned -/// (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood). -/// - Check that the overridden function is actually used in the function you want to -/// change the behavior of. Much of the code has been manually inlined for performance. -abstract contract ERC721 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev An account can hold up to 4294967295 tokens. - uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Only the token owner or an approved account can manage the token. - error NotOwnerNorApproved(); - - /// @dev The token does not exist. - error TokenDoesNotExist(); - - /// @dev The token already exists. - error TokenAlreadyExists(); - - /// @dev Cannot query the balance for the zero address. - error BalanceQueryForZeroAddress(); - - /// @dev Cannot mint or transfer to the zero address. - error TransferToZeroAddress(); - - /// @dev The token must be owned by `from`. - error TransferFromIncorrectOwner(); - - /// @dev The recipient's balance has overflowed. - error AccountBalanceOverflow(); - - /// @dev Cannot safely transfer to a contract that does not implement - /// the ERC721Receiver interface. - error TransferToNonERC721ReceiverImplementer(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when token `id` is transferred from `from` to `to`. - event Transfer(address indexed from, address indexed to, uint256 indexed id); - - /// @dev Emitted when `owner` enables `account` to manage the `id` token. - event Approval(address indexed owner, address indexed account, uint256 indexed id); - - /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. - event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); - - /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`. - uint256 private constant _TRANSFER_EVENT_SIGNATURE = - 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; - - /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`. - uint256 private constant _APPROVAL_EVENT_SIGNATURE = - 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925; - - /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. - uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = - 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ownership data slot of `id` is given by: - /// ``` - /// mstore(0x00, id) - /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - /// let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - /// ``` - /// Bits Layout: - /// - [0..159] `addr` - /// - [160..255] `extraData` - /// - /// The approved address slot is given by: `add(1, ownershipSlot)`. - /// - /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip - /// - /// The balance slot of `owner` is given by: - /// ``` - /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - /// mstore(0x00, owner) - /// let balanceSlot := keccak256(0x0c, 0x1c) - /// ``` - /// Bits Layout: - /// - [0..31] `balance` - /// - [32..255] `aux` - /// - /// The `operator` approval slot of `owner` is given by: - /// ``` - /// mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) - /// mstore(0x00, owner) - /// let operatorApprovalSlot := keccak256(0x0c, 0x30) - /// ``` - uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; - - /// @dev Pre-shifted and pre-masked constant. - uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC721 METADATA */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the token collection name. - function name() public view virtual returns (string memory); - - /// @dev Returns the token collection symbol. - function symbol() public view virtual returns (string memory); - - /// @dev Returns the Uniform Resource Identifier (URI) for token `id`. - function tokenURI(uint256 id) public view virtual returns (string memory); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC721 */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the owner of token `id`. - /// - /// Requirements: - /// - Token `id` must exist. - function ownerOf(uint256 id) public view virtual returns (address result) { - result = _ownerOf(id); - /// @solidity memory-safe-assembly - assembly { - if iszero(result) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns the number of tokens owned by `owner`. - /// - /// Requirements: - /// - `owner` must not be the zero address. - function balanceOf(address owner) public view virtual returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - // Revert if the `owner` is the zero address. - if iszero(owner) { - mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`. - revert(0x1c, 0x04) - } - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE) - } - } - - /// @dev Returns the account approved to manage token `id`. - /// - /// Requirements: - /// - Token `id` must exist. - function getApproved(uint256 id) public view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - if iszero(shl(96, sload(ownershipSlot))) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - result := sload(add(1, ownershipSlot)) - } - } - - /// @dev Sets `account` as the approved account to manage token `id`. - /// - /// Requirements: - /// - Token `id` must exist. - /// - The caller must be the owner of the token, - /// or an approved operator for the token owner. - /// - /// Emits an {Approval} event. - function approve(address account, uint256 id) public payable virtual { - _approve(msg.sender, account, id); - } - - /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. - function isApprovedForAll(address owner, address operator) - public - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, operator) - mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) - mstore(0x00, owner) - result := sload(keccak256(0x0c, 0x30)) - } - } - - /// @dev Sets whether `operator` is approved to manage the tokens of the caller. - /// - /// Emits an {ApprovalForAll} event. - function setApprovalForAll(address operator, bool isApproved) public virtual { - /// @solidity memory-safe-assembly - assembly { - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`msg.sender`, `operator`). - mstore(0x1c, operator) - mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) - mstore(0x00, caller()) - sstore(keccak256(0x0c, 0x30), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - // forgefmt: disable-next-item - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))) - } - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - The caller must be the owner of the token, or be approved to manage the token. - /// - /// Emits a {Transfer} event. - function transferFrom(address from, address to, uint256 id) public payable virtual { - _beforeTokenTransfer(from, to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - let bitmaskAddress := shr(96, not(0)) - from := and(bitmaskAddress, from) - to := and(bitmaskAddress, to) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller())) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - let owner := and(bitmaskAddress, ownershipPacked) - // Revert if the token does not exist, or if `from` is not the owner. - if iszero(mul(owner, eq(owner, from))) { - // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`. - mstore(shl(2, iszero(owner)), 0xceea21b6a1148100) - revert(0x1c, 0x04) - } - // Load, check, and update the token approval. - { - mstore(0x00, from) - let approvedAddress := sload(add(1, ownershipSlot)) - // Revert if the caller is not the owner, nor approved. - if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) { - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Delete the approved address if any. - if approvedAddress { sstore(add(1, ownershipSlot), 0) } - } - // Update with the new owner. - sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) - // Decrement the balance of `from`. - { - let fromBalanceSlot := keccak256(0x0c, 0x1c) - sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) - } - // Increment the balance of `to`. - { - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x1c) - let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) - } - _afterTokenTransfer(from, to, id); - } - - /// @dev Equivalent to `safeTransferFrom(from, to, id, "")`. - function safeTransferFrom(address from, address to, uint256 id) public payable virtual { - transferFrom(from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, ""); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - The caller must be the owner of the token, or be approved to manage the token. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function safeTransferFrom(address from, address to, uint256 id, bytes calldata data) - public - payable - virtual - { - transferFrom(from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); - } - - /// @dev Returns true if this contract implements the interface defined by `interfaceId`. - /// See: https://eips.ethereum.org/EIPS/eip-165 - /// This function call must use less than 30000 gas. - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let s := shr(224, interfaceId) - // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f. - result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL QUERY FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if token `id` exists. - function _exists(uint256 id) internal view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := iszero(iszero(shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))) - } - } - - /// @dev Returns the owner of token `id`. - /// Returns the zero address instead of reverting if the token does not exist. - function _ownerOf(uint256 id) internal view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL DATA HITCHHIKING FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // For performance, no events are emitted for the hitchhiking setters. - // Please emit your own events if required. - - /// @dev Returns the auxiliary data for `owner`. - /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. - /// Auxiliary data can be set for any address, even if it does not have any tokens. - function _getAux(address owner) internal view virtual returns (uint224 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - result := shr(32, sload(keccak256(0x0c, 0x1c))) - } - } - - /// @dev Set the auxiliary data for `owner` to `value`. - /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. - /// Auxiliary data can be set for any address, even if it does not have any tokens. - function _setAux(address owner, uint224 value) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner) - let balanceSlot := keccak256(0x0c, 0x1c) - let packed := sload(balanceSlot) - sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed))))) - } - } - - /// @dev Returns the extra data for token `id`. - /// Minting, transferring, burning a token will not change the extra data. - /// The extra data can be set on a non-existent token. - function _getExtraData(uint256 id) internal view virtual returns (uint96 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20))))) - } - } - - /// @dev Sets the extra data for token `id` to `value`. - /// Minting, transferring, burning a token will not change the extra data. - /// The extra data can be set on a non-existent token. - function _setExtraData(uint256 id, uint96 value) internal virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let packed := sload(ownershipSlot) - sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed))))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL MINT FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Mints token `id` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must not exist. - /// - `to` cannot be the zero address. - /// - /// Emits a {Transfer} event. - function _mint(address to, uint256 id) internal virtual { - _beforeTokenTransfer(address(0), to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - to := shr(96, shl(96, to)) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - // Revert if the token already exists. - if shl(96, ownershipPacked) { - mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`. - revert(0x1c, 0x04) - } - // Update with the owner. - sstore(ownershipSlot, or(ownershipPacked, to)) - // Increment the balance of the owner. - { - mstore(0x00, to) - let balanceSlot := keccak256(0x0c, 0x1c) - let balanceSlotPacked := add(sload(balanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(balanceSlot, balanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) - } - _afterTokenTransfer(address(0), to, id); - } - - /// @dev Mints token `id` to `to`, and updates the extra data for token `id` to `value`. - /// Does NOT check if token `id` already exists (assumes `id` is auto-incrementing). - /// - /// Requirements: - /// - /// - `to` cannot be the zero address. - /// - /// Emits a {Transfer} event. - function _mintAndSetExtraDataUnchecked(address to, uint256 id, uint96 value) internal virtual { - _beforeTokenTransfer(address(0), to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - to := shr(96, shl(96, to)) - // Update with the owner and extra data. - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - sstore(add(id, add(id, keccak256(0x00, 0x20))), or(shl(160, value), to)) - // Increment the balance of the owner. - { - mstore(0x00, to) - let balanceSlot := keccak256(0x0c, 0x1c) - let balanceSlotPacked := add(sload(balanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(balanceSlot, balanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) - } - _afterTokenTransfer(address(0), to, id); - } - - /// @dev Equivalent to `_safeMint(to, id, "")`. - function _safeMint(address to, uint256 id) internal virtual { - _safeMint(to, id, ""); - } - - /// @dev Mints token `id` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must not exist. - /// - `to` cannot be the zero address. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function _safeMint(address to, uint256 id, bytes memory data) internal virtual { - _mint(to, id); - if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL BURN FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_burn(address(0), id)`. - function _burn(uint256 id) internal virtual { - _burn(address(0), id); - } - - /// @dev Destroys token `id`, using `by`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - If `by` is not the zero address, - /// it must be the owner of the token, or be approved to manage the token. - /// - /// Emits a {Transfer} event. - function _burn(address by, uint256 id) internal virtual { - address owner = ownerOf(id); - _beforeTokenTransfer(owner, address(0), id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - by := shr(96, shl(96, by)) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - // Reload the owner in case it is changed in `_beforeTokenTransfer`. - owner := shr(96, shl(96, ownershipPacked)) - // Revert if the token does not exist. - if iszero(owner) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - // Load and check the token approval. - { - mstore(0x00, owner) - let approvedAddress := sload(add(1, ownershipSlot)) - // If `by` is not the zero address, do the authorization check. - // Revert if the `by` is not the owner, nor approved. - if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) { - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Delete the approved address if any. - if approvedAddress { sstore(add(1, ownershipSlot), 0) } - } - // Clear the owner. - sstore(ownershipSlot, xor(ownershipPacked, owner)) - // Decrement the balance of `owner`. - { - let balanceSlot := keccak256(0x0c, 0x1c) - sstore(balanceSlot, sub(sload(balanceSlot), 1)) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id) - } - _afterTokenTransfer(owner, address(0), id); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL APPROVAL FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether `account` is the owner of token `id`, or is approved to manage it. - /// - /// Requirements: - /// - Token `id` must exist. - function _isApprovedOrOwner(address account, uint256 id) - internal - view - virtual - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - result := 1 - // Clear the upper 96 bits. - account := shr(96, shl(96, account)) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let owner := shr(96, shl(96, sload(ownershipSlot))) - // Revert if the token does not exist. - if iszero(owner) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - // Check if `account` is the `owner`. - if iszero(eq(account, owner)) { - mstore(0x00, owner) - // Check if `account` is approved to manage the token. - if iszero(sload(keccak256(0x0c, 0x30))) { - result := eq(account, sload(add(1, ownershipSlot))) - } - } - } - } - - /// @dev Returns the account approved to manage token `id`. - /// Returns the zero address instead of reverting if the token does not exist. - function _getApproved(uint256 id) internal view virtual returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20))))) - } - } - - /// @dev Equivalent to `_approve(address(0), account, id)`. - function _approve(address account, uint256 id) internal virtual { - _approve(address(0), account, id); - } - - /// @dev Sets `account` as the approved account to manage token `id`, using `by`. - /// - /// Requirements: - /// - Token `id` must exist. - /// - If `by` is not the zero address, `by` must be the owner - /// or an approved operator for the token owner. - /// - /// Emits a {Approval} event. - function _approve(address by, address account, uint256 id) internal virtual { - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - let bitmaskAddress := shr(96, not(0)) - account := and(bitmaskAddress, account) - by := and(bitmaskAddress, by) - // Load the owner of the token. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let owner := and(bitmaskAddress, sload(ownershipSlot)) - // Revert if the token does not exist. - if iszero(owner) { - mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. - revert(0x1c, 0x04) - } - // If `by` is not the zero address, do the authorization check. - // Revert if `by` is not the owner, nor approved. - if iszero(or(iszero(by), eq(by, owner))) { - mstore(0x00, owner) - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Sets `account` as the approved account to manage `id`. - sstore(add(1, ownershipSlot), account) - // Emit the {Approval} event. - log4(codesize(), 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id) - } - } - - /// @dev Approve or remove the `operator` as an operator for `by`, - /// without authorization checks. - /// - /// Emits an {ApprovalForAll} event. - function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - by := shr(96, shl(96, by)) - operator := shr(96, shl(96, operator)) - // Convert to 0 or 1. - isApproved := iszero(iszero(isApproved)) - // Update the `isApproved` for (`by`, `operator`). - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) - mstore(0x00, by) - sstore(keccak256(0x0c, 0x30), isApproved) - // Emit the {ApprovalForAll} event. - mstore(0x00, isApproved) - log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL TRANSFER FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `_transfer(address(0), from, to, id)`. - function _transfer(address from, address to, uint256 id) internal virtual { - _transfer(address(0), from, to, id); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - If `by` is not the zero address, - /// it must be the owner of the token, or be approved to manage the token. - /// - /// Emits a {Transfer} event. - function _transfer(address by, address from, address to, uint256 id) internal virtual { - _beforeTokenTransfer(from, to, id); - /// @solidity memory-safe-assembly - assembly { - // Clear the upper 96 bits. - let bitmaskAddress := shr(96, not(0)) - from := and(bitmaskAddress, from) - to := and(bitmaskAddress, to) - by := and(bitmaskAddress, by) - // Load the ownership data. - mstore(0x00, id) - mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) - let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) - let ownershipPacked := sload(ownershipSlot) - let owner := and(bitmaskAddress, ownershipPacked) - // Revert if the token does not exist, or if `from` is not the owner. - if iszero(mul(owner, eq(owner, from))) { - // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`. - mstore(shl(2, iszero(owner)), 0xceea21b6a1148100) - revert(0x1c, 0x04) - } - // Load, check, and update the token approval. - { - mstore(0x00, from) - let approvedAddress := sload(add(1, ownershipSlot)) - // If `by` is not the zero address, do the authorization check. - // Revert if the `by` is not the owner, nor approved. - if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) { - if iszero(sload(keccak256(0x0c, 0x30))) { - mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. - revert(0x1c, 0x04) - } - } - // Delete the approved address if any. - if approvedAddress { sstore(add(1, ownershipSlot), 0) } - } - // Update with the new owner. - sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) - // Decrement the balance of `from`. - { - let fromBalanceSlot := keccak256(0x0c, 0x1c) - sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) - } - // Increment the balance of `to`. - { - mstore(0x00, to) - let toBalanceSlot := keccak256(0x0c, 0x1c) - let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) - // Revert if `to` is the zero address, or if the account balance overflows. - if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) { - // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. - mstore(shl(2, iszero(to)), 0xea553b3401336cea) - revert(0x1c, 0x04) - } - sstore(toBalanceSlot, toBalanceSlotPacked) - } - // Emit the {Transfer} event. - log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) - } - _afterTokenTransfer(from, to, id); - } - - /// @dev Equivalent to `_safeTransfer(from, to, id, "")`. - function _safeTransfer(address from, address to, uint256 id) internal virtual { - _safeTransfer(from, to, id, ""); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - The caller must be the owner of the token, or be approved to manage the token. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function _safeTransfer(address from, address to, uint256 id, bytes memory data) - internal - virtual - { - _transfer(address(0), from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); - } - - /// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`. - function _safeTransfer(address by, address from, address to, uint256 id) internal virtual { - _safeTransfer(by, from, to, id, ""); - } - - /// @dev Transfers token `id` from `from` to `to`. - /// - /// Requirements: - /// - /// - Token `id` must exist. - /// - `from` must be the owner of the token. - /// - `to` cannot be the zero address. - /// - If `by` is not the zero address, - /// it must be the owner of the token, or be approved to manage the token. - /// - If `to` refers to a smart contract, it must implement - /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - /// - /// Emits a {Transfer} event. - function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data) - internal - virtual - { - _transfer(by, from, to, id); - if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HOOKS FOR OVERRIDING */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Hook that is called before any token transfers, including minting and burning. - function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {} - - /// @dev Hook that is called after any token transfers, including minting and burning. - function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {} - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if `a` has bytecode of non-zero length. - function _hasCode(address a) private view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := extcodesize(a) // Can handle dirty upper bits. - } - } - - /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`. - /// Reverts if the target does not support the function correctly. - function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data) - private - { - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - // Prepare the calldata. - let m := mload(0x40) - let onERC721ReceivedSelector := 0x150b7a02 - mstore(m, onERC721ReceivedSelector) - mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`. - mstore(add(m, 0x40), shr(96, shl(96, from))) - mstore(add(m, 0x60), id) - mstore(add(m, 0x80), 0x80) - let n := mload(data) - mstore(add(m, 0xa0), n) - copy(add(m, 0xc0), add(data, 0x20), n) - // Revert if the call reverts. - if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) { - if returndatasize() { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - // Load the returndata and compare it. - if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) { - mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`. - revert(0x1c, 0x04) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/Base58.sol b/grouperBot/lib/solady/src/utils/Base58.sol deleted file mode 100644 index 760d37e..0000000 --- a/grouperBot/lib/solady/src/utils/Base58.sol +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library to encode strings in Base58. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base58.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Base58.sol) -library Base58 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev An unrecognized character or overflow was encountered during decoding. - error Base58DecodingError(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ENCODING / DECODING */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Encodes `data` into a Base58 string. - function encode(bytes memory data) internal pure returns (string memory result) { - uint256 l = data.length; - if (l == uint256(0)) return result; - /// @solidity memory-safe-assembly - assembly { - let b := add(data, 0x20) // Start of `data` bytes. - let z := 0 // Number of leading zero bytes in `data`. - // Count leading zero bytes. - for {} lt(byte(0, mload(add(b, z))), lt(z, l)) {} { z := add(1, z) } - - // Start the output offset by an over-estimate of the length. - let o := add(add(mload(0x40), 0x21), add(z, div(mul(sub(l, z), 8351), 6115))) - let e := o - - let limbs := o - let limbsEnd := limbs - // Populate the uint248 limbs. - for { - let i := mod(l, 31) - if i { - mstore(limbsEnd, shr(shl(3, add(1, sub(31, i))), mload(b))) - limbsEnd := add(limbsEnd, 0x20) - } - } lt(i, l) { i := add(i, 31) } { - mstore(limbsEnd, shr(8, mload(add(b, i)))) - limbsEnd := add(limbsEnd, 0x20) - } - // Use the extended scratch space for the lookup. We'll restore 0x40 later. - mstore(0x1f, "123456789ABCDEFGHJKLMNPQRSTUVWXY") - mstore(0x3f, "Zabcdefghijkmnopqrstuvwxyz") - - let w := not(0) // -1. - mstore(limbsEnd, w) // Put sentinel after limbs for faster looping. - for {} 1 {} { - let i := limbs - for {} iszero(mload(i)) { i := add(i, 0x20) } {} - if iszero(not(mload(i))) { break } // Break if all limbs are zero. - - let carry := 0 - for { i := limbs } 1 {} { - let acc := add(shl(248, carry), mload(i)) - mstore(i, div(acc, 58)) - carry := mod(acc, 58) - i := add(i, 0x20) - if eq(i, limbsEnd) { break } - } - o := add(o, w) - mstore8(o, mload(carry)) - } - let j := o - for { o := sub(o, z) } gt(j, o) {} { - j := sub(j, 0x20) - mstore(j, mul(div(w, 0xff), 49)) // '1111...1111' in ASCII. - } - - let n := sub(e, o) // Compute the final length. - result := sub(o, 0x20) // Move back one word for the length. - mstore(result, n) // Store the length. - mstore(add(add(result, 0x20), n), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(result, 0x40), n)) // Allocate memory. - } - } - - /// @dev Encodes the `data` word into a Base58 string. - function encodeWord(bytes32 data) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - let o := add(mload(0x40), 0x4c) // 32 for word, 44 for maximum possible length. - let e := o - - // Use the extended scratch space for the lookup. We'll restore 0x40 later. - mstore(0x1f, "123456789ABCDEFGHJKLMNPQRSTUVWXY") - mstore(0x3f, "Zabcdefghijkmnopqrstuvwxyz") - - let w := not(0) // -1. - let z := shl(5, iszero(data)) // Number of leading zeroes in `data`. - if iszero(z) { - for { let v := data } v { v := div(v, 58) } { - o := add(o, w) - mstore8(o, mload(mod(v, 58))) - } - for {} iszero(byte(z, data)) { z := add(z, 1) } {} // Just loop, `z` is often tiny. - } - if z { mstore(sub(o, 0x20), mul(div(w, 0xff), 49)) } // '1111...1111' in ASCII. - o := sub(o, z) - - let n := sub(e, o) // Compute the final length. - result := sub(o, 0x20) // Move back one word for the length. - mstore(result, n) // Store the length. - mstore(add(add(result, 0x20), n), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(result, 0x40), n)) // Allocate memory. - } - } - - /// @dev Decodes `encoded`, a Base58 string, into the original bytes. - function decode(string memory encoded) internal pure returns (bytes memory result) { - uint256 n = bytes(encoded).length; - if (n == uint256(0)) return result; - /// @solidity memory-safe-assembly - assembly { - let s := add(encoded, 0x20) - let z := 0 // Number of leading '1' in `data`. - // Count leading '1'. - for {} and(eq(49, byte(0, mload(add(s, z)))), lt(z, n)) {} { z := add(1, z) } - - // Start the output offset by an over-estimate of the length. - let o := add(add(mload(0x40), 0x21), add(z, div(mul(sub(n, z), 7323), 10000))) - let e := o - let limbs := o - let limbsEnd := limbs - let limbMask := shr(8, not(0)) - // Use the extended scratch space for the lookup. We'll restore 0x40 later. - mstore(0x2a, 0x30313233343536373839) - mstore(0x20, 0x1718191a1b1c1d1e1f20ffffffffffff2122232425262728292a2bff2c2d2e2f) - mstore(0x00, 0x000102030405060708ffffffffffffff090a0b0c0d0e0f10ff1112131415ff16) - - for { let j := 0 } 1 {} { - let c := sub(byte(0, mload(add(s, j))), 49) - // Check if the input character is valid. - if iszero(and(shl(c, 1), 0x3fff7ff03ffbeff01ff)) { - mstore(0x00, 0xe8fad793) // `Base58DecodingError()`. - revert(0x1c, 0x04) - } - let carry := byte(0, mload(c)) - for { let i := limbs } iszero(eq(i, limbsEnd)) { i := add(i, 0x20) } { - let acc := add(carry, mul(58, mload(i))) - mstore(i, and(limbMask, acc)) - carry := shr(248, acc) - } - // Carry will always be < 58. - if carry { - mstore(limbsEnd, carry) - limbsEnd := add(limbsEnd, 0x20) - } - j := add(j, 1) - if eq(j, n) { break } - } - // Copy and compact the uint248 limbs. - for { let i := limbs } iszero(eq(i, limbsEnd)) { i := add(i, 0x20) } { - o := sub(o, 31) - mstore(sub(o, 1), mload(i)) - } - // Strip any leading zeros from the limbs. - for {} lt(byte(0, mload(o)), lt(o, e)) {} { o := add(o, 1) } - o := sub(o, z) // Move back for the leading zero bytes. - calldatacopy(o, calldatasize(), z) // Fill the leading zero bytes. - - let l := sub(e, o) // Compute the final length. - result := sub(o, 0x20) // Move back one word for the length. - mstore(result, l) // Store the length. - mstore(add(add(result, 0x20), l), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(result, 0x40), l)) // Allocate memory. - } - } - - /// @dev Decodes `encoded`, a Base58 string, into the original word. - function decodeWord(string memory encoded) internal pure returns (bytes32 result) { - uint256 n = bytes(encoded).length; - if (n == uint256(0)) return result; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - let s := add(encoded, 0x20) - let t := add(1, div(not(0), 58)) // Overflow threshold for multiplication. - // Use the extended scratch space for the lookup. We'll restore 0x40 later. - mstore(0x2a, 0x30313233343536373839) - mstore(0x20, 0x1718191a1b1c1d1e1f20ffffffffffff2122232425262728292a2bff2c2d2e2f) - mstore(0x00, 0x000102030405060708ffffffffffffff090a0b0c0d0e0f10ff1112131415ff16) - - for { let j := 0 } 1 {} { - let c := sub(byte(0, mload(add(s, j))), 49) - let p := mul(result, 58) - let acc := add(byte(0, mload(c)), p) - // Check if the input character is valid. - if iszero(and(0x3fff7ff03ffbeff01ff, shl(c, lt(lt(acc, p), lt(result, t))))) { - mstore(0x00, 0xe8fad793) // `Base58DecodingError()`. - revert(0x1c, 0x04) - } - result := acc - j := add(j, 1) - if eq(j, n) { break } - } - mstore(0x40, m) // Restore the free memory pointer. - } - } -} diff --git a/grouperBot/lib/solady/src/utils/Base64.sol b/grouperBot/lib/solady/src/utils/Base64.sol deleted file mode 100644 index 357add0..0000000 --- a/grouperBot/lib/solady/src/utils/Base64.sol +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library to encode strings in Base64. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol) -/// @author Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos - . -library Base64 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ENCODING / DECODING */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Encodes `data` using the base64 encoding described in RFC 4648. - /// See: https://datatracker.ietf.org/doc/html/rfc4648 - /// @param fileSafe Whether to replace '+' with '-' and '/' with '_'. - /// @param noPadding Whether to strip away the padding. - function encode(bytes memory data, bool fileSafe, bool noPadding) - internal - pure - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - let dataLength := mload(data) - - if dataLength { - // Multiply by 4/3 rounded up. - // The `shl(2, ...)` is equivalent to multiplying by 4. - let encodedLength := shl(2, div(add(dataLength, 2), 3)) - - // Set `result` to point to the start of the free memory. - result := mload(0x40) - - // Store the table into the scratch space. - // Offsetted by -1 byte so that the `mload` will load the character. - // We will rewrite the free memory pointer at `0x40` later with - // the allocated size. - // The magic constant 0x0670 will turn "-_" into "+/". - mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef") - mstore(0x3f, xor("ghijklmnopqrstuvwxyz0123456789-_", mul(iszero(fileSafe), 0x0670))) - - // Skip the first slot, which stores the length. - let ptr := add(result, 0x20) - let end := add(ptr, encodedLength) - - let dataEnd := add(add(0x20, data), dataLength) - let dataEndValue := mload(dataEnd) // Cache the value at the `dataEnd` slot. - mstore(dataEnd, 0x00) // Zeroize the `dataEnd` slot to clear dirty bits. - - // Run over the input, 3 bytes at a time. - for {} 1 {} { - data := add(data, 3) // Advance 3 bytes. - let input := mload(data) - - // Write 4 bytes. Optimized for fewer stack operations. - mstore8(0, mload(and(shr(18, input), 0x3F))) - mstore8(1, mload(and(shr(12, input), 0x3F))) - mstore8(2, mload(and(shr(6, input), 0x3F))) - mstore8(3, mload(and(input, 0x3F))) - mstore(ptr, mload(0x00)) - - ptr := add(ptr, 4) // Advance 4 bytes. - if iszero(lt(ptr, end)) { break } - } - mstore(dataEnd, dataEndValue) // Restore the cached value at `dataEnd`. - mstore(0x40, add(end, 0x20)) // Allocate the memory. - // Equivalent to `o = [0, 2, 1][dataLength % 3]`. - let o := div(2, mod(dataLength, 3)) - // Offset `ptr` and pad with '='. We can simply write over the end. - mstore(sub(ptr, o), shl(240, 0x3d3d)) - // Set `o` to zero if there is padding. - o := mul(iszero(iszero(noPadding)), o) - mstore(sub(ptr, o), 0) // Zeroize the slot after the string. - mstore(result, sub(encodedLength, o)) // Store the length. - } - } - } - - /// @dev Encodes `data` using the base64 encoding described in RFC 4648. - /// Equivalent to `encode(data, false, false)`. - function encode(bytes memory data) internal pure returns (string memory result) { - result = encode(data, false, false); - } - - /// @dev Encodes `data` using the base64 encoding described in RFC 4648. - /// Equivalent to `encode(data, fileSafe, false)`. - function encode(bytes memory data, bool fileSafe) - internal - pure - returns (string memory result) - { - result = encode(data, fileSafe, false); - } - - /// @dev Decodes base64 encoded `data`. - /// - /// Supports: - /// - RFC 4648 (both standard and file-safe mode). - /// - RFC 3501 (63: ','). - /// - /// Does not support: - /// - Line breaks. - /// - /// Note: For performance reasons, - /// this function will NOT revert on invalid `data` inputs. - /// Outputs for invalid inputs will simply be undefined behaviour. - /// It is the user's responsibility to ensure that the `data` - /// is a valid base64 encoded string. - function decode(string memory data) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - let dataLength := mload(data) - - if dataLength { - let decodedLength := mul(shr(2, dataLength), 3) - - for {} 1 {} { - // If padded. - if iszero(and(dataLength, 3)) { - let t := xor(mload(add(data, dataLength)), 0x3d3d) - // forgefmt: disable-next-item - decodedLength := sub( - decodedLength, - add(iszero(byte(30, t)), iszero(byte(31, t))) - ) - break - } - // If non-padded. - decodedLength := add(decodedLength, sub(and(dataLength, 3), 1)) - break - } - result := mload(0x40) - - // Write the length of the bytes. - mstore(result, decodedLength) - - // Skip the first slot, which stores the length. - let ptr := add(result, 0x20) - let end := add(ptr, decodedLength) - - // Load the table into the scratch space. - // Constants are optimized for smaller bytecode with zero gas overhead. - // `m` also doubles as the mask of the upper 6 bits. - let m := 0xfc000000fc00686c7074787c8084888c9094989ca0a4a8acb0b4b8bcc0c4c8cc - mstore(0x5b, m) - mstore(0x3b, 0x04080c1014181c2024282c3034383c4044484c5054585c6064) - mstore(0x1a, 0xf8fcf800fcd0d4d8dce0e4e8ecf0f4) - - for {} 1 {} { - // Read 4 bytes. - data := add(data, 4) - let input := mload(data) - - // Write 3 bytes. - // forgefmt: disable-next-item - mstore(ptr, or( - and(m, mload(byte(28, input))), - shr(6, or( - and(m, mload(byte(29, input))), - shr(6, or( - and(m, mload(byte(30, input))), - shr(6, mload(byte(31, input))) - )) - )) - )) - ptr := add(ptr, 3) - if iszero(lt(ptr, end)) { break } - } - mstore(0x40, add(end, 0x20)) // Allocate the memory. - mstore(end, 0) // Zeroize the slot after the bytes. - mstore(0x60, 0) // Restore the zero slot. - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/BlockHashLib.sol b/grouperBot/lib/solady/src/utils/BlockHashLib.sol deleted file mode 100644 index c26fbab..0000000 --- a/grouperBot/lib/solady/src/utils/BlockHashLib.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for accessing block hashes way beyond the 256-block limit. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/BlockHashLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Blockhash.sol) -library BlockHashLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Address of the EIP-2935 history storage contract. - /// See: https://eips.ethereum.org/EIPS/eip-2935 - address internal constant HISTORY_STORAGE_ADDRESS = 0x0000F90827F1C53a10cb7A02335B175320002935; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Retrieves the block hash for any historical block within the supported range. - /// The function gracefully handles future blocks and blocks beyond the history window by returning zero, - /// consistent with the EVM's native `BLOCKHASH` behavior. - function blockHash(uint256 blockNumber) internal view returns (bytes32 result) { - unchecked { - // If `blockNumber + 256` overflows: - // - Typical chain height (`block.number > 255`) -> `staticcall` -> 0. - // - Very early chain (`block.number <= 255`) -> `blockhash` -> 0. - if (block.number <= blockNumber + 256) return blockhash(blockNumber); - } - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, blockNumber) - mstore(0x00, 0) - pop(staticcall(gas(), HISTORY_STORAGE_ADDRESS, 0x20, 0x20, 0x00, 0x20)) - result := mload(0x00) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/CREATE3.sol b/grouperBot/lib/solady/src/utils/CREATE3.sol deleted file mode 100644 index 57b5b0b..0000000 --- a/grouperBot/lib/solady/src/utils/CREATE3.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Deterministic deployments agnostic to the initialization code. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/CREATE3.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) -/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol) -library CREATE3 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unable to deploy the contract. - error DeploymentFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTECODE CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /** - * -------------------------------------------------------------------+ - * Opcode | Mnemonic | Stack | Memory | - * -------------------------------------------------------------------| - * 36 | CALLDATASIZE | cds | | - * 3d | RETURNDATASIZE | 0 cds | | - * 3d | RETURNDATASIZE | 0 0 cds | | - * 37 | CALLDATACOPY | | [0..cds): calldata | - * 36 | CALLDATASIZE | cds | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 cds | [0..cds): calldata | - * 34 | CALLVALUE | value 0 cds | [0..cds): calldata | - * f0 | CREATE | newContract | [0..cds): calldata | - * -------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * -------------------------------------------------------------------| - * 67 bytecode | PUSH8 bytecode | bytecode | | - * 3d | RETURNDATASIZE | 0 bytecode | | - * 52 | MSTORE | | [0..8): bytecode | - * 60 0x08 | PUSH1 0x08 | 0x08 | [0..8): bytecode | - * 60 0x18 | PUSH1 0x18 | 0x18 0x08 | [0..8): bytecode | - * f3 | RETURN | | [0..8): bytecode | - * -------------------------------------------------------------------+ - */ - - /// @dev The proxy initialization code. - uint256 private constant _PROXY_INITCODE = 0x67363d3d37363d34f03d5260086018f3; - - /// @dev Hash of the `_PROXY_INITCODE`. - /// Equivalent to `keccak256(abi.encodePacked(hex"67363d3d37363d34f03d5260086018f3"))`. - bytes32 internal constant PROXY_INITCODE_HASH = - 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CREATE3 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys `initCode` deterministically with a `salt`. - /// Returns the deterministic address of the deployed contract, - /// which solely depends on `salt`. - function deployDeterministic(bytes memory initCode, bytes32 salt) - internal - returns (address deployed) - { - deployed = deployDeterministic(0, initCode, salt); - } - - /// @dev Deploys `initCode` deterministically with a `salt`. - /// The deployed contract is funded with `value` (in wei) ETH. - /// Returns the deterministic address of the deployed contract, - /// which solely depends on `salt`. - function deployDeterministic(uint256 value, bytes memory initCode, bytes32 salt) - internal - returns (address deployed) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, _PROXY_INITCODE) // Store the `_PROXY_INITCODE`. - let proxy := create2(0, 0x10, 0x10, salt) - if iszero(proxy) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x14, proxy) // Store the proxy's address. - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01). - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex). - mstore(0x00, 0xd694) - mstore8(0x34, 0x01) // Nonce of the proxy contract (1). - deployed := keccak256(0x1e, 0x17) - if iszero( - mul( // The arguments of `mul` are evaluated last to first. - extcodesize(deployed), - call(gas(), proxy, value, add(initCode, 0x20), mload(initCode), 0x00, 0x00) - ) - ) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns the deterministic address for `salt`. - function predictDeterministicAddress(bytes32 salt) internal view returns (address deployed) { - deployed = predictDeterministicAddress(salt, address(this)); - } - - /// @dev Returns the deterministic address for `salt` with `deployer`. - function predictDeterministicAddress(bytes32 salt, address deployer) - internal - pure - returns (address deployed) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, deployer) // Store `deployer`. - mstore8(0x0b, 0xff) // Store the prefix. - mstore(0x20, salt) // Store the salt. - mstore(0x40, PROXY_INITCODE_HASH) // Store the bytecode hash. - - mstore(0x14, keccak256(0x0b, 0x55)) // Store the proxy's address. - mstore(0x40, m) // Restore the free memory pointer. - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01). - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex). - mstore(0x00, 0xd694) - mstore8(0x34, 0x01) // Nonce of the proxy contract (1). - deployed := keccak256(0x1e, 0x17) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/CallContextChecker.sol b/grouperBot/lib/solady/src/utils/CallContextChecker.sol deleted file mode 100644 index 5655166..0000000 --- a/grouperBot/lib/solady/src/utils/CallContextChecker.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Call context checker mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/CallContextChecker.sol) -contract CallContextChecker { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The call is from an unauthorized call context. - error UnauthorizedCallContext(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For checking if the context is a delegate call. - /// - /// Note: To enable use cases with an immutable default implementation in the bytecode, - /// (see: ERC6551Proxy), we don't require that the proxy address must match the - /// value stored in the implementation slot, which may not be initialized. - uint256 private immutable __self = uint256(uint160(address(this))); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CALL CONTEXT CHECKS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // A proxy call can be either via a `delegatecall` to an implementation, - // or a 7702 call on an authority that points to a delegation. - - /// @dev Returns whether the current call context is on a EIP7702 authority - /// (i.e. externally owned account). - function _onEIP7702Authority() internal view virtual returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - extcodecopy(address(), 0x00, 0x00, 0x20) - // Note: Checking that it starts with hex"ef01" is the most general and futureproof. - // 7702 bytecode is `abi.encodePacked(hex"ef01", uint8(version), address(delegation))`. - result := eq(0xef01, shr(240, mload(0x00))) - } - } - - /// @dev Returns the implementation of this contract. - function _selfImplementation() internal view virtual returns (address) { - return address(uint160(__self)); - } - - /// @dev Returns whether the current call context is on the implementation itself. - function _onImplementation() internal view virtual returns (bool) { - return __self == uint160(address(this)); - } - - /// @dev Requires that the current call context is performed via a EIP7702 authority. - function _checkOnlyEIP7702Authority() internal view virtual { - if (!_onEIP7702Authority()) _revertUnauthorizedCallContext(); - } - - /// @dev Requires that the current call context is performed via a proxy. - function _checkOnlyProxy() internal view virtual { - if (_onImplementation()) _revertUnauthorizedCallContext(); - } - - /// @dev Requires that the current call context is NOT performed via a proxy. - /// This is the opposite of `checkOnlyProxy`. - function _checkNotDelegated() internal view virtual { - if (!_onImplementation()) _revertUnauthorizedCallContext(); - } - - /// @dev Requires that the current call context is performed via a EIP7702 authority. - modifier onlyEIP7702Authority() virtual { - _checkOnlyEIP7702Authority(); - _; - } - - /// @dev Requires that the current call context is performed via a proxy. - modifier onlyProxy() virtual { - _checkOnlyProxy(); - _; - } - - /// @dev Requires that the current call context is NOT performed via a proxy. - /// This is the opposite of `onlyProxy`. - modifier notDelegated() virtual { - _checkNotDelegated(); - _; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - function _revertUnauthorizedCallContext() private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x9f03a026) // `UnauthorizedCallContext()`. - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/DateTimeLib.sol b/grouperBot/lib/solady/src/utils/DateTimeLib.sol deleted file mode 100644 index 00e8f58..0000000 --- a/grouperBot/lib/solady/src/utils/DateTimeLib.sol +++ /dev/null @@ -1,512 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for date time operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/DateTimeLib.sol) -/// @author Modified from BokkyPooBahsDateTimeLibrary (https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary) -/// @dev -/// Conventions: -/// --------------------------------------------------------------------+ -/// Unit | Range | Notes | -/// --------------------------------------------------------------------| -/// timestamp | 0..0x1e18549868c76ff | Unix timestamp. | -/// epochDay | 0..0x16d3e098039 | Days since 1970-01-01. | -/// year | 1970..0xffffffff | Gregorian calendar year. | -/// month | 1..12 | Gregorian calendar month. | -/// day | 1..31 | Gregorian calendar day of month. | -/// weekday | 1..7 | The day of the week (1-indexed). | -/// --------------------------------------------------------------------+ -/// All timestamps of days are rounded down to 00:00:00 UTC. -library DateTimeLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Weekdays are 1-indexed, adhering to ISO 8601. - - uint256 internal constant MON = 1; - uint256 internal constant TUE = 2; - uint256 internal constant WED = 3; - uint256 internal constant THU = 4; - uint256 internal constant FRI = 5; - uint256 internal constant SAT = 6; - uint256 internal constant SUN = 7; - - // Months and days of months are 1-indexed, adhering to ISO 8601. - - uint256 internal constant JAN = 1; - uint256 internal constant FEB = 2; - uint256 internal constant MAR = 3; - uint256 internal constant APR = 4; - uint256 internal constant MAY = 5; - uint256 internal constant JUN = 6; - uint256 internal constant JUL = 7; - uint256 internal constant AUG = 8; - uint256 internal constant SEP = 9; - uint256 internal constant OCT = 10; - uint256 internal constant NOV = 11; - uint256 internal constant DEC = 12; - - // These limits are large enough for most practical purposes. - // Inputs that exceed these limits result in undefined behavior. - - uint256 internal constant MAX_SUPPORTED_YEAR = 0xffffffff; - uint256 internal constant MAX_SUPPORTED_EPOCH_DAY = 0x16d3e098039; - uint256 internal constant MAX_SUPPORTED_TIMESTAMP = 0x1e18549868c76ff; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DATE TIME OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of days since 1970-01-01 from (`year`,`month`,`day`). - /// See: https://howardhinnant.github.io/date_algorithms.html - /// Note: Inputs outside the supported ranges result in undefined behavior. - /// Use {isSupportedDate} to check if the inputs are supported. - function dateToEpochDay(uint256 year, uint256 month, uint256 day) - internal - pure - returns (uint256 epochDay) - { - /// @solidity memory-safe-assembly - assembly { - year := sub(year, lt(month, 3)) - let doy := add(shr(11, add(mul(62719, mod(add(month, 9), 12)), 769)), day) - let yoe := mod(year, 400) - let doe := sub(add(add(mul(yoe, 365), shr(2, yoe)), doy), div(yoe, 100)) - epochDay := sub(add(mul(div(year, 400), 146097), doe), 719469) - } - } - - /// @dev Returns (`year`,`month`,`day`) from the number of days since 1970-01-01. - /// Note: Inputs outside the supported ranges result in undefined behavior. - /// Use {isSupportedDays} to check if the inputs is supported. - function epochDayToDate(uint256 epochDay) - internal - pure - returns (uint256 year, uint256 month, uint256 day) - { - /// @solidity memory-safe-assembly - assembly { - epochDay := add(epochDay, 719468) - let doe := mod(epochDay, 146097) - let yoe := - div(sub(sub(add(doe, div(doe, 36524)), div(doe, 1460)), eq(doe, 146096)), 365) - let doy := sub(doe, sub(add(mul(365, yoe), shr(2, yoe)), div(yoe, 100))) - let mp := div(add(mul(5, doy), 2), 153) - day := add(sub(doy, shr(11, add(mul(mp, 62719), 769))), 1) - month := byte(mp, shl(160, 0x030405060708090a0b0c0102)) - year := add(add(yoe, mul(div(epochDay, 146097), 400)), lt(month, 3)) - } - } - - /// @dev Returns the unix timestamp from (`year`,`month`,`day`). - /// Note: Inputs outside the supported ranges result in undefined behavior. - /// Use {isSupportedDate} to check if the inputs are supported. - function dateToTimestamp(uint256 year, uint256 month, uint256 day) - internal - pure - returns (uint256 result) - { - unchecked { - result = dateToEpochDay(year, month, day) * 86400; - } - } - - /// @dev Returns (`year`,`month`,`day`) from the given unix timestamp. - /// Note: Inputs outside the supported ranges result in undefined behavior. - /// Use {isSupportedTimestamp} to check if the inputs are supported. - function timestampToDate(uint256 timestamp) - internal - pure - returns (uint256 year, uint256 month, uint256 day) - { - (year, month, day) = epochDayToDate(timestamp / 86400); - } - - /// @dev Returns the unix timestamp from - /// (`year`,`month`,`day`,`hour`,`minute`,`second`). - /// Note: Inputs outside the supported ranges result in undefined behavior. - /// Use {isSupportedDateTime} to check if the inputs are supported. - function dateTimeToTimestamp( - uint256 year, - uint256 month, - uint256 day, - uint256 hour, - uint256 minute, - uint256 second - ) internal pure returns (uint256 result) { - unchecked { - result = dateToEpochDay(year, month, day) * 86400 + hour * 3600 + minute * 60 + second; - } - } - - /// @dev Returns (`year`,`month`,`day`,`hour`,`minute`,`second`) - /// from the given unix timestamp. - /// Note: Inputs outside the supported ranges result in undefined behavior. - /// Use {isSupportedTimestamp} to check if the inputs are supported. - function timestampToDateTime(uint256 timestamp) - internal - pure - returns ( - uint256 year, - uint256 month, - uint256 day, - uint256 hour, - uint256 minute, - uint256 second - ) - { - unchecked { - (year, month, day) = epochDayToDate(timestamp / 86400); - uint256 secs = timestamp % 86400; - hour = secs / 3600; - secs = secs % 3600; - minute = secs / 60; - second = secs % 60; - } - } - - /// @dev Returns if the `year` is leap. - function isLeapYear(uint256 year) internal pure returns (bool leap) { - /// @solidity memory-safe-assembly - assembly { - leap := iszero(and(add(mul(iszero(mod(year, 25)), 12), 3), year)) - } - } - - /// @dev Returns number of days in given `month` of `year`. - function daysInMonth(uint256 year, uint256 month) internal pure returns (uint256 result) { - bool flag = isLeapYear(year); - /// @solidity memory-safe-assembly - assembly { - // `daysInMonths = [31,28,31,30,31,30,31,31,30,31,30,31]`. - // `result = daysInMonths[month - 1] + isLeapYear(year)`. - result := - add(byte(month, shl(152, 0x1f1c1f1e1f1e1f1f1e1f1e1f)), and(eq(month, 2), flag)) - } - } - - /// @dev Returns the weekday from the unix timestamp. - /// Monday: 1, Tuesday: 2, ....., Sunday: 7. - function weekday(uint256 timestamp) internal pure returns (uint256 result) { - unchecked { - result = ((timestamp / 86400 + 3) % 7) + 1; - } - } - - /// @dev Returns if (`year`,`month`,`day`) is a supported date. - /// - `1970 <= year <= MAX_SUPPORTED_YEAR`. - /// - `1 <= month <= 12`. - /// - `1 <= day <= daysInMonth(year, month)`. - function isSupportedDate(uint256 year, uint256 month, uint256 day) - internal - pure - returns (bool result) - { - uint256 md = daysInMonth(year, month); - /// @solidity memory-safe-assembly - assembly { - result := - and( - lt(sub(year, 1970), sub(MAX_SUPPORTED_YEAR, 1969)), - and(lt(sub(month, 1), 12), lt(sub(day, 1), md)) - ) - } - } - - /// @dev Returns if (`year`,`month`,`day`,`hour`,`minute`,`second`) is a supported date time. - /// - `1970 <= year <= MAX_SUPPORTED_YEAR`. - /// - `1 <= month <= 12`. - /// - `1 <= day <= daysInMonth(year, month)`. - /// - `hour < 24`. - /// - `minute < 60`. - /// - `second < 60`. - function isSupportedDateTime( - uint256 year, - uint256 month, - uint256 day, - uint256 hour, - uint256 minute, - uint256 second - ) internal pure returns (bool result) { - if (isSupportedDate(year, month, day)) { - /// @solidity memory-safe-assembly - assembly { - result := and(lt(hour, 24), and(lt(minute, 60), lt(second, 60))) - } - } - } - - /// @dev Returns if `epochDay` is a supported unix epoch day. - function isSupportedEpochDay(uint256 epochDay) internal pure returns (bool result) { - unchecked { - result = epochDay < MAX_SUPPORTED_EPOCH_DAY + 1; - } - } - - /// @dev Returns if `timestamp` is a supported unix timestamp. - function isSupportedTimestamp(uint256 timestamp) internal pure returns (bool result) { - unchecked { - result = timestamp < MAX_SUPPORTED_TIMESTAMP + 1; - } - } - - /// @dev Returns the unix timestamp of the given `n`th weekday `wd`, in `month` of `year`. - /// Example: 3rd Friday of Feb 2022 is `nthWeekdayInMonthOfYearTimestamp(2022, 2, 3, 5)` - /// Note: `n` is 1-indexed for traditional consistency. - /// Invalid weekdays (i.e. `wd == 0 || wd > 7`) result in undefined behavior. - function nthWeekdayInMonthOfYearTimestamp(uint256 year, uint256 month, uint256 n, uint256 wd) - internal - pure - returns (uint256 result) - { - uint256 d = dateToEpochDay(year, month, 1); - uint256 md = daysInMonth(year, month); - /// @solidity memory-safe-assembly - assembly { - let diff := sub(wd, add(mod(add(d, 3), 7), 1)) - let date := add(mul(sub(n, 1), 7), add(mul(gt(diff, 6), 7), diff)) - result := mul(mul(86400, add(date, d)), and(lt(date, md), iszero(iszero(n)))) - } - } - - /// @dev Returns the unix timestamp of the most recent Monday. - function mondayTimestamp(uint256 timestamp) internal pure returns (uint256 result) { - uint256 t = timestamp; - /// @solidity memory-safe-assembly - assembly { - let day := div(t, 86400) - result := mul(mul(sub(day, mod(add(day, 3), 7)), 86400), gt(t, 345599)) - } - } - - /// @dev Returns whether the unix timestamp falls on a Saturday or Sunday. - /// To check whether it is a week day, just take the negation of the result. - function isWeekEnd(uint256 timestamp) internal pure returns (bool result) { - result = weekday(timestamp) > FRI; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DATE TIME ARITHMETIC OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Adds `numYears` to the unix timestamp, and returns the result. - /// Note: The result will share the same Gregorian calendar month, - /// but different Gregorian calendar years for non-zero `numYears`. - /// If the Gregorian calendar month of the result has less days - /// than the Gregorian calendar month day of the `timestamp`, - /// the result's month day will be the maximum possible value for the month. - /// (e.g. from 29th Feb to 28th Feb) - function addYears(uint256 timestamp, uint256 numYears) internal pure returns (uint256 result) { - (uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400); - result = _offsetted(year + numYears, month, day, timestamp); - } - - /// @dev Adds `numMonths` to the unix timestamp, and returns the result. - /// Note: If the Gregorian calendar month of the result has less days - /// than the Gregorian calendar month day of the `timestamp`, - /// the result's month day will be the maximum possible value for the month. - /// (e.g. from 29th Feb to 28th Feb) - function addMonths(uint256 timestamp, uint256 numMonths) - internal - pure - returns (uint256 result) - { - (uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400); - month = _sub(month + numMonths, 1); - result = _offsetted(year + month / 12, _add(month % 12, 1), day, timestamp); - } - - /// @dev Adds `numDays` to the unix timestamp, and returns the result. - function addDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result) { - result = timestamp + numDays * 86400; - } - - /// @dev Adds `numHours` to the unix timestamp, and returns the result. - function addHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result) { - result = timestamp + numHours * 3600; - } - - /// @dev Adds `numMinutes` to the unix timestamp, and returns the result. - function addMinutes(uint256 timestamp, uint256 numMinutes) - internal - pure - returns (uint256 result) - { - result = timestamp + numMinutes * 60; - } - - /// @dev Adds `numSeconds` to the unix timestamp, and returns the result. - function addSeconds(uint256 timestamp, uint256 numSeconds) - internal - pure - returns (uint256 result) - { - result = timestamp + numSeconds; - } - - /// @dev Subtracts `numYears` from the unix timestamp, and returns the result. - /// Note: The result will share the same Gregorian calendar month, - /// but different Gregorian calendar years for non-zero `numYears`. - /// If the Gregorian calendar month of the result has less days - /// than the Gregorian calendar month day of the `timestamp`, - /// the result's month day will be the maximum possible value for the month. - /// (e.g. from 29th Feb to 28th Feb) - function subYears(uint256 timestamp, uint256 numYears) internal pure returns (uint256 result) { - (uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400); - result = _offsetted(year - numYears, month, day, timestamp); - } - - /// @dev Subtracts `numYears` from the unix timestamp, and returns the result. - /// Note: If the Gregorian calendar month of the result has less days - /// than the Gregorian calendar month day of the `timestamp`, - /// the result's month day will be the maximum possible value for the month. - /// (e.g. from 29th Feb to 28th Feb) - function subMonths(uint256 timestamp, uint256 numMonths) - internal - pure - returns (uint256 result) - { - (uint256 year, uint256 month, uint256 day) = epochDayToDate(timestamp / 86400); - uint256 yearMonth = _totalMonths(year, month) - _add(numMonths, 1); - result = _offsetted(yearMonth / 12, _add(yearMonth % 12, 1), day, timestamp); - } - - /// @dev Subtracts `numDays` from the unix timestamp, and returns the result. - function subDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result) { - result = timestamp - numDays * 86400; - } - - /// @dev Subtracts `numHours` from the unix timestamp, and returns the result. - function subHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result) { - result = timestamp - numHours * 3600; - } - - /// @dev Subtracts `numMinutes` from the unix timestamp, and returns the result. - function subMinutes(uint256 timestamp, uint256 numMinutes) - internal - pure - returns (uint256 result) - { - result = timestamp - numMinutes * 60; - } - - /// @dev Subtracts `numSeconds` from the unix timestamp, and returns the result. - function subSeconds(uint256 timestamp, uint256 numSeconds) - internal - pure - returns (uint256 result) - { - result = timestamp - numSeconds; - } - - /// @dev Returns the difference in Gregorian calendar years - /// between `fromTimestamp` and `toTimestamp`. - /// Note: Even if the true time difference is less than a year, - /// the difference can be non-zero is the timestamps are - /// from different Gregorian calendar years - function diffYears(uint256 fromTimestamp, uint256 toTimestamp) - internal - pure - returns (uint256 result) - { - toTimestamp - fromTimestamp; - (uint256 fromYear,,) = epochDayToDate(fromTimestamp / 86400); - (uint256 toYear,,) = epochDayToDate(toTimestamp / 86400); - result = _sub(toYear, fromYear); - } - - /// @dev Returns the difference in Gregorian calendar months - /// between `fromTimestamp` and `toTimestamp`. - /// Note: Even if the true time difference is less than a month, - /// the difference can be non-zero is the timestamps are - /// from different Gregorian calendar months. - function diffMonths(uint256 fromTimestamp, uint256 toTimestamp) - internal - pure - returns (uint256 result) - { - toTimestamp - fromTimestamp; - (uint256 fromYear, uint256 fromMonth,) = epochDayToDate(fromTimestamp / 86400); - (uint256 toYear, uint256 toMonth,) = epochDayToDate(toTimestamp / 86400); - result = _sub(_totalMonths(toYear, toMonth), _totalMonths(fromYear, fromMonth)); - } - - /// @dev Returns the difference in days between `fromTimestamp` and `toTimestamp`. - function diffDays(uint256 fromTimestamp, uint256 toTimestamp) - internal - pure - returns (uint256 result) - { - result = (toTimestamp - fromTimestamp) / 86400; - } - - /// @dev Returns the difference in hours between `fromTimestamp` and `toTimestamp`. - function diffHours(uint256 fromTimestamp, uint256 toTimestamp) - internal - pure - returns (uint256 result) - { - result = (toTimestamp - fromTimestamp) / 3600; - } - - /// @dev Returns the difference in minutes between `fromTimestamp` and `toTimestamp`. - function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp) - internal - pure - returns (uint256 result) - { - result = (toTimestamp - fromTimestamp) / 60; - } - - /// @dev Returns the difference in seconds between `fromTimestamp` and `toTimestamp`. - function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp) - internal - pure - returns (uint256 result) - { - result = toTimestamp - fromTimestamp; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unchecked arithmetic for computing the total number of months. - function _totalMonths(uint256 numYears, uint256 numMonths) - private - pure - returns (uint256 total) - { - unchecked { - total = numYears * 12 + numMonths; - } - } - - /// @dev Unchecked arithmetic for adding two numbers. - function _add(uint256 a, uint256 b) private pure returns (uint256 c) { - unchecked { - c = a + b; - } - } - - /// @dev Unchecked arithmetic for subtracting two numbers. - function _sub(uint256 a, uint256 b) private pure returns (uint256 c) { - unchecked { - c = a - b; - } - } - - /// @dev Returns the offsetted timestamp. - function _offsetted(uint256 year, uint256 month, uint256 day, uint256 timestamp) - private - pure - returns (uint256 result) - { - uint256 dm = daysInMonth(year, month); - if (day >= dm) { - day = dm; - } - result = dateToEpochDay(year, month, day) * 86400 + (timestamp % 86400); - } -} diff --git a/grouperBot/lib/solady/src/utils/DeploylessPredeployQueryer.sol b/grouperBot/lib/solady/src/utils/DeploylessPredeployQueryer.sol deleted file mode 100644 index c321bd5..0000000 --- a/grouperBot/lib/solady/src/utils/DeploylessPredeployQueryer.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Deployless queryer for predeploys. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/DeploylessPredeployQueryer.sol) -/// @author Wilson Cusack (Coinbase) -/// (https://github.com/coinbase/smart-wallet/blob/main/src/utils/ERC1271InputGenerator.sol) -/// (https://github.com/wilsoncusack/scw-tx/blob/main/utils/ERC1271.ts) -/// -/// @dev -/// This contract is not meant to ever actually be deployed, -/// only mock deployed and used via a static `eth_call`. -/// -/// Creation code (hex-encoded): -/// `3860b63d393d516020805190606051833b15607e575b5059926040908285528351938460051b9459523d604087015260005b858103603e578680590390f35b6000828683820101510138908688820151910147875af115607457603f19875903018482890101523d59523d6000593e84016031565b3d6000803e3d6000fd5b816000828193519083479101906040515af11560ad5783815114601f3d111660155763d1f6b81290526004601cfd5b3d81803e3d90fdfe` -/// See: https://gist.github.com/Vectorized/f77fce00a03dfa99aee526d2a77fd2aa -/// -/// May be useful for generating ERC-6492 compliant signatures. -/// Inspired by Ambire's DeploylessUniversalSigValidator -/// (https://github.com/AmbireTech/signature-validator/blob/main/contracts/DeploylessUniversalSigValidator.sol) -contract DeploylessPredeployQueryer { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The returned address by the factory does not match the provided address. - error ReturnedAddressMismatch(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The code of the deployed contract can be `abi.decoded` into an array of bytes, - /// where each entry can be `abi.decoded` into the required variables. - /// - /// For example, if `targetQueryCalldata`'s 0th call is expected to return a `uint256`, - /// you will use `abi.decode(abi.decode(deployed.code, (bytes[]))[0], (uint256))` to - /// get the returned `uint256`. - constructor( - address target, - bytes[] memory targetQueryCalldata, - address factory, - bytes memory factoryCalldata - ) payable { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - // If the target does not exist, deploy it. - if iszero(extcodesize(target)) { - if iszero( - call( - gas(), - factory, - selfbalance(), - add(factoryCalldata, 0x20), - mload(factoryCalldata), - m, - 0x20 - ) - ) { - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - if iszero(and(gt(returndatasize(), 0x1f), eq(mload(m), target))) { - mstore(0x00, 0xd1f6b812) // `ReturnedAddressMismatch()`. - revert(0x1c, 0x04) - } - } - let l := mload(targetQueryCalldata) - let n := shl(5, l) - let r := add(m, 0x40) - let o := add(r, n) - for { let i := 0 } iszero(eq(i, n)) { i := add(0x20, i) } { - let j := mload(add(add(targetQueryCalldata, 0x20), i)) - if iszero( - call(gas(), target, selfbalance(), add(j, 0x20), mload(j), codesize(), 0x00) - ) { - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - mstore(add(r, i), sub(o, r)) - mstore(o, returndatasize()) - returndatacopy(add(o, 0x20), 0x00, returndatasize()) - o := and(add(add(o, returndatasize()), 0x3f), not(0x1f)) - } - mstore(m, 0x20) - mstore(add(m, 0x20), l) - return(m, sub(o, m)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/DynamicArrayLib.sol b/grouperBot/lib/solady/src/utils/DynamicArrayLib.sol deleted file mode 100644 index 2dac234..0000000 --- a/grouperBot/lib/solady/src/utils/DynamicArrayLib.sol +++ /dev/null @@ -1,1020 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for memory arrays with automatic capacity resizing. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/DynamicArrayLib.sol) -library DynamicArrayLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Type to represent a dynamic array in memory. - /// You can directly assign to `data`, and the `p` function will - /// take care of the memory allocation. - struct DynamicArray { - uint256[] data; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when the element is not found in the array. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UINT256 ARRAY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Low level minimalist uint256 array operations. - // If you don't need syntax sugar, it's recommended to use these. - // Some of these functions return the same array for function chaining. - // e.g. `array.set(0, 1).set(1, 2)`. - - /// @dev Returns a uint256 array with `n` elements. The elements are not zeroized. - function malloc(uint256 n) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := or(sub(0, shr(32, n)), mload(0x40)) - mstore(result, n) - mstore(0x40, add(add(result, 0x20), shl(5, n))) - } - } - - /// @dev Zeroizes all the elements of `a`. - function zeroize(uint256[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - calldatacopy(add(result, 0x20), calldatasize(), shl(5, mload(result))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function get(uint256[] memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getUint256(uint256[] memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getAddress(uint256[] memory a, uint256 i) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getBool(uint256[] memory a, uint256 i) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getBytes32(uint256[] memory a, uint256 i) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, uint256 data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), data) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, address data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), shr(96, shl(96, data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, bool data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), iszero(iszero(data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, bytes32 data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), data) - } - } - - /// @dev Casts `a` to `address[]`. - function asAddressArray(uint256[] memory a) internal pure returns (address[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `bool[]`. - function asBoolArray(uint256[] memory a) internal pure returns (bool[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `bytes32[]`. - function asBytes32Array(uint256[] memory a) internal pure returns (bytes32[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `uint256[]`. - function toUint256Array(address[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `uint256[]`. - function toUint256Array(bool[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `uint256[]`. - function toUint256Array(bytes32[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Reduces the size of `a` to `n`. - /// If `n` is greater than the size of `a`, this will be a no-op. - function truncate(uint256[] memory a, uint256 n) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := a - mstore(mul(lt(n, mload(result)), result), n) - } - } - - /// @dev Clears the array and attempts to free the memory if possible. - function free(uint256[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - let n := mload(result) - mstore(shl(6, lt(iszero(n), eq(add(shl(5, add(1, n)), result), mload(0x40)))), result) - mstore(result, 0) - } - } - - /// @dev Equivalent to `keccak256(abi.encodePacked(a))`. - function hash(uint256[] memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(add(a, 0x20), shl(5, mload(a))) - } - } - - /// @dev Returns a copy of `a` sliced from `start` to `end` (exclusive). - function slice(uint256[] memory a, uint256 start, uint256 end) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - let arrayLen := mload(a) - if iszero(gt(arrayLen, end)) { end := arrayLen } - if iszero(gt(arrayLen, start)) { start := arrayLen } - if lt(start, end) { - result := mload(0x40) - let resultLen := sub(end, start) - mstore(result, resultLen) - a := add(a, shl(5, start)) - // Copy the `a` one word at a time, backwards. - let o := shl(5, resultLen) - mstore(0x40, add(add(result, o), 0x20)) // Allocate memory. - for {} 1 {} { - mstore(add(result, o), mload(add(a, o))) - o := sub(o, 0x20) - if iszero(o) { break } - } - } - } - } - - /// @dev Returns a copy of `a` sliced from `start` to the end of the array. - function slice(uint256[] memory a, uint256 start) - internal - pure - returns (uint256[] memory result) - { - result = slice(a, start, type(uint256).max); - } - - /// @dev Returns a copy of the array. - function copy(uint256[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let end := add(add(result, 0x20), shl(5, mload(a))) - let o := result - for { let d := sub(a, result) } 1 {} { - mstore(o, mload(add(o, d))) - o := add(0x20, o) - if eq(o, end) { break } - } - mstore(0x40, o) - } - } - - /// @dev Returns if `needle` is in `a`. - function contains(uint256[] memory a, uint256 needle) internal pure returns (bool) { - return ~indexOf(a, needle, 0) != 0; - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(uint256[] memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) - if lt(from, mload(a)) { - let o := add(a, shl(5, from)) - let end := add(shl(5, add(1, mload(a))), a) - let c := mload(end) // Cache the word after the array. - for { mstore(end, needle) } 1 {} { - o := add(o, 0x20) - if eq(mload(o), needle) { break } - } - mstore(end, c) // Restore the word after the array. - if iszero(eq(o, end)) { result := shr(5, sub(o, add(0x20, a))) } - } - } - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(uint256[] memory a, uint256 needle) internal pure returns (uint256 result) { - result = indexOf(a, needle, 0); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(uint256[] memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) - let n := mload(a) - if n { - if iszero(lt(from, n)) { from := sub(n, 1) } - let o := add(shl(5, add(2, from)), a) - for { mstore(a, needle) } 1 {} { - o := sub(o, 0x20) - if eq(mload(o), needle) { break } - } - mstore(a, n) // Restore the length. - if iszero(eq(o, a)) { result := shr(5, sub(o, add(0x20, a))) } - } - } - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(uint256[] memory a, uint256 needle) - internal - pure - returns (uint256 result) - { - result = lastIndexOf(a, needle, NOT_FOUND); - } - - /// @dev Directly returns `a` without copying. - function directReturn(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let retStart := sub(a, 0x20) - mstore(retStart, 0x20) - return(retStart, add(0x40, shl(5, mload(a)))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DYNAMIC ARRAY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Some of these functions return the same array for function chaining. - // e.g. `a.p("1").p("2")`. - - /// @dev Shorthand for `a.data.length`. - function length(DynamicArray memory a) internal pure returns (uint256) { - return a.data.length; - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(uint256[] memory a) internal pure returns (DynamicArray memory result) { - result.data = a; - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(address[] memory a) internal pure returns (DynamicArray memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, a) - } - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(bool[] memory a) internal pure returns (DynamicArray memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, a) - } - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(bytes32[] memory a) internal pure returns (DynamicArray memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, a) - } - } - - /// @dev Clears the array without deallocating the memory. - function clear(DynamicArray memory a) internal pure returns (DynamicArray memory result) { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(mload(result), 0) - } - } - - /// @dev Clears the array and attempts to free the memory if possible. - function free(DynamicArray memory a) internal pure returns (DynamicArray memory result) { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(result) - if iszero(eq(arrData, 0x60)) { - let prime := 8188386068317523 - let cap := mload(sub(arrData, 0x20)) - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - // If `cap` is non-zero and the memory is contiguous, we can free it. - if lt(iszero(cap), eq(mload(0x40), add(arrData, add(0x20, cap)))) { - mstore(0x40, sub(arrData, 0x20)) - } - mstore(result, 0x60) - } - } - } - - /// @dev Resizes the array to contain `n` elements. New elements will be zeroized. - function resize(DynamicArray memory a, uint256 n) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - reserve(result, n); - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(result) - let arrLen := mload(arrData) - if iszero(lt(n, arrLen)) { - calldatacopy( - add(arrData, shl(5, add(1, arrLen))), calldatasize(), shl(5, sub(n, arrLen)) - ) - } - mstore(arrData, n) - } - } - - /// @dev Increases the size of `a` to `n`. - /// If `n` is less than the size of `a`, this will be a no-op. - /// This method does not zeroize any newly created elements. - function expand(DynamicArray memory a, uint256 n) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - if (n >= a.data.length) { - reserve(result, n); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(result), n) - } - } - } - - /// @dev Reduces the size of `a` to `n`. - /// If `n` is greater than the size of `a`, this will be a no-op. - function truncate(DynamicArray memory a, uint256 n) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(mul(lt(n, mload(mload(result))), mload(result)), n) - } - } - - /// @dev Reserves at least `minimum` amount of contiguous memory. - function reserve(DynamicArray memory a, uint256 minimum) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(minimum, 0xffffffff)) { invalid() } // For extra safety. - for { let arrData := mload(a) } 1 {} { - // Some random prime number to multiply `cap`, so that - // we know that the `cap` is for a dynamic array. - // Selected to be larger than any memory pointer realistically. - let prime := 8188386068317523 - // Special case for `arrData` pointing to zero pointer. - if eq(arrData, 0x60) { - let newCap := shl(5, add(1, minimum)) - let capSlot := mload(0x40) - mstore(capSlot, mul(prime, newCap)) // Store the capacity. - let newArrData := add(0x20, capSlot) - mstore(newArrData, 0) // Store the length. - mstore(0x40, add(newArrData, add(0x20, newCap))) // Allocate memory. - mstore(a, newArrData) - break - } - let w := not(0x1f) - let cap := mload(add(arrData, w)) // `mload(sub(arrData, w))`. - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - let newCap := shl(5, minimum) - // If we don't need to grow the memory. - if iszero(and(gt(minimum, mload(arrData)), gt(newCap, cap))) { break } - // If the memory is contiguous, we can simply expand it. - if eq(mload(0x40), add(arrData, add(0x20, cap))) { - mstore(add(arrData, w), mul(prime, newCap)) // Store the capacity. - mstore(0x40, add(arrData, add(0x20, newCap))) // Expand the memory allocation. - break - } - let capSlot := mload(0x40) - let newArrData := add(capSlot, 0x20) - mstore(0x40, add(newArrData, add(0x20, newCap))) // Reallocate the memory. - mstore(a, newArrData) // Store the `newArrData`. - // Copy `arrData` one word at a time, backwards. - for { let o := add(0x20, shl(5, mload(arrData))) } 1 {} { - mstore(add(newArrData, o), mload(add(arrData, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(capSlot, mul(prime, newCap)) // Store the capacity. - mstore(newArrData, mload(arrData)) // Store the length. - break - } - } - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, uint256 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(a) - let newArrLen := add(mload(arrData), 1) - let newArrBytesLen := shl(5, newArrLen) - // Some random prime number to multiply `cap`, so that - // we know that the `cap` is for a dynamic array. - // Selected to be larger than any memory pointer realistically. - let prime := 8188386068317523 - let cap := mload(sub(arrData, 0x20)) - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - - // Expand / Reallocate memory if required. - // Note that we need to allocate an extra word for the length. - for {} iszero(lt(newArrBytesLen, cap)) {} { - // Approximately more than double the capacity to ensure more than enough space. - let newCap := add(cap, or(cap, newArrBytesLen)) - // If the memory is contiguous, we can simply expand it. - if iszero(or(xor(mload(0x40), add(arrData, add(0x20, cap))), iszero(cap))) { - mstore(sub(arrData, 0x20), mul(prime, newCap)) // Store the capacity. - mstore(0x40, add(arrData, add(0x20, newCap))) // Expand the memory allocation. - break - } - // Set the `newArrData` to point to the word after `cap`. - let newArrData := add(mload(0x40), 0x20) - mstore(0x40, add(newArrData, add(0x20, newCap))) // Reallocate the memory. - mstore(a, newArrData) // Store the `newArrData`. - let w := not(0x1f) - // Copy `arrData` one word at a time, backwards. - for { let o := newArrBytesLen } 1 {} { - mstore(add(newArrData, o), mload(add(arrData, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(add(newArrData, w), mul(prime, newCap)) // Store the memory. - arrData := newArrData // Assign `newArrData` to `arrData`. - break - } - mstore(add(arrData, newArrBytesLen), data) // Append `data`. - mstore(arrData, newArrLen) // Store the length. - } - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, address data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = p(a, uint256(uint160(data))); - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, bool data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = p(a, _toUint(data)); - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, bytes32 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = p(a, uint256(data)); - } - - /// @dev Shorthand for returning an empty array. - function p() internal pure returns (DynamicArray memory result) {} - - /// @dev Shorthand for `p(p(), data)`. - function p(uint256 data) internal pure returns (DynamicArray memory result) { - p(result, uint256(data)); - } - - /// @dev Shorthand for `p(p(), data)`. - function p(address data) internal pure returns (DynamicArray memory result) { - p(result, uint256(uint160(data))); - } - - /// @dev Shorthand for `p(p(), data)`. - function p(bool data) internal pure returns (DynamicArray memory result) { - p(result, _toUint(data)); - } - - /// @dev Shorthand for `p(p(), data)`. - function p(bytes32 data) internal pure returns (DynamicArray memory result) { - p(result, uint256(data)); - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function pop(DynamicArray memory a) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popUint256(DynamicArray memory a) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popAddress(DynamicArray memory a) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popBool(DynamicArray memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popBytes32(DynamicArray memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function get(DynamicArray memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getUint256(DynamicArray memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getAddress(DynamicArray memory a, uint256 i) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getBool(DynamicArray memory a, uint256 i) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getBytes32(DynamicArray memory a, uint256 i) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, uint256 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), data) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, address data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), shr(96, shl(96, data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, bool data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), iszero(iszero(data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, bytes32 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), data) - } - } - - /// @dev Returns the underlying array as a `uint256[]`. - function asUint256Array(DynamicArray memory a) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns the underlying array as a `address[]`. - function asAddressArray(DynamicArray memory a) - internal - pure - returns (address[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns the underlying array as a `bool[]`. - function asBoolArray(DynamicArray memory a) internal pure returns (bool[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns the underlying array as a `bytes32[]`. - function asBytes32Array(DynamicArray memory a) - internal - pure - returns (bytes32[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns a copy of `a` sliced from `start` to `end` (exclusive). - function slice(DynamicArray memory a, uint256 start, uint256 end) - internal - pure - returns (DynamicArray memory result) - { - result.data = slice(a.data, start, end); - } - - /// @dev Returns a copy of `a` sliced from `start` to the end of the array. - function slice(DynamicArray memory a, uint256 start) - internal - pure - returns (DynamicArray memory result) - { - result.data = slice(a.data, start, type(uint256).max); - } - - /// @dev Returns a copy of `a`. - function copy(DynamicArray memory a) internal pure returns (DynamicArray memory result) { - result.data = copy(a.data); - } - - /// @dev Returns if `needle` is in `a`. - function contains(DynamicArray memory a, uint256 needle) internal pure returns (bool) { - return ~indexOf(a.data, needle, 0) != 0; - } - - /// @dev Returns if `needle` is in `a`. - function contains(DynamicArray memory a, address needle) internal pure returns (bool) { - return ~indexOf(a.data, uint160(needle), 0) != 0; - } - - /// @dev Returns if `needle` is in `a`. - function contains(DynamicArray memory a, bytes32 needle) internal pure returns (bool) { - return ~indexOf(a.data, uint256(needle), 0) != 0; - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256) - { - return indexOf(a.data, needle, from); - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, address needle, uint256 from) - internal - pure - returns (uint256) - { - return indexOf(a.data, uint160(needle), from); - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, bytes32 needle, uint256 from) - internal - pure - returns (uint256) - { - return indexOf(a.data, uint256(needle), from); - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, uint256 needle) internal pure returns (uint256) { - return indexOf(a.data, needle, 0); - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, address needle) internal pure returns (uint256) { - return indexOf(a.data, uint160(needle), 0); - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, bytes32 needle) internal pure returns (uint256) { - return indexOf(a.data, uint256(needle), 0); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256) - { - return lastIndexOf(a.data, needle, from); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, address needle, uint256 from) - internal - pure - returns (uint256) - { - return lastIndexOf(a.data, uint160(needle), from); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, bytes32 needle, uint256 from) - internal - pure - returns (uint256) - { - return lastIndexOf(a.data, uint256(needle), from); - } - - /// @dev Returns the last index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, uint256 needle) internal pure returns (uint256) { - return lastIndexOf(a.data, needle, NOT_FOUND); - } - - /// @dev Returns the last index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, address needle) internal pure returns (uint256) { - return lastIndexOf(a.data, uint160(needle), NOT_FOUND); - } - - /// @dev Returns the last index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, bytes32 needle) internal pure returns (uint256) { - return lastIndexOf(a.data, uint256(needle), NOT_FOUND); - } - - /// @dev Equivalent to `keccak256(abi.encodePacked(a.data))`. - function hash(DynamicArray memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(add(mload(a), 0x20), shl(5, mload(mload(a)))) - } - } - - /// @dev Directly returns `a` without copying. - function directReturn(DynamicArray memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(a) - let retStart := sub(arrData, 0x20) - mstore(retStart, 0x20) - return(retStart, add(0x40, shl(5, mload(arrData)))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper for deallocating an automatically allocated array pointer. - function _deallocate(DynamicArray memory result) private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Deallocate, as we have already allocated. - } - } - - /// @dev Casts the bool into a uint256. - function _toUint(bool b) private pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := iszero(iszero(b)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/DynamicBufferLib.sol b/grouperBot/lib/solady/src/utils/DynamicBufferLib.sol deleted file mode 100644 index be05412..0000000 --- a/grouperBot/lib/solady/src/utils/DynamicBufferLib.sol +++ /dev/null @@ -1,1313 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for buffers with automatic capacity resizing. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/DynamicBufferLib.sol) -/// @author Modified from cozyco (https://github.com/samkingco/cozyco/blob/main/contracts/utils/DynamicBuffer.sol) -library DynamicBufferLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Type to represent a dynamic buffer in memory. - /// You can directly assign to `data`, and the `p` function will - /// take care of the memory allocation. - struct DynamicBuffer { - bytes data; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Some of these functions return the same buffer for function chaining. - // e.g. `buffer.p("1").p("2")`. - - /// @dev Shorthand for `buffer.data.length`. - function length(DynamicBuffer memory buffer) internal pure returns (uint256) { - return buffer.data.length; - } - - /// @dev Reserves at least `minimum` amount of contiguous memory. - function reserve(DynamicBuffer memory buffer, uint256 minimum) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = buffer; - uint256 n = buffer.data.length; - if (minimum > n) { - uint256 i = 0x40; - do {} while ((i <<= 1) < minimum); - bytes memory data; - /// @solidity memory-safe-assembly - assembly { - data := 0x01 - mstore(data, sub(i, n)) - } - result = p(result, data); - } - } - - /// @dev Clears the buffer without deallocating the memory. - function clear(DynamicBuffer memory buffer) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(buffer), 0) - } - result = buffer; - } - - /// @dev Returns a string pointing to the underlying bytes data. - /// Note: The string WILL change if the buffer is updated. - function s(DynamicBuffer memory buffer) internal pure returns (string memory) { - return string(buffer.data); - } - - /// @dev Appends `data` to `buffer`. - function p(DynamicBuffer memory buffer, bytes memory data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = buffer; - if (data.length == uint256(0)) return result; - /// @solidity memory-safe-assembly - assembly { - let w := not(0x1f) - let bufData := mload(buffer) - let bufDataLen := mload(bufData) - let newBufDataLen := add(mload(data), bufDataLen) - // Some random prime number to multiply `cap`, so that - // we know that the `cap` is for a dynamic buffer. - // Selected to be larger than any memory pointer realistically. - let prime := 1621250193422201 - let cap := mload(add(bufData, w)) // `mload(sub(bufData, 0x20))`. - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - - // Expand / Reallocate memory if required. - // Note that we need to allocate an extra word for the length, and - // and another extra word as a safety word (giving a total of 0x40 bytes). - // Without the safety word, the backwards copying can cause a buffer overflow. - for {} iszero(lt(newBufDataLen, cap)) {} { - // Approximately more than double the capacity to ensure more than enough space. - let newCap := and(add(cap, add(or(cap, newBufDataLen), 0x20)), w) - // If the memory is contiguous, we can simply expand it. - if iszero(or(xor(mload(0x40), add(bufData, add(0x40, cap))), iszero(cap))) { - // Store `cap * prime` in the word before the length. - mstore(add(bufData, w), mul(prime, newCap)) - mstore(0x40, add(bufData, add(0x40, newCap))) // Expand the memory allocation. - break - } - // Set the `newBufData` to point to the word after `cap`. - let newBufData := add(mload(0x40), 0x20) - mstore(0x40, add(newBufData, add(0x40, newCap))) // Reallocate the memory. - mstore(buffer, newBufData) // Store the `newBufData`. - // Copy `bufData` one word at a time, backwards. - for { let o := and(add(bufDataLen, 0x20), w) } 1 {} { - mstore(add(newBufData, o), mload(add(bufData, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - // Store `cap * prime` in the word before the length. - mstore(add(newBufData, w), mul(prime, newCap)) - bufData := newBufData // Assign `newBufData` to `bufData`. - break - } - // If it's a reserve operation, set the variables to skip the appending. - if eq(data, 0x01) { - mstore(data, 0x00) - newBufDataLen := bufDataLen - } - // Copy `data` one word at a time, backwards. - for { let o := and(add(mload(data), 0x20), w) } 1 {} { - mstore(add(add(bufData, bufDataLen), o), mload(add(data, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(add(add(bufData, 0x20), newBufDataLen), 0) // Zeroize the word after the buffer. - mstore(bufData, newBufDataLen) // Store the length. - } - } - - /// @dev Appends `data0`, `data1` to `buffer`. - function p(DynamicBuffer memory buffer, bytes memory data0, bytes memory data1) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(p(buffer, data0), data1); - } - - /// @dev Appends `data0` .. `data2` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(buffer, data0), data1), data2); - } - - /// @dev Appends `data0` .. `data3` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(buffer, data0), data1), data2), data3); - } - - /// @dev Appends `data0` .. `data4` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(p(buffer, data0), data1), data2), data3), data4); - } - - /// @dev Appends `data0` .. `data5` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(p(p(buffer, data0), data1), data2), data3), data4), data5); - } - - /// @dev Appends `data0` .. `data6` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5, - bytes memory data6 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(p(p(p(buffer, data0), data1), data2), data3), data4), data5), data6); - } - - /// @dev Appends `abi.encodePacked(bool(data))` to buffer. - function pBool(DynamicBuffer memory buffer, bool data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - uint256 casted; - /// @solidity memory-safe-assembly - assembly { - casted := iszero(iszero(data)) - } - result = p(buffer, _single(casted, 1)); - } - - /// @dev Appends `abi.encodePacked(address(data))` to buffer. - function pAddress(DynamicBuffer memory buffer, address data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(uint256(uint160(data)), 20)); - } - - /// @dev Appends `abi.encodePacked(uint8(data))` to buffer. - function pUint8(DynamicBuffer memory buffer, uint8 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 1)); - } - - /// @dev Appends `abi.encodePacked(uint16(data))` to buffer. - function pUint16(DynamicBuffer memory buffer, uint16 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 2)); - } - - /// @dev Appends `abi.encodePacked(uint24(data))` to buffer. - function pUint24(DynamicBuffer memory buffer, uint24 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 3)); - } - - /// @dev Appends `abi.encodePacked(uint32(data))` to buffer. - function pUint32(DynamicBuffer memory buffer, uint32 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 4)); - } - - /// @dev Appends `abi.encodePacked(uint40(data))` to buffer. - function pUint40(DynamicBuffer memory buffer, uint40 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 5)); - } - - /// @dev Appends `abi.encodePacked(uint48(data))` to buffer. - function pUint48(DynamicBuffer memory buffer, uint48 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 6)); - } - - /// @dev Appends `abi.encodePacked(uint56(data))` to buffer. - function pUint56(DynamicBuffer memory buffer, uint56 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 7)); - } - - /// @dev Appends `abi.encodePacked(uint64(data))` to buffer. - function pUint64(DynamicBuffer memory buffer, uint64 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 8)); - } - - /// @dev Appends `abi.encodePacked(uint72(data))` to buffer. - function pUint72(DynamicBuffer memory buffer, uint72 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 9)); - } - - /// @dev Appends `abi.encodePacked(uint80(data))` to buffer. - function pUint80(DynamicBuffer memory buffer, uint80 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 10)); - } - - /// @dev Appends `abi.encodePacked(uint88(data))` to buffer. - function pUint88(DynamicBuffer memory buffer, uint88 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 11)); - } - - /// @dev Appends `abi.encodePacked(uint96(data))` to buffer. - function pUint96(DynamicBuffer memory buffer, uint96 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 12)); - } - - /// @dev Appends `abi.encodePacked(uint104(data))` to buffer. - function pUint104(DynamicBuffer memory buffer, uint104 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 13)); - } - - /// @dev Appends `abi.encodePacked(uint112(data))` to buffer. - function pUint112(DynamicBuffer memory buffer, uint112 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 14)); - } - - /// @dev Appends `abi.encodePacked(uint120(data))` to buffer. - function pUint120(DynamicBuffer memory buffer, uint120 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 15)); - } - - /// @dev Appends `abi.encodePacked(uint128(data))` to buffer. - function pUint128(DynamicBuffer memory buffer, uint128 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 16)); - } - - /// @dev Appends `abi.encodePacked(uint136(data))` to buffer. - function pUint136(DynamicBuffer memory buffer, uint136 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 17)); - } - - /// @dev Appends `abi.encodePacked(uint144(data))` to buffer. - function pUint144(DynamicBuffer memory buffer, uint144 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 18)); - } - - /// @dev Appends `abi.encodePacked(uint152(data))` to buffer. - function pUint152(DynamicBuffer memory buffer, uint152 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 19)); - } - - /// @dev Appends `abi.encodePacked(uint160(data))` to buffer. - function pUint160(DynamicBuffer memory buffer, uint160 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 20)); - } - - /// @dev Appends `abi.encodePacked(uint168(data))` to buffer. - function pUint168(DynamicBuffer memory buffer, uint168 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 21)); - } - - /// @dev Appends `abi.encodePacked(uint176(data))` to buffer. - function pUint176(DynamicBuffer memory buffer, uint176 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 22)); - } - - /// @dev Appends `abi.encodePacked(uint184(data))` to buffer. - function pUint184(DynamicBuffer memory buffer, uint184 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 23)); - } - - /// @dev Appends `abi.encodePacked(uint192(data))` to buffer. - function pUint192(DynamicBuffer memory buffer, uint192 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 24)); - } - - /// @dev Appends `abi.encodePacked(uint200(data))` to buffer. - function pUint200(DynamicBuffer memory buffer, uint200 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 25)); - } - - /// @dev Appends `abi.encodePacked(uint208(data))` to buffer. - function pUint208(DynamicBuffer memory buffer, uint208 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 26)); - } - - /// @dev Appends `abi.encodePacked(uint216(data))` to buffer. - function pUint216(DynamicBuffer memory buffer, uint216 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 27)); - } - - /// @dev Appends `abi.encodePacked(uint224(data))` to buffer. - function pUint224(DynamicBuffer memory buffer, uint224 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 28)); - } - - /// @dev Appends `abi.encodePacked(uint232(data))` to buffer. - function pUint232(DynamicBuffer memory buffer, uint232 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 29)); - } - - /// @dev Appends `abi.encodePacked(uint240(data))` to buffer. - function pUint240(DynamicBuffer memory buffer, uint240 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 30)); - } - - /// @dev Appends `abi.encodePacked(uint248(data))` to buffer. - function pUint248(DynamicBuffer memory buffer, uint248 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 31)); - } - - /// @dev Appends `abi.encodePacked(uint256(data))` to buffer. - function pUint256(DynamicBuffer memory buffer, uint256 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 32)); - } - - /// @dev Appends `abi.encodePacked(bytes1(data))` to buffer. - function pBytes1(DynamicBuffer memory buffer, bytes1 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 1)); - } - - /// @dev Appends `abi.encodePacked(bytes2(data))` to buffer. - function pBytes2(DynamicBuffer memory buffer, bytes2 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 2)); - } - - /// @dev Appends `abi.encodePacked(bytes3(data))` to buffer. - function pBytes3(DynamicBuffer memory buffer, bytes3 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 3)); - } - - /// @dev Appends `abi.encodePacked(bytes4(data))` to buffer. - function pBytes4(DynamicBuffer memory buffer, bytes4 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 4)); - } - - /// @dev Appends `abi.encodePacked(bytes5(data))` to buffer. - function pBytes5(DynamicBuffer memory buffer, bytes5 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 5)); - } - - /// @dev Appends `abi.encodePacked(bytes6(data))` to buffer. - function pBytes6(DynamicBuffer memory buffer, bytes6 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 6)); - } - - /// @dev Appends `abi.encodePacked(bytes7(data))` to buffer. - function pBytes7(DynamicBuffer memory buffer, bytes7 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 7)); - } - - /// @dev Appends `abi.encodePacked(bytes8(data))` to buffer. - function pBytes8(DynamicBuffer memory buffer, bytes8 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 8)); - } - - /// @dev Appends `abi.encodePacked(bytes9(data))` to buffer. - function pBytes9(DynamicBuffer memory buffer, bytes9 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 9)); - } - - /// @dev Appends `abi.encodePacked(bytes10(data))` to buffer. - function pBytes10(DynamicBuffer memory buffer, bytes10 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 10)); - } - - /// @dev Appends `abi.encodePacked(bytes11(data))` to buffer. - function pBytes11(DynamicBuffer memory buffer, bytes11 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 11)); - } - - /// @dev Appends `abi.encodePacked(bytes12(data))` to buffer. - function pBytes12(DynamicBuffer memory buffer, bytes12 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 12)); - } - - /// @dev Appends `abi.encodePacked(bytes13(data))` to buffer. - function pBytes13(DynamicBuffer memory buffer, bytes13 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 13)); - } - - /// @dev Appends `abi.encodePacked(bytes14(data))` to buffer. - function pBytes14(DynamicBuffer memory buffer, bytes14 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 14)); - } - - /// @dev Appends `abi.encodePacked(bytes15(data))` to buffer. - function pBytes15(DynamicBuffer memory buffer, bytes15 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 15)); - } - - /// @dev Appends `abi.encodePacked(bytes16(data))` to buffer. - function pBytes16(DynamicBuffer memory buffer, bytes16 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 16)); - } - - /// @dev Appends `abi.encodePacked(bytes17(data))` to buffer. - function pBytes17(DynamicBuffer memory buffer, bytes17 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 17)); - } - - /// @dev Appends `abi.encodePacked(bytes18(data))` to buffer. - function pBytes18(DynamicBuffer memory buffer, bytes18 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 18)); - } - - /// @dev Appends `abi.encodePacked(bytes19(data))` to buffer. - function pBytes19(DynamicBuffer memory buffer, bytes19 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 19)); - } - - /// @dev Appends `abi.encodePacked(bytes20(data))` to buffer. - function pBytes20(DynamicBuffer memory buffer, bytes20 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 20)); - } - - /// @dev Appends `abi.encodePacked(bytes21(data))` to buffer. - function pBytes21(DynamicBuffer memory buffer, bytes21 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 21)); - } - - /// @dev Appends `abi.encodePacked(bytes22(data))` to buffer. - function pBytes22(DynamicBuffer memory buffer, bytes22 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 22)); - } - - /// @dev Appends `abi.encodePacked(bytes23(data))` to buffer. - function pBytes23(DynamicBuffer memory buffer, bytes23 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 23)); - } - - /// @dev Appends `abi.encodePacked(bytes24(data))` to buffer. - function pBytes24(DynamicBuffer memory buffer, bytes24 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 24)); - } - - /// @dev Appends `abi.encodePacked(bytes25(data))` to buffer. - function pBytes25(DynamicBuffer memory buffer, bytes25 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 25)); - } - - /// @dev Appends `abi.encodePacked(bytes26(data))` to buffer. - function pBytes26(DynamicBuffer memory buffer, bytes26 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 26)); - } - - /// @dev Appends `abi.encodePacked(bytes27(data))` to buffer. - function pBytes27(DynamicBuffer memory buffer, bytes27 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 27)); - } - - /// @dev Appends `abi.encodePacked(bytes28(data))` to buffer. - function pBytes28(DynamicBuffer memory buffer, bytes28 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 28)); - } - - /// @dev Appends `abi.encodePacked(bytes29(data))` to buffer. - function pBytes29(DynamicBuffer memory buffer, bytes29 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 29)); - } - - /// @dev Appends `abi.encodePacked(bytes30(data))` to buffer. - function pBytes30(DynamicBuffer memory buffer, bytes30 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 30)); - } - - /// @dev Appends `abi.encodePacked(bytes31(data))` to buffer. - function pBytes31(DynamicBuffer memory buffer, bytes31 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 31)); - } - - /// @dev Appends `abi.encodePacked(bytes32(data))` to buffer. - function pBytes32(DynamicBuffer memory buffer, bytes32 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 32)); - } - - /// @dev Shorthand for returning a new buffer. - function p() internal pure returns (DynamicBuffer memory result) {} - - /// @dev Shorthand for `p(p(), data)`. - function p(bytes memory data) internal pure returns (DynamicBuffer memory result) { - p(result, data); - } - - /// @dev Shorthand for `p(p(), data0, data1)`. - function p(bytes memory data0, bytes memory data1) - internal - pure - returns (DynamicBuffer memory result) - { - p(p(result, data0), data1); - } - - /// @dev Shorthand for `p(p(), data0, .., data2)`. - function p(bytes memory data0, bytes memory data1, bytes memory data2) - internal - pure - returns (DynamicBuffer memory result) - { - p(p(p(result, data0), data1), data2); - } - - /// @dev Shorthand for `p(p(), data0, .., data3)`. - function p(bytes memory data0, bytes memory data1, bytes memory data2, bytes memory data3) - internal - pure - returns (DynamicBuffer memory result) - { - p(p(p(p(result, data0), data1), data2), data3); - } - - /// @dev Shorthand for `p(p(), data0, .., data4)`. - function p( - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4 - ) internal pure returns (DynamicBuffer memory result) { - p(p(p(p(p(result, data0), data1), data2), data3), data4); - } - - /// @dev Shorthand for `p(p(), data0, .., data5)`. - function p( - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5 - ) internal pure returns (DynamicBuffer memory result) { - p(p(p(p(p(p(result, data0), data1), data2), data3), data4), data5); - } - - /// @dev Shorthand for `p(p(), data0, .., data6)`. - function p( - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5, - bytes memory data6 - ) internal pure returns (DynamicBuffer memory result) { - p(p(p(p(p(p(p(result, data0), data1), data2), data3), data4), data5), data6); - } - - /// @dev Shorthand for `pBool(p(), data)`. - function pBool(bool data) internal pure returns (DynamicBuffer memory result) { - pBool(result, data); - } - - /// @dev Shorthand for `pAddress(p(), data)`. - function pAddress(address data) internal pure returns (DynamicBuffer memory result) { - pAddress(result, data); - } - - /// @dev Shorthand for `pUint8(p(), data)`. - function pUint8(uint8 data) internal pure returns (DynamicBuffer memory result) { - pUint8(result, data); - } - - /// @dev Shorthand for `pUint16(p(), data)`. - function pUint16(uint16 data) internal pure returns (DynamicBuffer memory result) { - pUint16(result, data); - } - - /// @dev Shorthand for `pUint24(p(), data)`. - function pUint24(uint24 data) internal pure returns (DynamicBuffer memory result) { - pUint24(result, data); - } - - /// @dev Shorthand for `pUint32(p(), data)`. - function pUint32(uint32 data) internal pure returns (DynamicBuffer memory result) { - pUint32(result, data); - } - - /// @dev Shorthand for `pUint40(p(), data)`. - function pUint40(uint40 data) internal pure returns (DynamicBuffer memory result) { - pUint40(result, data); - } - - /// @dev Shorthand for `pUint48(p(), data)`. - function pUint48(uint48 data) internal pure returns (DynamicBuffer memory result) { - pUint48(result, data); - } - - /// @dev Shorthand for `pUint56(p(), data)`. - function pUint56(uint56 data) internal pure returns (DynamicBuffer memory result) { - pUint56(result, data); - } - - /// @dev Shorthand for `pUint64(p(), data)`. - function pUint64(uint64 data) internal pure returns (DynamicBuffer memory result) { - pUint64(result, data); - } - - /// @dev Shorthand for `pUint72(p(), data)`. - function pUint72(uint72 data) internal pure returns (DynamicBuffer memory result) { - pUint72(result, data); - } - - /// @dev Shorthand for `pUint80(p(), data)`. - function pUint80(uint80 data) internal pure returns (DynamicBuffer memory result) { - pUint80(result, data); - } - - /// @dev Shorthand for `pUint88(p(), data)`. - function pUint88(uint88 data) internal pure returns (DynamicBuffer memory result) { - pUint88(result, data); - } - - /// @dev Shorthand for `pUint96(p(), data)`. - function pUint96(uint96 data) internal pure returns (DynamicBuffer memory result) { - pUint96(result, data); - } - - /// @dev Shorthand for `pUint104(p(), data)`. - function pUint104(uint104 data) internal pure returns (DynamicBuffer memory result) { - pUint104(result, data); - } - - /// @dev Shorthand for `pUint112(p(), data)`. - function pUint112(uint112 data) internal pure returns (DynamicBuffer memory result) { - pUint112(result, data); - } - - /// @dev Shorthand for `pUint120(p(), data)`. - function pUint120(uint120 data) internal pure returns (DynamicBuffer memory result) { - pUint120(result, data); - } - - /// @dev Shorthand for `pUint128(p(), data)`. - function pUint128(uint128 data) internal pure returns (DynamicBuffer memory result) { - pUint128(result, data); - } - - /// @dev Shorthand for `pUint136(p(), data)`. - function pUint136(uint136 data) internal pure returns (DynamicBuffer memory result) { - pUint136(result, data); - } - - /// @dev Shorthand for `pUint144(p(), data)`. - function pUint144(uint144 data) internal pure returns (DynamicBuffer memory result) { - pUint144(result, data); - } - - /// @dev Shorthand for `pUint152(p(), data)`. - function pUint152(uint152 data) internal pure returns (DynamicBuffer memory result) { - pUint152(result, data); - } - - /// @dev Shorthand for `pUint160(p(), data)`. - function pUint160(uint160 data) internal pure returns (DynamicBuffer memory result) { - pUint160(result, data); - } - - /// @dev Shorthand for `pUint168(p(), data)`. - function pUint168(uint168 data) internal pure returns (DynamicBuffer memory result) { - pUint168(result, data); - } - - /// @dev Shorthand for `pUint176(p(), data)`. - function pUint176(uint176 data) internal pure returns (DynamicBuffer memory result) { - pUint176(result, data); - } - - /// @dev Shorthand for `pUint184(p(), data)`. - function pUint184(uint184 data) internal pure returns (DynamicBuffer memory result) { - pUint184(result, data); - } - - /// @dev Shorthand for `pUint192(p(), data)`. - function pUint192(uint192 data) internal pure returns (DynamicBuffer memory result) { - pUint192(result, data); - } - - /// @dev Shorthand for `pUint200(p(), data)`. - function pUint200(uint200 data) internal pure returns (DynamicBuffer memory result) { - pUint200(result, data); - } - - /// @dev Shorthand for `pUint208(p(), data)`. - function pUint208(uint208 data) internal pure returns (DynamicBuffer memory result) { - pUint208(result, data); - } - - /// @dev Shorthand for `pUint216(p(), data)`. - function pUint216(uint216 data) internal pure returns (DynamicBuffer memory result) { - pUint216(result, data); - } - - /// @dev Shorthand for `pUint224(p(), data)`. - function pUint224(uint224 data) internal pure returns (DynamicBuffer memory result) { - pUint224(result, data); - } - - /// @dev Shorthand for `pUint232(p(), data)`. - function pUint232(uint232 data) internal pure returns (DynamicBuffer memory result) { - pUint232(result, data); - } - - /// @dev Shorthand for `pUint240(p(), data)`. - function pUint240(uint240 data) internal pure returns (DynamicBuffer memory result) { - pUint240(result, data); - } - - /// @dev Shorthand for `pUint248(p(), data)`. - function pUint248(uint248 data) internal pure returns (DynamicBuffer memory result) { - pUint248(result, data); - } - - /// @dev Shorthand for `pUint256(p(), data)`. - function pUint256(uint256 data) internal pure returns (DynamicBuffer memory result) { - pUint256(result, data); - } - - /// @dev Shorthand for `pBytes1(p(), data)`. - function pBytes1(bytes1 data) internal pure returns (DynamicBuffer memory result) { - pBytes1(result, data); - } - - /// @dev Shorthand for `pBytes2(p(), data)`. - function pBytes2(bytes2 data) internal pure returns (DynamicBuffer memory result) { - pBytes2(result, data); - } - - /// @dev Shorthand for `pBytes3(p(), data)`. - function pBytes3(bytes3 data) internal pure returns (DynamicBuffer memory result) { - pBytes3(result, data); - } - - /// @dev Shorthand for `pBytes4(p(), data)`. - function pBytes4(bytes4 data) internal pure returns (DynamicBuffer memory result) { - pBytes4(result, data); - } - - /// @dev Shorthand for `pBytes5(p(), data)`. - function pBytes5(bytes5 data) internal pure returns (DynamicBuffer memory result) { - pBytes5(result, data); - } - - /// @dev Shorthand for `pBytes6(p(), data)`. - function pBytes6(bytes6 data) internal pure returns (DynamicBuffer memory result) { - pBytes6(result, data); - } - - /// @dev Shorthand for `pBytes7(p(), data)`. - function pBytes7(bytes7 data) internal pure returns (DynamicBuffer memory result) { - pBytes7(result, data); - } - - /// @dev Shorthand for `pBytes8(p(), data)`. - function pBytes8(bytes8 data) internal pure returns (DynamicBuffer memory result) { - pBytes8(result, data); - } - - /// @dev Shorthand for `pBytes9(p(), data)`. - function pBytes9(bytes9 data) internal pure returns (DynamicBuffer memory result) { - pBytes9(result, data); - } - - /// @dev Shorthand for `pBytes10(p(), data)`. - function pBytes10(bytes10 data) internal pure returns (DynamicBuffer memory result) { - pBytes10(result, data); - } - - /// @dev Shorthand for `pBytes11(p(), data)`. - function pBytes11(bytes11 data) internal pure returns (DynamicBuffer memory result) { - pBytes11(result, data); - } - - /// @dev Shorthand for `pBytes12(p(), data)`. - function pBytes12(bytes12 data) internal pure returns (DynamicBuffer memory result) { - pBytes12(result, data); - } - - /// @dev Shorthand for `pBytes13(p(), data)`. - function pBytes13(bytes13 data) internal pure returns (DynamicBuffer memory result) { - pBytes13(result, data); - } - - /// @dev Shorthand for `pBytes14(p(), data)`. - function pBytes14(bytes14 data) internal pure returns (DynamicBuffer memory result) { - pBytes14(result, data); - } - - /// @dev Shorthand for `pBytes15(p(), data)`. - function pBytes15(bytes15 data) internal pure returns (DynamicBuffer memory result) { - pBytes15(result, data); - } - - /// @dev Shorthand for `pBytes16(p(), data)`. - function pBytes16(bytes16 data) internal pure returns (DynamicBuffer memory result) { - pBytes16(result, data); - } - - /// @dev Shorthand for `pBytes17(p(), data)`. - function pBytes17(bytes17 data) internal pure returns (DynamicBuffer memory result) { - pBytes17(result, data); - } - - /// @dev Shorthand for `pBytes18(p(), data)`. - function pBytes18(bytes18 data) internal pure returns (DynamicBuffer memory result) { - pBytes18(result, data); - } - - /// @dev Shorthand for `pBytes19(p(), data)`. - function pBytes19(bytes19 data) internal pure returns (DynamicBuffer memory result) { - pBytes19(result, data); - } - - /// @dev Shorthand for `pBytes20(p(), data)`. - function pBytes20(bytes20 data) internal pure returns (DynamicBuffer memory result) { - pBytes20(result, data); - } - - /// @dev Shorthand for `pBytes21(p(), data)`. - function pBytes21(bytes21 data) internal pure returns (DynamicBuffer memory result) { - pBytes21(result, data); - } - - /// @dev Shorthand for `pBytes22(p(), data)`. - function pBytes22(bytes22 data) internal pure returns (DynamicBuffer memory result) { - pBytes22(result, data); - } - - /// @dev Shorthand for `pBytes23(p(), data)`. - function pBytes23(bytes23 data) internal pure returns (DynamicBuffer memory result) { - pBytes23(result, data); - } - - /// @dev Shorthand for `pBytes24(p(), data)`. - function pBytes24(bytes24 data) internal pure returns (DynamicBuffer memory result) { - pBytes24(result, data); - } - - /// @dev Shorthand for `pBytes25(p(), data)`. - function pBytes25(bytes25 data) internal pure returns (DynamicBuffer memory result) { - pBytes25(result, data); - } - - /// @dev Shorthand for `pBytes26(p(), data)`. - function pBytes26(bytes26 data) internal pure returns (DynamicBuffer memory result) { - pBytes26(result, data); - } - - /// @dev Shorthand for `pBytes27(p(), data)`. - function pBytes27(bytes27 data) internal pure returns (DynamicBuffer memory result) { - pBytes27(result, data); - } - - /// @dev Shorthand for `pBytes28(p(), data)`. - function pBytes28(bytes28 data) internal pure returns (DynamicBuffer memory result) { - pBytes28(result, data); - } - - /// @dev Shorthand for `pBytes29(p(), data)`. - function pBytes29(bytes29 data) internal pure returns (DynamicBuffer memory result) { - pBytes29(result, data); - } - - /// @dev Shorthand for `pBytes30(p(), data)`. - function pBytes30(bytes30 data) internal pure returns (DynamicBuffer memory result) { - pBytes30(result, data); - } - - /// @dev Shorthand for `pBytes31(p(), data)`. - function pBytes31(bytes31 data) internal pure returns (DynamicBuffer memory result) { - pBytes31(result, data); - } - - /// @dev Shorthand for `pBytes32(p(), data)`. - function pBytes32(bytes32 data) internal pure returns (DynamicBuffer memory result) { - pBytes32(result, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper for deallocating an automatically allocated `buffer` pointer. - function _deallocate(DynamicBuffer memory result) private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Deallocate, as we have already allocated. - } - } - - /// @dev Returns a temporary bytes string of length `n` for `data`. - function _single(uint256 data, uint256 n) private pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := 0x00 - mstore(n, data) - mstore(result, n) - } - } - - /// @dev Returns a temporary bytes string of length `n` for `data`. - function _single(bytes32 data, uint256 n) private pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := 0x00 - mstore(0x20, data) - mstore(result, n) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ECDSA.sol b/grouperBot/lib/solady/src/utils/ECDSA.sol deleted file mode 100644 index c2ba9b1..0000000 --- a/grouperBot/lib/solady/src/utils/ECDSA.sol +++ /dev/null @@ -1,442 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Gas optimized ECDSA wrapper. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) -/// -/// @dev Note: -/// - The recovery functions use the ecrecover precompile (0x1). -/// - As of Solady version 0.0.68, the `recover` variants will revert upon recovery failure. -/// This is for more safety by default. -/// Use the `tryRecover` variants if you need to get the zero address back -/// upon recovery failure instead. -/// - As of Solady version 0.0.134, all `bytes signature` variants accept both -/// regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures. -/// See: https://eips.ethereum.org/EIPS/eip-2098 -/// This is for calldata efficiency on smart accounts prevalent on L2s. -/// -/// WARNING! Do NOT directly use signatures as unique identifiers: -/// - The recovery operations do NOT check if a signature is non-malleable. -/// - Use a nonce in the digest to prevent replay attacks on the same contract. -/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts. -/// EIP-712 also enables readable signing of typed data for better user safety. -/// - If you need a unique hash from a signature, please use the `canonicalHash` functions. -library ECDSA { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The order of the secp256k1 elliptic curve. - uint256 internal constant N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141; - - /// @dev `N/2 + 1`. Used for checking the malleability of the signature. - uint256 private constant _HALF_N_PLUS_1 = - 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The signature is invalid. - error InvalidSignature(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RECOVERY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. - function recover(bytes32 hash, bytes memory signature) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - for { let m := mload(0x40) } 1 { - mstore(0x00, 0x8baa579f) // `InvalidSignature()`. - revert(0x1c, 0x04) - } { - switch mload(signature) - case 64 { - let vs := mload(add(signature, 0x40)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. - mstore(0x60, mload(add(signature, 0x40))) // `s`. - } - default { continue } - mstore(0x00, hash) - mstore(0x40, mload(add(signature, 0x20))) // `r`. - result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - if returndatasize() { break } - } - } - } - - /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. - function recoverCalldata(bytes32 hash, bytes calldata signature) - internal - view - returns (address result) - { - /// @solidity memory-safe-assembly - assembly { - for { let m := mload(0x40) } 1 { - mstore(0x00, 0x8baa579f) // `InvalidSignature()`. - revert(0x1c, 0x04) - } { - switch signature.length - case 64 { - let vs := calldataload(add(signature.offset, 0x20)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, calldataload(signature.offset)) // `r`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. - calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`. - } - default { continue } - mstore(0x00, hash) - result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - if returndatasize() { break } - } - } - } - - /// @dev Recovers the signer's address from a message digest `hash`, - /// and the EIP-2098 short form signature defined by `r` and `vs`. - function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, hash) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, r) - mstore(0x60, shr(1, shl(1, vs))) // `s`. - result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - if iszero(returndatasize()) { - mstore(0x00, 0x8baa579f) // `InvalidSignature()`. - revert(0x1c, 0x04) - } - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Recovers the signer's address from a message digest `hash`, - /// and the signature defined by `v`, `r`, `s`. - function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) - internal - view - returns (address result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, hash) - mstore(0x20, and(v, 0xff)) - mstore(0x40, r) - mstore(0x60, s) - result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - if iszero(returndatasize()) { - mstore(0x00, 0x8baa579f) // `InvalidSignature()`. - revert(0x1c, 0x04) - } - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* TRY-RECOVER OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // WARNING! - // These functions will NOT revert upon recovery failure. - // Instead, they will return the zero address upon recovery failure. - // It is critical that the returned address is NEVER compared against - // a zero address (e.g. an uninitialized address variable). - - /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. - function tryRecover(bytes32 hash, bytes memory signature) - internal - view - returns (address result) - { - /// @solidity memory-safe-assembly - assembly { - for { let m := mload(0x40) } 1 {} { - switch mload(signature) - case 64 { - let vs := mload(add(signature, 0x40)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. - mstore(0x60, mload(add(signature, 0x40))) // `s`. - } - default { break } - mstore(0x00, hash) - mstore(0x40, mload(add(signature, 0x20))) // `r`. - pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) - mstore(0x60, 0) // Restore the zero slot. - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - result := mload(xor(0x60, returndatasize())) - mstore(0x40, m) // Restore the free memory pointer. - break - } - } - } - - /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. - function tryRecoverCalldata(bytes32 hash, bytes calldata signature) - internal - view - returns (address result) - { - /// @solidity memory-safe-assembly - assembly { - for { let m := mload(0x40) } 1 {} { - switch signature.length - case 64 { - let vs := calldataload(add(signature.offset, 0x20)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, calldataload(signature.offset)) // `r`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. - calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`. - } - default { break } - mstore(0x00, hash) - pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) - mstore(0x60, 0) // Restore the zero slot. - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - result := mload(xor(0x60, returndatasize())) - mstore(0x40, m) // Restore the free memory pointer. - break - } - } - } - - /// @dev Recovers the signer's address from a message digest `hash`, - /// and the EIP-2098 short form signature defined by `r` and `vs`. - function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) - internal - view - returns (address result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, hash) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, r) - mstore(0x60, shr(1, shl(1, vs))) // `s`. - pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) - mstore(0x60, 0) // Restore the zero slot. - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - result := mload(xor(0x60, returndatasize())) - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Recovers the signer's address from a message digest `hash`, - /// and the signature defined by `v`, `r`, `s`. - function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) - internal - view - returns (address result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, hash) - mstore(0x20, and(v, 0xff)) - mstore(0x40, r) - mstore(0x60, s) - pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) - mstore(0x60, 0) // Restore the zero slot. - // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. - result := mload(xor(0x60, returndatasize())) - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HASHING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns an Ethereum Signed Message, created from a `hash`. - /// This produces a hash corresponding to the one signed with the - /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign) - /// JSON-RPC method as part of EIP-191. - function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, hash) // Store into scratch space for keccak256. - mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes. - result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`. - } - } - - /// @dev Returns an Ethereum Signed Message, created from `s`. - /// This produces a hash corresponding to the one signed with the - /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign) - /// JSON-RPC method as part of EIP-191. - /// Note: Supports lengths of `s` up to 999999 bytes. - function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let sLength := mload(s) - let o := 0x20 - mstore(o, "\x19Ethereum Signed Message:\n") // 26 bytes, zero-right-padded. - mstore(0x00, 0x00) - // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`. - for { let temp := sLength } 1 {} { - o := sub(o, 1) - mstore8(o, add(48, mod(temp, 10))) - temp := div(temp, 10) - if iszero(temp) { break } - } - let n := sub(0x3a, o) // Header length: `26 + 32 - o`. - // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20)) - mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header. - result := keccak256(add(s, sub(0x20, n)), add(n, sLength)) - mstore(s, sLength) // Restore the length. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CANONICAL HASH FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // The following functions return the hash of the signature in its canonicalized format, - // which is the 65-byte `abi.encodePacked(r, s, uint8(v))`, where `v` is either 27 or 28. - // If `s` is greater than `N / 2` then it will be converted to `N - s` - // and the `v` value will be flipped. - // If the signature has an invalid length, or if `v` is invalid, - // a uniquely corrupt hash will be returned. - // These functions are useful for "poor-mans-VRF". - - /// @dev Returns the canonical hash of `signature`. - function canonicalHash(bytes memory signature) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let l := mload(signature) - for {} 1 {} { - mstore(0x00, mload(add(signature, 0x20))) // `r`. - let s := mload(add(signature, 0x40)) - let v := mload(add(signature, 0x41)) - if eq(l, 64) { - v := add(shr(255, s), 27) - s := shr(1, shl(1, s)) - } - if iszero(lt(s, _HALF_N_PLUS_1)) { - v := xor(v, 7) - s := sub(N, s) - } - mstore(0x21, v) - mstore(0x20, s) - result := keccak256(0x00, 0x41) - mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. - break - } - - // If the length is neither 64 nor 65, return a uniquely corrupted hash. - if iszero(lt(sub(l, 64), 2)) { - // `bytes4(keccak256("InvalidSignatureLength"))`. - result := xor(keccak256(add(signature, 0x20), l), 0xd62f1ab2) - } - } - } - - /// @dev Returns the canonical hash of `signature`. - function canonicalHashCalldata(bytes calldata signature) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - mstore(0x00, calldataload(signature.offset)) // `r`. - let s := calldataload(add(signature.offset, 0x20)) - let v := calldataload(add(signature.offset, 0x21)) - if eq(signature.length, 64) { - v := add(shr(255, s), 27) - s := shr(1, shl(1, s)) - } - if iszero(lt(s, _HALF_N_PLUS_1)) { - v := xor(v, 7) - s := sub(N, s) - } - mstore(0x21, v) - mstore(0x20, s) - result := keccak256(0x00, 0x41) - mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. - break - } - // If the length is neither 64 nor 65, return a uniquely corrupted hash. - if iszero(lt(sub(signature.length, 64), 2)) { - calldatacopy(mload(0x40), signature.offset, signature.length) - // `bytes4(keccak256("InvalidSignatureLength"))`. - result := xor(keccak256(mload(0x40), signature.length), 0xd62f1ab2) - } - } - } - - /// @dev Returns the canonical hash of `signature`. - function canonicalHash(bytes32 r, bytes32 vs) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) // `r`. - let v := add(shr(255, vs), 27) - let s := shr(1, shl(1, vs)) - mstore(0x21, v) - mstore(0x20, s) - result := keccak256(0x00, 0x41) - mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the canonical hash of `signature`. - function canonicalHash(uint8 v, bytes32 r, bytes32 s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) // `r`. - if iszero(lt(s, _HALF_N_PLUS_1)) { - v := xor(v, 7) - s := sub(N, s) - } - mstore(0x21, v) - mstore(0x20, s) - result := keccak256(0x00, 0x41) - mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EMPTY CALLDATA HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns an empty calldata bytes. - function emptySignature() internal pure returns (bytes calldata signature) { - /// @solidity memory-safe-assembly - assembly { - signature.length := 0 - } - } -} diff --git a/grouperBot/lib/solady/src/utils/EIP712.sol b/grouperBot/lib/solady/src/utils/EIP712.sol deleted file mode 100644 index 9277c29..0000000 --- a/grouperBot/lib/solady/src/utils/EIP712.sol +++ /dev/null @@ -1,300 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Contract for EIP-712 typed structured data hashing and signing. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EIP712.sol) -/// @author Modified from Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/EIP712.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol) -/// -/// @dev Note, this implementation: -/// - Uses `address(this)` for the `verifyingContract` field. -/// - Does NOT use the optional EIP-712 salt. -/// - Does NOT use any EIP-712 extensions. -/// This is for simplicity and to save gas. -/// If you need to customize, please fork / modify accordingly. -abstract contract EIP712 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS AND IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. - bytes32 internal constant _DOMAIN_TYPEHASH = - 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; - - /// @dev `keccak256("EIP712Domain(string name,string version,address verifyingContract)")`. - /// This is only used in `_hashTypedDataSansChainId`. - bytes32 internal constant _DOMAIN_TYPEHASH_SANS_CHAIN_ID = - 0x91ab3d17e3a50a9d89e63fd30b92be7f5336b03b287bb946787a83a9d62a2766; - - /// @dev `keccak256("EIP712Domain(string name,string version)")`. - /// This is only used in `_hashTypedDataSansChainIdAndVerifyingContract`. - bytes32 internal constant _DOMAIN_TYPEHASH_SANS_CHAIN_ID_AND_VERIFYING_CONTRACT = - 0xb03948446334eb9b2196d5eb166f69b9d49403eb4a12f36de8d3f9f3cb8e15c3; - - /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId)")`. - /// This is only used in `_hashTypedDataSansVerifyingContract`. - bytes32 internal constant _DOMAIN_TYPEHASH_SANS_VERIFYING_CONTRACT = - 0xc2f8787176b8ac6bf7215b4adcc1e069bf4ab82d9ab1df05a57a91d425935b6e; - - uint256 private immutable _cachedThis; - uint256 private immutable _cachedChainId; - bytes32 private immutable _cachedNameHash; - bytes32 private immutable _cachedVersionHash; - bytes32 private immutable _cachedDomainSeparator; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Cache the hashes for cheaper runtime gas costs. - /// In the case of upgradeable contracts (i.e. proxies), - /// or if the chain id changes due to a hard fork, - /// the domain separator will be seamlessly calculated on-the-fly. - constructor() { - _cachedThis = uint256(uint160(address(this))); - _cachedChainId = block.chainid; - - string memory name; - string memory version; - if (!_domainNameAndVersionMayChange()) (name, version) = _domainNameAndVersion(); - bytes32 nameHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(name)); - bytes32 versionHash = - _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(version)); - _cachedNameHash = nameHash; - _cachedVersionHash = versionHash; - - bytes32 separator; - if (!_domainNameAndVersionMayChange()) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Load the free memory pointer. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), nameHash) - mstore(add(m, 0x40), versionHash) - mstore(add(m, 0x60), chainid()) - mstore(add(m, 0x80), address()) - separator := keccak256(m, 0xa0) - } - } - _cachedDomainSeparator = separator; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* FUNCTIONS TO OVERRIDE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Please override this function to return the domain name and version. - /// ``` - /// function _domainNameAndVersion() - /// internal - /// pure - /// virtual - /// returns (string memory name, string memory version) - /// { - /// name = "Solady"; - /// version = "1"; - /// } - /// ``` - /// - /// Note: If the returned result may change after the contract has been deployed, - /// you must override `_domainNameAndVersionMayChange()` to return true. - function _domainNameAndVersion() - internal - view - virtual - returns (string memory name, string memory version); - - /// @dev Returns if `_domainNameAndVersion()` may change - /// after the contract has been deployed (i.e. after the constructor). - /// Default: false. - function _domainNameAndVersionMayChange() internal pure virtual returns (bool result) {} - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HASHING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the EIP-712 domain separator. - function _domainSeparator() internal view virtual returns (bytes32 separator) { - if (_domainNameAndVersionMayChange()) { - separator = _buildDomainSeparator(); - } else { - separator = _cachedDomainSeparator; - if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator(); - } - } - - /// @dev Returns the hash of the fully encoded EIP-712 message for this domain, - /// given `structHash`, as defined in - /// https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct. - /// - /// The hash can be used together with {ECDSA-recover} to obtain the signer of a message: - /// ``` - /// bytes32 digest = _hashTypedData(keccak256(abi.encode( - /// keccak256("Mail(address to,string contents)"), - /// mailTo, - /// keccak256(bytes(mailContents)) - /// ))); - /// address signer = ECDSA.recover(digest, signature); - /// ``` - function _hashTypedData(bytes32 structHash) internal view virtual returns (bytes32 digest) { - // We will use `digest` to store the domain separator to save a bit of gas. - if (_domainNameAndVersionMayChange()) { - digest = _buildDomainSeparator(); - } else { - digest = _cachedDomainSeparator; - if (_cachedDomainSeparatorInvalidated()) digest = _buildDomainSeparator(); - } - /// @solidity memory-safe-assembly - assembly { - // Compute the digest. - mstore(0x00, 0x1901000000000000) // Store "\x19\x01". - mstore(0x1a, digest) // Store the domain separator. - mstore(0x3a, structHash) // Store the struct hash. - digest := keccak256(0x18, 0x42) - // Restore the part of the free memory slot that was overwritten. - mstore(0x3a, 0) - } - } - - /// @dev Variant of `_hashTypedData` that excludes the chain ID. - /// Included for the niche use case of cross-chain workflows. - function _hashTypedDataSansChainId(bytes32 structHash) - internal - view - virtual - returns (bytes32 digest) - { - (string memory name, string memory version) = _domainNameAndVersion(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Load the free memory pointer. - mstore(0x00, _DOMAIN_TYPEHASH_SANS_CHAIN_ID) - mstore(0x20, keccak256(add(name, 0x20), mload(name))) - mstore(0x40, keccak256(add(version, 0x20), mload(version))) - mstore(0x60, address()) - // Compute the digest. - mstore(0x20, keccak256(0x00, 0x80)) // Store the domain separator. - mstore(0x00, 0x1901) // Store "\x19\x01". - mstore(0x40, structHash) // Store the struct hash. - digest := keccak256(0x1e, 0x42) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /// @dev Variant of `_hashTypedData` that excludes the chain ID and verifying contract. - /// Included for the niche use case of cross-chain and multi-verifier workflows. - function _hashTypedDataSansChainIdAndVerifyingContract(bytes32 structHash) - internal - view - virtual - returns (bytes32 digest) - { - (string memory name, string memory version) = _domainNameAndVersion(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Load the free memory pointer. - mstore(0x00, _DOMAIN_TYPEHASH_SANS_CHAIN_ID_AND_VERIFYING_CONTRACT) - mstore(0x20, keccak256(add(name, 0x20), mload(name))) - mstore(0x40, keccak256(add(version, 0x20), mload(version))) - // Compute the digest. - mstore(0x20, keccak256(0x00, 0x60)) // Store the domain separator. - mstore(0x00, 0x1901) // Store "\x19\x01". - mstore(0x40, structHash) // Store the struct hash. - digest := keccak256(0x1e, 0x42) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /// @dev Variant of `_hashTypedData` that excludes the chain ID and verifying contract. - /// Included for the niche use case of multi-verifier workflows. - function _hashTypedDataSansVerifyingContract(bytes32 structHash) - internal - view - virtual - returns (bytes32 digest) - { - (string memory name, string memory version) = _domainNameAndVersion(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Load the free memory pointer. - mstore(0x00, _DOMAIN_TYPEHASH_SANS_VERIFYING_CONTRACT) - mstore(0x20, keccak256(add(name, 0x20), mload(name))) - mstore(0x40, keccak256(add(version, 0x20), mload(version))) - mstore(0x60, chainid()) - // Compute the digest. - mstore(0x20, keccak256(0x00, 0x80)) // Store the domain separator. - mstore(0x00, 0x1901) // Store "\x19\x01". - mstore(0x40, structHash) // Store the struct hash. - digest := keccak256(0x1e, 0x42) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EIP-5267 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev See: https://eips.ethereum.org/EIPS/eip-5267 - function eip712Domain() - public - view - virtual - returns ( - bytes1 fields, - string memory name, - string memory version, - uint256 chainId, - address verifyingContract, - bytes32 salt, - uint256[] memory extensions - ) - { - fields = hex"0f"; // `0b01111`. - (name, version) = _domainNameAndVersion(); - chainId = block.chainid; - verifyingContract = address(this); - salt = salt; // `bytes32(0)`. - extensions = extensions; // `new uint256[](0)`. - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the EIP-712 domain separator. - function _buildDomainSeparator() private view returns (bytes32 separator) { - // We will use `separator` to store the name hash to save a bit of gas. - bytes32 versionHash; - if (_domainNameAndVersionMayChange()) { - (string memory name, string memory version) = _domainNameAndVersion(); - separator = keccak256(bytes(name)); - versionHash = keccak256(bytes(version)); - } else { - separator = _cachedNameHash; - versionHash = _cachedVersionHash; - } - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Load the free memory pointer. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), separator) // Name hash. - mstore(add(m, 0x40), versionHash) - mstore(add(m, 0x60), chainid()) - mstore(add(m, 0x80), address()) - separator := keccak256(m, 0xa0) - } - } - - /// @dev Returns if the cached domain separator has been invalidated. - function _cachedDomainSeparatorInvalidated() private view returns (bool result) { - uint256 cachedChainId = _cachedChainId; - uint256 cachedThis = _cachedThis; - /// @solidity memory-safe-assembly - assembly { - result := iszero(and(eq(chainid(), cachedChainId), eq(address(), cachedThis))) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ERC1967Factory.sol b/grouperBot/lib/solady/src/utils/ERC1967Factory.sol deleted file mode 100644 index c57022f..0000000 --- a/grouperBot/lib/solady/src/utils/ERC1967Factory.sol +++ /dev/null @@ -1,418 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Factory for deploying and managing ERC1967 proxy contracts. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ERC1967Factory.sol) -/// @author jtriley-eth (https://github.com/jtriley-eth/minimum-viable-proxy) -contract ERC1967Factory { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The caller is not authorized to call the function. - error Unauthorized(); - - /// @dev The proxy deployment failed. - error DeploymentFailed(); - - /// @dev The upgrade failed. - error UpgradeFailed(); - - /// @dev The salt does not start with the caller. - error SaltDoesNotStartWithCaller(); - - /// @dev `bytes4(keccak256(bytes("Unauthorized()")))`. - uint256 internal constant _UNAUTHORIZED_ERROR_SELECTOR = 0x82b42900; - - /// @dev `bytes4(keccak256(bytes("DeploymentFailed()")))`. - uint256 internal constant _DEPLOYMENT_FAILED_ERROR_SELECTOR = 0x30116425; - - /// @dev `bytes4(keccak256(bytes("UpgradeFailed()")))`. - uint256 internal constant _UPGRADE_FAILED_ERROR_SELECTOR = 0x55299b49; - - /// @dev `bytes4(keccak256(bytes("SaltDoesNotStartWithCaller()")))`. - uint256 internal constant _SALT_DOES_NOT_START_WITH_CALLER_ERROR_SELECTOR = 0x2f634836; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The admin of a proxy contract has been changed. - event AdminChanged(address indexed proxy, address indexed admin); - - /// @dev The implementation for a proxy has been upgraded. - event Upgraded(address indexed proxy, address indexed implementation); - - /// @dev A proxy has been deployed. - event Deployed(address indexed proxy, address indexed implementation, address indexed admin); - - /// @dev `keccak256(bytes("AdminChanged(address,address)"))`. - uint256 internal constant _ADMIN_CHANGED_EVENT_SIGNATURE = - 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f; - - /// @dev `keccak256(bytes("Upgraded(address,address)"))`. - uint256 internal constant _UPGRADED_EVENT_SIGNATURE = - 0x5d611f318680d00598bb735d61bacf0c514c6b50e1e5ad30040a4df2b12791c7; - - /// @dev `keccak256(bytes("Deployed(address,address,address)"))`. - uint256 internal constant _DEPLOYED_EVENT_SIGNATURE = - 0xc95935a66d15e0da5e412aca0ad27ae891d20b2fb91cf3994b6a3bf2b8178082; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // The admin slot for a `proxy` is `shl(96, proxy)`. - - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. - uint256 internal constant _IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ADMIN FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the admin of the proxy. - function adminOf(address proxy) public view returns (address admin) { - assembly { - admin := sload(shl(96, proxy)) - } - } - - /// @dev Sets the admin of the proxy. - /// The caller of this function must be the admin of the proxy on this factory. - function changeAdmin(address proxy, address admin) public { - assembly { - // Check if the caller is the admin of the proxy. - if iszero(eq(sload(shl(96, proxy)), caller())) { - mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR) - revert(0x1c, 0x04) - } - // Store the admin for the proxy. - sstore(shl(96, proxy), admin) - // Emit the {AdminChanged} event. - log3(0, 0, _ADMIN_CHANGED_EVENT_SIGNATURE, proxy, admin) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UPGRADE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Upgrades the proxy to point to `implementation`. - /// The caller of this function must be the admin of the proxy on this factory. - function upgrade(address proxy, address implementation) public payable { - upgradeAndCall(proxy, implementation, _emptyData()); - } - - /// @dev Upgrades the proxy to point to `implementation`. - /// Then, calls the proxy with abi encoded `data`. - /// The caller of this function must be the admin of the proxy on this factory. - function upgradeAndCall(address proxy, address implementation, bytes calldata data) - public - payable - { - assembly { - // Check if the caller is the admin of the proxy. - if iszero(eq(sload(shl(96, proxy)), caller())) { - mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR) - revert(0x1c, 0x04) - } - // Set up the calldata to upgrade the proxy. - let m := mload(0x40) - mstore(m, implementation) - mstore(add(m, 0x20), _IMPLEMENTATION_SLOT) - calldatacopy(add(m, 0x40), data.offset, data.length) - // Try upgrading the proxy and revert upon failure. - if iszero(call(gas(), proxy, callvalue(), m, add(0x40, data.length), 0x00, 0x00)) { - // Revert with the `UpgradeFailed` selector if there is no error returndata. - if iszero(returndatasize()) { - mstore(0x00, _UPGRADE_FAILED_ERROR_SELECTOR) - revert(0x1c, 0x04) - } - // Otherwise, bubble up the returned error. - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - // Emit the {Upgraded} event. - log3(0, 0, _UPGRADED_EVENT_SIGNATURE, proxy, implementation) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DEPLOY FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a proxy for `implementation`, with `admin`, - /// and returns its address. - /// The value passed into this function will be forwarded to the proxy. - function deploy(address implementation, address admin) public payable returns (address proxy) { - proxy = deployAndCall(implementation, admin, _emptyData()); - } - - /// @dev Deploys a proxy for `implementation`, with `admin`, - /// and returns its address. - /// The value passed into this function will be forwarded to the proxy. - /// Then, calls the proxy with abi encoded `data`. - function deployAndCall(address implementation, address admin, bytes calldata data) - public - payable - returns (address proxy) - { - proxy = _deploy(implementation, admin, bytes32(0), false, data); - } - - /// @dev Deploys a proxy for `implementation`, with `admin`, `salt`, - /// and returns its deterministic address. - /// The value passed into this function will be forwarded to the proxy. - function deployDeterministic(address implementation, address admin, bytes32 salt) - public - payable - returns (address proxy) - { - proxy = deployDeterministicAndCall(implementation, admin, salt, _emptyData()); - } - - /// @dev Deploys a proxy for `implementation`, with `admin`, `salt`, - /// and returns its deterministic address. - /// The value passed into this function will be forwarded to the proxy. - /// Then, calls the proxy with abi encoded `data`. - function deployDeterministicAndCall( - address implementation, - address admin, - bytes32 salt, - bytes calldata data - ) public payable returns (address proxy) { - assembly { - // If the salt does not start with the zero address or the caller. - if iszero(or(iszero(shr(96, salt)), eq(caller(), shr(96, salt)))) { - mstore(0x00, _SALT_DOES_NOT_START_WITH_CALLER_ERROR_SELECTOR) - revert(0x1c, 0x04) - } - } - proxy = _deploy(implementation, admin, salt, true, data); - } - - /// @dev Deploys the proxy, with optionality to deploy deterministically with a `salt`. - function _deploy( - address implementation, - address admin, - bytes32 salt, - bool useSalt, - bytes calldata data - ) internal returns (address proxy) { - bytes32 m = _initCode(); - assembly { - // Create the proxy. - switch useSalt - case 0 { proxy := create(0, add(m, 0x13), 0x88) } - default { proxy := create2(0, add(m, 0x13), 0x88, salt) } - // Revert if the creation fails. - if iszero(proxy) { - mstore(0x00, _DEPLOYMENT_FAILED_ERROR_SELECTOR) - revert(0x1c, 0x04) - } - - // Set up the calldata to set the implementation of the proxy. - mstore(m, implementation) - mstore(add(m, 0x20), _IMPLEMENTATION_SLOT) - calldatacopy(add(m, 0x40), data.offset, data.length) - // Try setting the implementation on the proxy and revert upon failure. - if iszero(call(gas(), proxy, callvalue(), m, add(0x40, data.length), 0x00, 0x00)) { - // Revert with the `DeploymentFailed` selector if there is no error returndata. - if iszero(returndatasize()) { - mstore(0x00, _DEPLOYMENT_FAILED_ERROR_SELECTOR) - revert(0x1c, 0x04) - } - // Otherwise, bubble up the returned error. - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - - // Store the admin for the proxy. - sstore(shl(96, proxy), admin) - - // Emit the {Deployed} event. - log4(0, 0, _DEPLOYED_EVENT_SIGNATURE, proxy, implementation, admin) - } - } - - /// @dev Returns the address of the proxy deployed with `salt`. - function predictDeterministicAddress(bytes32 salt) public view returns (address predicted) { - bytes32 hash = initCodeHash(); - assembly { - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, hash) - mstore(0x01, shl(96, address())) - mstore(0x15, salt) - // Note: `predicted` has dirty upper 96 bits. We won't clean it here - // as it will be automatically cleaned when it is copied into the returndata. - // Please clean as needed if used in other inline assembly blocks. - predicted := keccak256(0x00, 0x55) - // Restore the part of the free memory pointer that has been overwritten. - mstore(0x35, 0) - } - } - - /// @dev Returns the initialization code hash of the proxy. - /// Used for mining vanity addresses with create2crunch. - function initCodeHash() public view returns (bytes32 result) { - bytes32 m = _initCode(); - assembly { - result := keccak256(add(m, 0x13), 0x88) - } - } - - /// @dev Returns a pointer to the initialization code of a proxy created via this factory. - function _initCode() internal view returns (bytes32 m) { - assembly { - /** - * -------------------------------------------------------------------------------------+ - * CREATION (9 bytes) | - * -------------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * -------------------------------------------------------------------------------------| - * 60 runSize | PUSH1 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * -------------------------------------------------------------------------------------| - * RUNTIME (127 bytes) | - * -------------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * -------------------------------------------------------------------------------------| - * | - * ::: keep some values in stack :::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | | - * 3d | RETURNDATASIZE | 0 0 | | - * | - * ::: check if caller is factory ::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 33 | CALLER | c 0 0 | | - * 73 factory | PUSH20 factory | f c 0 0 | | - * 14 | EQ | isf 0 0 | | - * 60 0x57 | PUSH1 0x57 | dest isf 0 0 | | - * 57 | JUMPI | 0 0 | | - * | - * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds 0 0 | | - * 3d | RETURNDATASIZE | 0 cds 0 0 | | - * 3d | RETURNDATASIZE | 0 0 cds 0 0 | | - * 37 | CALLDATACOPY | 0 0 | [0..calldatasize): calldata | - * | - * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds 0 0 | [0..calldatasize): calldata | - * 3d | RETURNDATASIZE | 0 cds 0 0 | [0..calldatasize): calldata | - * 7f slot | PUSH32 slot | s 0 cds 0 0 | [0..calldatasize): calldata | - * 54 | SLOAD | i 0 cds 0 0 | [0..calldatasize): calldata | - * 5a | GAS | g i 0 cds 0 0 | [0..calldatasize): calldata | - * f4 | DELEGATECALL | succ | [0..calldatasize): calldata | - * | - * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds succ | [0..calldatasize): calldata | - * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..calldatasize): calldata | - * 80 | DUP1 | 0 0 rds succ | [0..calldatasize): calldata | - * 3e | RETURNDATACOPY | succ | [0..returndatasize): returndata | - * | - * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::::::: | - * 60 0x52 | PUSH1 0x52 | dest succ | [0..returndatasize): returndata | - * 57 | JUMPI | | [0..returndatasize): returndata | - * | - * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * fd | REVERT | | [0..returndatasize): returndata | - * | - * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | | [0..returndatasize): returndata | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * f3 | RETURN | | [0..returndatasize): returndata | - * | - * ::: set new implementation (caller is factory) ::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | 0 0 | | - * 3d | RETURNDATASIZE | 0 0 0 | | - * 35 | CALLDATALOAD | impl 0 0 | | - * 60 0x20 | PUSH1 0x20 | w impl 0 0 | | - * 35 | CALLDATALOAD | slot impl 0 0 | | - * 55 | SSTORE | 0 0 | | - * | - * ::: no extra calldata, return :::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 60 0x40 | PUSH1 0x40 | 2w 0 0 | | - * 80 | DUP1 | 2w 2w 0 0 | | - * 36 | CALLDATASIZE | cds 2w 2w 0 0 | | - * 11 | GT | gt 2w 0 0 | | - * 15 | ISZERO | lte 2w 0 0 | | - * 60 0x52 | PUSH1 0x52 | dest lte 2w 0 0 | | - * 57 | JUMPI | 2w 0 0 | | - * | - * ::: copy extra calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds 2w 0 0 | | - * 03 | SUB | t 0 0 | | - * 80 | DUP1 | t t 0 0 | | - * 60 0x40 | PUSH1 0x40 | 2w t t 0 0 | | - * 3d | RETURNDATASIZE | 0 2w t t 0 0 | | - * 37 | CALLDATACOPY | t 0 0 | [0..t): extra calldata | - * | - * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 t 0 0 | [0..t): extra calldata | - * 3d | RETURNDATASIZE | 0 0 t 0 0 | [0..t): extra calldata | - * 35 | CALLDATALOAD | i 0 t 0 0 | [0..t): extra calldata | - * 5a | GAS | g i 0 t 0 0 | [0..t): extra calldata | - * f4 | DELEGATECALL | succ | [0..t): extra calldata | - * | - * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds succ | [0..t): extra calldata | - * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..t): extra calldata | - * 80 | DUP1 | 0 0 rds succ | [0..t): extra calldata | - * 3e | RETURNDATACOPY | succ | [0..returndatasize): returndata | - * | - * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::::::: | - * 60 0x52 | PUSH1 0x52 | dest succ | [0..returndatasize): returndata | - * 57 | JUMPI | | [0..returndatasize): returndata | - * | - * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * fd | REVERT | | [0..returndatasize): returndata | - * -------------------------------------------------------------------------------------+ - */ - m := mload(0x40) - // forgefmt: disable-start - switch shr(112, address()) - case 0 { - // If the factory's address has six or more leading zero bytes. - mstore(add(m, 0x75), 0x604c573d6000fd) // 7 - mstore(add(m, 0x6e), 0x3d3560203555604080361115604c5736038060403d373d3d355af43d6000803e) // 32 - mstore(add(m, 0x4e), 0x3735a920a3ca505d382bbc545af43d6000803e604c573d6000fd5b3d6000f35b) // 32 - mstore(add(m, 0x2e), 0x14605157363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc) // 32 - mstore(add(m, 0x0e), address()) // 14 - mstore(m, 0x60793d8160093d39f33d3d336d) // 9 + 4 - } - default { - mstore(add(m, 0x7b), 0x6052573d6000fd) // 7 - mstore(add(m, 0x74), 0x3d356020355560408036111560525736038060403d373d3d355af43d6000803e) // 32 - mstore(add(m, 0x54), 0x3735a920a3ca505d382bbc545af43d6000803e6052573d6000fd5b3d6000f35b) // 32 - mstore(add(m, 0x34), 0x14605757363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc) // 32 - mstore(add(m, 0x14), address()) // 20 - mstore(m, 0x607f3d8160093d39f33d3d3373) // 9 + 4 - } - // forgefmt: disable-end - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper function to return an empty bytes calldata. - function _emptyData() internal pure returns (bytes calldata data) { - assembly { - data.length := 0 - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ERC1967FactoryConstants.sol b/grouperBot/lib/solady/src/utils/ERC1967FactoryConstants.sol deleted file mode 100644 index a54be22..0000000 --- a/grouperBot/lib/solady/src/utils/ERC1967FactoryConstants.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice The address and bytecode of the canonical ERC1967Factory deployment. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ERC1967FactoryLib.sol) -/// @author jtriley-eth (https://github.com/jtriley-eth/minimum-viable-proxy) -/// -/// @dev The canonical ERC1967Factory is deployed permissionlessly via -/// 0age's ImmutableCreate2Factory located at 0x0000000000FFe8B47B3e2130213B802212439497. -/// -/// `ADDRESS = immutableCreate2Factory.safeCreate2(SALT, INITCODE)` -/// -/// If the canonical ERC1967Factory has not been deployed on your EVM chain of choice, -/// please feel free to deploy via 0age's ImmutableCreate2Factory. -/// -/// If 0age's ImmutableCreate2Factory has not been deployed on your EVM chain of choice, -/// please refer to 0age's ImmutableCreate2Factory deployment instructions at: -/// https://github.com/ProjectOpenSea/seaport/blob/main/docs/Deployment.md -/// -/// Contract verification: -/// - Source code: -/// https://github.com/Vectorized/solady/blob/5212e50fef1f2ff1b1b5e03a5d276a0d23c02713/src/utils/ERC1967Factory.sol -/// (The EXACT source code is required. Use the file at the commit instead of the latest copy.) -/// - Optimization Enabled: Yes with 1000000 runs -/// - Compiler Version: v0.8.19+commit.7dd6d404 -/// - Other Settings: default evmVersion, MIT license -library ERC1967FactoryConstants { - /// @dev The canonical ERC1967Factory address for EVM chains. - address internal constant ADDRESS = 0x0000000000006396FF2a80c067f99B3d2Ab4Df24; - - /// @dev The canonical ERC1967Factory bytecode for EVM chains. - /// Useful for forge tests: - /// `vm.etch(ADDRESS, BYTECODE)`. - bytes internal constant BYTECODE = - hex"6080604052600436106100b15760003560e01c8063545e7c611161006957806399a88ec41161004e57806399a88ec41461019d578063a97b90d5146101b0578063db4c545e146101c357600080fd5b8063545e7c61146101775780639623609d1461018a57600080fd5b80633729f9221161009a5780633729f922146101315780634314f120146101445780635414dff01461015757600080fd5b80631acfd02a146100b65780632abbef15146100d8575b600080fd5b3480156100c257600080fd5b506100d66100d1366004610604565b6101e6565b005b3480156100e457600080fd5b506101076100f3366004610637565b30600c908152600091909152602090205490565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61010761013f366004610652565b610237565b6101076101523660046106d7565b61024e565b34801561016357600080fd5b50610107610172366004610738565b610267565b610107610185366004610604565b61029a565b6100d66101983660046106d7565b6102af565b6100d66101ab366004610604565b61035f565b6101076101be366004610751565b610370565b3480156101cf57600080fd5b506101d86103a9565b604051908152602001610128565b30600c52816000526020600c2033815414610209576382b429006000526004601cfd5b81905580827f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f600080a35050565b60006102468484843685610370565b949350505050565b600061025e8585838087876103c2565b95945050505050565b6000806102726103a9565b905060ff600053806035523060601b6001528260155260556000209150600060355250919050565b60006102a88383368461024e565b9392505050565b30600c5283600052336020600c2054146102d1576382b429006000526004601cfd5b6040518381527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc602082015281836040830137600080836040018334895af1610331573d610327576355299b496000526004601cfd5b3d6000803e3d6000fd5b5082847f5d611f318680d00598bb735d61bacf0c514c6b50e1e5ad30040a4df2b12791c7600080a350505050565b61036c82823660006102af565b5050565b60008360601c33148460601c151761039057632f6348366000526004601cfd5b61039f868686600187876103c2565b9695505050505050565b6000806103b461049c565b608960139091012092915050565b6000806103cd61049c565b90508480156103e757866089601384016000f592506103f3565b6089601383016000f092505b50816104075763301164256000526004601cfd5b8781527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc602082015282846040830137600080846040018334865af161045a573d6103275763301164256000526004601cfd5b30600c5281600052866020600c20558688837fc95935a66d15e0da5e412aca0ad27ae891d20b2fb91cf3994b6a3bf2b8178082600080a4509695505050505050565b6040513060701c801561054257666052573d6000fd607b8301527f3d356020355560408036111560525736038060403d373d3d355af43d6000803e60748301527f3735a920a3ca505d382bbc545af43d6000803e6052573d6000fd5b3d6000f35b60548301527f14605757363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc60348301523060148301526c607f3d8160093d39f33d3d337382525090565b66604c573d6000fd60758301527f3d3560203555604080361115604c5736038060403d373d3d355af43d6000803e606e8301527f3735a920a3ca505d382bbc545af43d6000803e604c573d6000fd5b3d6000f35b604e8301527f14605157363d3d37363d7f360894a13ba1a3210667c828492db98dca3e2076cc602e83015230600e8301526c60793d8160093d39f33d3d336d82525090565b803573ffffffffffffffffffffffffffffffffffffffff811681146105ff57600080fd5b919050565b6000806040838503121561061757600080fd5b610620836105db565b915061062e602084016105db565b90509250929050565b60006020828403121561064957600080fd5b6102a8826105db565b60008060006060848603121561066757600080fd5b610670846105db565b925061067e602085016105db565b9150604084013590509250925092565b60008083601f8401126106a057600080fd5b50813567ffffffffffffffff8111156106b857600080fd5b6020830191508360208285010111156106d057600080fd5b9250929050565b600080600080606085870312156106ed57600080fd5b6106f6856105db565b9350610704602086016105db565b9250604085013567ffffffffffffffff81111561072057600080fd5b61072c8782880161068e565b95989497509550505050565b60006020828403121561074a57600080fd5b5035919050565b60008060008060006080868803121561076957600080fd5b610772866105db565b9450610780602087016105db565b935060408601359250606086013567ffffffffffffffff8111156107a357600080fd5b6107af8882890161068e565b96999598509396509294939250505056fea26469706673582212200ac7c3ccbc2d311c48bf5465b021542e0e306fe3c462c060ba6a3d2f81ff6c5f64736f6c63430008130033"; - - /// @dev The initialization code used to deploy the canonical ERC1967Factory. - bytes internal constant INITCODE = abi.encodePacked( - hex"608060405234801561001057600080fd5b506107f6806100206000396000f3fe", BYTECODE - ); - - /// @dev For deterministic deployment via 0age's ImmutableCreate2Factory. - bytes32 internal constant SALT = - 0x0000000000000000000000000000000000000000e75e4f228818c80007508f33; -} diff --git a/grouperBot/lib/solady/src/utils/EfficientHashLib.sol b/grouperBot/lib/solady/src/utils/EfficientHashLib.sol deleted file mode 100644 index 77e7dd4..0000000 --- a/grouperBot/lib/solady/src/utils/EfficientHashLib.sol +++ /dev/null @@ -1,934 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for efficiently performing keccak256 hashes. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EfficientHashLib.sol) -/// @dev To avoid stack-too-deep, you can use: -/// ``` -/// bytes32[] memory buffer = EfficientHashLib.malloc(10); -/// EfficientHashLib.set(buffer, 0, value0); -/// .. -/// EfficientHashLib.set(buffer, 9, value9); -/// bytes32 finalHash = EfficientHashLib.hash(buffer); -/// ``` -library EfficientHashLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MALLOC-LESS HASHING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `keccak256(abi.encode(v0))`. - function hash(bytes32 v0) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, v0) - result := keccak256(0x00, 0x20) - } - } - - /// @dev Returns `keccak256(abi.encode(v0))`. - function hash(uint256 v0) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, v0) - result := keccak256(0x00, 0x20) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, v1))`. - function hash(bytes32 v0, bytes32 v1) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, v0) - mstore(0x20, v1) - result := keccak256(0x00, 0x40) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, v1))`. - function hash(uint256 v0, uint256 v1) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, v0) - mstore(0x20, v1) - result := keccak256(0x00, 0x40) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, v1, v2))`. - function hash(bytes32 v0, bytes32 v1, bytes32 v2) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - result := keccak256(m, 0x60) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, v1, v2))`. - function hash(uint256 v0, uint256 v1, uint256 v2) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - result := keccak256(m, 0x60) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`. - function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - result := keccak256(m, 0x80) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`. - function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - result := keccak256(m, 0x80) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v4))`. - function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - result := keccak256(m, 0xa0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v4))`. - function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - result := keccak256(m, 0xa0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v5))`. - function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4, bytes32 v5) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - result := keccak256(m, 0xc0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v5))`. - function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4, uint256 v5) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - result := keccak256(m, 0xc0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v6))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - result := keccak256(m, 0xe0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v6))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - result := keccak256(m, 0xe0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v7))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6, - bytes32 v7 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - result := keccak256(m, 0x100) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v7))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6, - uint256 v7 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - result := keccak256(m, 0x100) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v8))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6, - bytes32 v7, - bytes32 v8 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - result := keccak256(m, 0x120) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v8))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6, - uint256 v7, - uint256 v8 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - result := keccak256(m, 0x120) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v9))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6, - bytes32 v7, - bytes32 v8, - bytes32 v9 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - result := keccak256(m, 0x140) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v9))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6, - uint256 v7, - uint256 v8, - uint256 v9 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - result := keccak256(m, 0x140) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v10))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6, - bytes32 v7, - bytes32 v8, - bytes32 v9, - bytes32 v10 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - result := keccak256(m, 0x160) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v10))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6, - uint256 v7, - uint256 v8, - uint256 v9, - uint256 v10 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - result := keccak256(m, 0x160) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v11))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6, - bytes32 v7, - bytes32 v8, - bytes32 v9, - bytes32 v10, - bytes32 v11 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - mstore(add(m, 0x160), v11) - result := keccak256(m, 0x180) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v11))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6, - uint256 v7, - uint256 v8, - uint256 v9, - uint256 v10, - uint256 v11 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - mstore(add(m, 0x160), v11) - result := keccak256(m, 0x180) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v12))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6, - bytes32 v7, - bytes32 v8, - bytes32 v9, - bytes32 v10, - bytes32 v11, - bytes32 v12 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - mstore(add(m, 0x160), v11) - mstore(add(m, 0x180), v12) - result := keccak256(m, 0x1a0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v12))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6, - uint256 v7, - uint256 v8, - uint256 v9, - uint256 v10, - uint256 v11, - uint256 v12 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - mstore(add(m, 0x160), v11) - mstore(add(m, 0x180), v12) - result := keccak256(m, 0x1a0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v13))`. - function hash( - bytes32 v0, - bytes32 v1, - bytes32 v2, - bytes32 v3, - bytes32 v4, - bytes32 v5, - bytes32 v6, - bytes32 v7, - bytes32 v8, - bytes32 v9, - bytes32 v10, - bytes32 v11, - bytes32 v12, - bytes32 v13 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - mstore(add(m, 0x160), v11) - mstore(add(m, 0x180), v12) - mstore(add(m, 0x1a0), v13) - result := keccak256(m, 0x1c0) - } - } - - /// @dev Returns `keccak256(abi.encode(v0, .., v13))`. - function hash( - uint256 v0, - uint256 v1, - uint256 v2, - uint256 v3, - uint256 v4, - uint256 v5, - uint256 v6, - uint256 v7, - uint256 v8, - uint256 v9, - uint256 v10, - uint256 v11, - uint256 v12, - uint256 v13 - ) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, v0) - mstore(add(m, 0x20), v1) - mstore(add(m, 0x40), v2) - mstore(add(m, 0x60), v3) - mstore(add(m, 0x80), v4) - mstore(add(m, 0xa0), v5) - mstore(add(m, 0xc0), v6) - mstore(add(m, 0xe0), v7) - mstore(add(m, 0x100), v8) - mstore(add(m, 0x120), v9) - mstore(add(m, 0x140), v10) - mstore(add(m, 0x160), v11) - mstore(add(m, 0x180), v12) - mstore(add(m, 0x1a0), v13) - result := keccak256(m, 0x1c0) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTES32 BUFFER HASHING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `keccak256(abi.encode(buffer[0], .., buffer[buffer.length - 1]))`. - function hash(bytes32[] memory buffer) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(add(buffer, 0x20), shl(5, mload(buffer))) - } - } - - /// @dev Sets `buffer[i]` to `value`, without a bounds check. - /// Returns the `buffer` for function chaining. - function set(bytes32[] memory buffer, uint256 i, bytes32 value) - internal - pure - returns (bytes32[] memory) - { - /// @solidity memory-safe-assembly - assembly { - mstore(add(buffer, shl(5, add(1, i))), value) - } - return buffer; - } - - /// @dev Sets `buffer[i]` to `value`, without a bounds check. - /// Returns the `buffer` for function chaining. - function set(bytes32[] memory buffer, uint256 i, uint256 value) - internal - pure - returns (bytes32[] memory) - { - /// @solidity memory-safe-assembly - assembly { - mstore(add(buffer, shl(5, add(1, i))), value) - } - return buffer; - } - - /// @dev Returns `new bytes32[](n)`, without zeroing out the memory. - function malloc(uint256 n) internal pure returns (bytes32[] memory buffer) { - /// @solidity memory-safe-assembly - assembly { - buffer := mload(0x40) - mstore(buffer, n) - mstore(0x40, add(shl(5, add(1, n)), buffer)) - } - } - - /// @dev Frees memory that has been allocated for `buffer`. - /// No-op if `buffer.length` is zero, or if new memory has been allocated after `buffer`. - function free(bytes32[] memory buffer) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(buffer) - mstore(shl(6, lt(iszero(n), eq(add(shl(5, add(1, n)), buffer), mload(0x40)))), buffer) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EQUALITY CHECKS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `a == abi.decode(b, (bytes32))`. - function eq(bytes32 a, bytes memory b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := and(eq(0x20, mload(b)), eq(a, mload(add(b, 0x20)))) - } - } - - /// @dev Returns `abi.decode(a, (bytes32)) == a`. - function eq(bytes memory a, bytes32 b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := and(eq(0x20, mload(a)), eq(b, mload(add(a, 0x20)))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTE SLICE HASHING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function hash(bytes memory b, uint256 start, uint256 end) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(b) - end := xor(end, mul(xor(end, n), lt(n, end))) - start := xor(start, mul(xor(start, n), lt(n, start))) - result := keccak256(add(add(b, 0x20), start), mul(gt(end, start), sub(end, start))) - } - } - - /// @dev Returns the keccak256 of the slice from `start` to the end of the bytes. - function hash(bytes memory b, uint256 start) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(b) - start := xor(start, mul(xor(start, n), lt(n, start))) - result := keccak256(add(add(b, 0x20), start), mul(gt(n, start), sub(n, start))) - } - } - - /// @dev Returns the keccak256 of the bytes. - function hash(bytes memory b) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(add(b, 0x20), mload(b)) - } - } - - /// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function hashCalldata(bytes calldata b, uint256 start, uint256 end) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - end := xor(end, mul(xor(end, b.length), lt(b.length, end))) - start := xor(start, mul(xor(start, b.length), lt(b.length, start))) - let n := mul(gt(end, start), sub(end, start)) - calldatacopy(mload(0x40), add(b.offset, start), n) - result := keccak256(mload(0x40), n) - } - } - - /// @dev Returns the keccak256 of the slice from `start` to the end of the bytes. - function hashCalldata(bytes calldata b, uint256 start) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - start := xor(start, mul(xor(start, b.length), lt(b.length, start))) - let n := mul(gt(b.length, start), sub(b.length, start)) - calldatacopy(mload(0x40), add(b.offset, start), n) - result := keccak256(mload(0x40), n) - } - } - - /// @dev Returns the keccak256 of the bytes. - function hashCalldata(bytes calldata b) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - calldatacopy(mload(0x40), b.offset, b.length) - result := keccak256(mload(0x40), b.length) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* SHA2-256 HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `sha256(abi.encode(b))`. Yes, it's more efficient. - function sha2(bytes32 b) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, b) - result := mload(staticcall(gas(), 2, 0x00, 0x20, 0x01, 0x20)) - if iszero(returndatasize()) { invalid() } - } - } - - /// @dev Returns the sha256 of the slice from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function sha2(bytes memory b, uint256 start, uint256 end) - internal - view - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(b) - end := xor(end, mul(xor(end, n), lt(n, end))) - start := xor(start, mul(xor(start, n), lt(n, start))) - // forgefmt: disable-next-item - result := mload(staticcall(gas(), 2, add(add(b, 0x20), start), - mul(gt(end, start), sub(end, start)), 0x01, 0x20)) - if iszero(returndatasize()) { invalid() } - } - } - - /// @dev Returns the sha256 of the slice from `start` to the end of the bytes. - function sha2(bytes memory b, uint256 start) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(b) - start := xor(start, mul(xor(start, n), lt(n, start))) - // forgefmt: disable-next-item - result := mload(staticcall(gas(), 2, add(add(b, 0x20), start), - mul(gt(n, start), sub(n, start)), 0x01, 0x20)) - if iszero(returndatasize()) { invalid() } - } - } - - /// @dev Returns the sha256 of the bytes. - function sha2(bytes memory b) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(staticcall(gas(), 2, add(b, 0x20), mload(b), 0x01, 0x20)) - if iszero(returndatasize()) { invalid() } - } - } - - /// @dev Returns the sha256 of the slice from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function sha2Calldata(bytes calldata b, uint256 start, uint256 end) - internal - view - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - end := xor(end, mul(xor(end, b.length), lt(b.length, end))) - start := xor(start, mul(xor(start, b.length), lt(b.length, start))) - let n := mul(gt(end, start), sub(end, start)) - calldatacopy(mload(0x40), add(b.offset, start), n) - result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20)) - if iszero(returndatasize()) { invalid() } - } - } - - /// @dev Returns the sha256 of the slice from `start` to the end of the bytes. - function sha2Calldata(bytes calldata b, uint256 start) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - start := xor(start, mul(xor(start, b.length), lt(b.length, start))) - let n := mul(gt(b.length, start), sub(b.length, start)) - calldatacopy(mload(0x40), add(b.offset, start), n) - result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20)) - if iszero(returndatasize()) { invalid() } - } - } - - /// @dev Returns the sha256 of the bytes. - function sha2Calldata(bytes calldata b) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - calldatacopy(mload(0x40), b.offset, b.length) - result := mload(staticcall(gas(), 2, mload(0x40), b.length, 0x01, 0x20)) - if iszero(returndatasize()) { invalid() } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/EnumerableMapLib.sol b/grouperBot/lib/solady/src/utils/EnumerableMapLib.sol deleted file mode 100644 index 57154c6..0000000 --- a/grouperBot/lib/solady/src/utils/EnumerableMapLib.sol +++ /dev/null @@ -1,820 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {EnumerableSetLib} from "./EnumerableSetLib.sol"; - -/// @notice Library for managing enumerable maps in storage. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EnumerableMapLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableMap.sol) -library EnumerableMapLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The key does not exist in the enumerable map. - error EnumerableMapKeyNotFound(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev An enumerable map of `bytes32` to `bytes32`. - struct Bytes32ToBytes32Map { - EnumerableSetLib.Bytes32Set _keys; - mapping(bytes32 => bytes32) _values; - } - - /// @dev An enumerable map of `bytes32` to `uint256`. - struct Bytes32ToUint256Map { - EnumerableSetLib.Bytes32Set _keys; - mapping(bytes32 => uint256) _values; - } - - /// @dev An enumerable map of `bytes32` to `address`. - struct Bytes32ToAddressMap { - EnumerableSetLib.Bytes32Set _keys; - mapping(bytes32 => address) _values; - } - - /// @dev An enumerable map of `uint256` to `bytes32`. - struct Uint256ToBytes32Map { - EnumerableSetLib.Uint256Set _keys; - mapping(uint256 => bytes32) _values; - } - - /// @dev An enumerable map of `uint256` to `uint256`. - struct Uint256ToUint256Map { - EnumerableSetLib.Uint256Set _keys; - mapping(uint256 => uint256) _values; - } - - /// @dev An enumerable map of `uint256` to `address`. - struct Uint256ToAddressMap { - EnumerableSetLib.Uint256Set _keys; - mapping(uint256 => address) _values; - } - - /// @dev An enumerable map of `address` to `bytes32`. - struct AddressToBytes32Map { - EnumerableSetLib.AddressSet _keys; - mapping(address => bytes32) _values; - } - - /// @dev An enumerable map of `address` to `uint256`. - struct AddressToUint256Map { - EnumerableSetLib.AddressSet _keys; - mapping(address => uint256) _values; - } - - /// @dev An enumerable map of `address` to `address`. - struct AddressToAddressMap { - EnumerableSetLib.AddressSet _keys; - mapping(address => address) _values; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* GETTERS / SETTERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Bytes32ToBytes32Map storage map, - bytes32 key, - bytes32 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Bytes32ToBytes32Map storage map, uint256 i) - internal - view - returns (bytes32 key, bytes32 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) - internal - view - returns (bool exists, bytes32 value) - { - exists = (value = map._values[key]) != bytes32(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Bytes32ToBytes32Map storage map, bytes32 key) - internal - view - returns (bytes32 value) - { - if ((value = map._values[key]) == bytes32(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Bytes32ToUint256Map storage map, bytes32 key, uint256 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Bytes32ToUint256Map storage map, bytes32 key, uint256 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Bytes32ToUint256Map storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Bytes32ToUint256Map storage map, - bytes32 key, - uint256 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Bytes32ToUint256Map storage map, bytes32 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Bytes32ToUint256Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Bytes32ToUint256Map storage map, uint256 i) - internal - view - returns (bytes32 key, uint256 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Bytes32ToUint256Map storage map, bytes32 key) - internal - view - returns (bool exists, uint256 value) - { - exists = (value = map._values[key]) != uint256(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Bytes32ToUint256Map storage map, bytes32 key) - internal - view - returns (uint256 value) - { - if ((value = map._values[key]) == uint256(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Bytes32ToUint256Map storage map) internal view returns (bytes32[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Bytes32ToAddressMap storage map, bytes32 key, address value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Bytes32ToAddressMap storage map, bytes32 key, address value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Bytes32ToAddressMap storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Bytes32ToAddressMap storage map, - bytes32 key, - address value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Bytes32ToAddressMap storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Bytes32ToAddressMap storage map, uint256 i) - internal - view - returns (bytes32 key, address value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Bytes32ToAddressMap storage map, bytes32 key) - internal - view - returns (bool exists, address value) - { - exists = (value = map._values[key]) != address(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Bytes32ToAddressMap storage map, bytes32 key) - internal - view - returns (address value) - { - if ((value = map._values[key]) == address(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Uint256ToBytes32Map storage map, uint256 key, bytes32 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Uint256ToBytes32Map storage map, uint256 key, bytes32 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Uint256ToBytes32Map storage map, uint256 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Uint256ToBytes32Map storage map, - uint256 key, - bytes32 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Uint256ToBytes32Map storage map, uint256 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Uint256ToBytes32Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Uint256ToBytes32Map storage map, uint256 i) - internal - view - returns (uint256 key, bytes32 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Uint256ToBytes32Map storage map, uint256 key) - internal - view - returns (bool exists, bytes32 value) - { - exists = (value = map._values[key]) != bytes32(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Uint256ToBytes32Map storage map, uint256 key) - internal - view - returns (bytes32 value) - { - if ((value = map._values[key]) == bytes32(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Uint256ToBytes32Map storage map) internal view returns (uint256[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Uint256ToUint256Map storage map, uint256 key, uint256 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Uint256ToUint256Map storage map, uint256 key, uint256 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Uint256ToUint256Map storage map, uint256 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Uint256ToUint256Map storage map, - uint256 key, - uint256 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Uint256ToUint256Map storage map, uint256 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Uint256ToUint256Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Uint256ToUint256Map storage map, uint256 i) - internal - view - returns (uint256 key, uint256 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Uint256ToUint256Map storage map, uint256 key) - internal - view - returns (bool exists, uint256 value) - { - exists = (value = map._values[key]) != uint256(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Uint256ToUint256Map storage map, uint256 key) - internal - view - returns (uint256 value) - { - if ((value = map._values[key]) == uint256(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Uint256ToUint256Map storage map) internal view returns (uint256[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Uint256ToAddressMap storage map, uint256 key, address value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Uint256ToAddressMap storage map, uint256 key, address value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Uint256ToAddressMap storage map, uint256 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Uint256ToAddressMap storage map, - uint256 key, - address value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Uint256ToAddressMap storage map, uint256 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Uint256ToAddressMap storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Uint256ToAddressMap storage map, uint256 i) - internal - view - returns (uint256 key, address value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Uint256ToAddressMap storage map, uint256 key) - internal - view - returns (bool exists, address value) - { - exists = (value = map._values[key]) != address(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Uint256ToAddressMap storage map, uint256 key) - internal - view - returns (address value) - { - if ((value = map._values[key]) == address(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Uint256ToAddressMap storage map) internal view returns (uint256[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(AddressToBytes32Map storage map, address key, bytes32 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(AddressToBytes32Map storage map, address key, bytes32 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(AddressToBytes32Map storage map, address key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - AddressToBytes32Map storage map, - address key, - bytes32 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(AddressToBytes32Map storage map, address key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(AddressToBytes32Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(AddressToBytes32Map storage map, uint256 i) - internal - view - returns (address key, bytes32 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(AddressToBytes32Map storage map, address key) - internal - view - returns (bool exists, bytes32 value) - { - exists = (value = map._values[key]) != bytes32(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(AddressToBytes32Map storage map, address key) - internal - view - returns (bytes32 value) - { - if ((value = map._values[key]) == bytes32(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(AddressToUint256Map storage map, address key, uint256 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(AddressToUint256Map storage map, address key, uint256 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(AddressToUint256Map storage map, address key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - AddressToUint256Map storage map, - address key, - uint256 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(AddressToUint256Map storage map, address key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(AddressToUint256Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(AddressToUint256Map storage map, uint256 i) - internal - view - returns (address key, uint256 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(AddressToUint256Map storage map, address key) - internal - view - returns (bool exists, uint256 value) - { - exists = (value = map._values[key]) != uint256(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(AddressToUint256Map storage map, address key) - internal - view - returns (uint256 value) - { - if ((value = map._values[key]) == uint256(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(AddressToUint256Map storage map) internal view returns (address[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(AddressToAddressMap storage map, address key, address value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(AddressToAddressMap storage map, address key, address value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(AddressToAddressMap storage map, address key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - AddressToAddressMap storage map, - address key, - address value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(AddressToAddressMap storage map, address key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(AddressToAddressMap storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(AddressToAddressMap storage map, uint256 i) - internal - view - returns (address key, address value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(AddressToAddressMap storage map, address key) - internal - view - returns (bool exists, address value) - { - exists = (value = map._values[key]) != address(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(AddressToAddressMap storage map, address key) - internal - view - returns (address value) - { - if ((value = map._values[key]) == address(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(AddressToAddressMap storage map) internal view returns (address[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Reverts with `EnumerableMapKeyNotFound()`. - function _revertNotFound() private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x88682bf3) // `EnumerableMapKeyNotFound()`. - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/EnumerableSetLib.sol b/grouperBot/lib/solady/src/utils/EnumerableSetLib.sol deleted file mode 100644 index cb770dd..0000000 --- a/grouperBot/lib/solady/src/utils/EnumerableSetLib.sol +++ /dev/null @@ -1,918 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for managing enumerable sets in storage. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EnumerableSetLib.sol) -/// -/// @dev Note: -/// In many applications, the number of elements in an enumerable set is small. -/// This enumerable set implementation avoids storing the length and indices -/// for up to 3 elements. Once the length exceeds 3 for the first time, the length -/// and indices will be initialized. The amortized cost of adding elements is O(1). -/// -/// The AddressSet implementation packs the length with the 0th entry. -/// -/// All enumerable sets except Uint8Set use a pop and swap mechanism to remove elements. -/// This means that the iteration order of elements can change between element removals. -library EnumerableSetLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The index must be less than the length. - error IndexOutOfBounds(); - - /// @dev The value cannot be the zero sentinel. - error ValueIsZeroSentinel(); - - /// @dev Cannot accommodate a new unique value with the capacity. - error ExceedsCapacity(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The index to represent a value that does not exist. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /// @dev A sentinel value to denote the zero value in storage. - /// No elements can be equal to this value. - /// `uint72(bytes9(keccak256(bytes("_ZERO_SENTINEL"))))`. - uint256 private constant _ZERO_SENTINEL = 0xfbb67fda52d4bfb8bf; - - /// @dev The storage layout is given by: - /// ``` - /// mstore(0x04, _ENUMERABLE_ADDRESS_SET_SLOT_SEED) - /// mstore(0x00, set.slot) - /// let rootSlot := keccak256(0x00, 0x24) - /// mstore(0x20, rootSlot) - /// mstore(0x00, shr(96, shl(96, value))) - /// let positionSlot := keccak256(0x00, 0x40) - /// let valueSlot := add(rootSlot, sload(positionSlot)) - /// let valueInStorage := shr(96, sload(valueSlot)) - /// let lazyLength := shr(160, shl(160, sload(rootSlot))) - /// ``` - uint256 private constant _ENUMERABLE_ADDRESS_SET_SLOT_SEED = 0x978aab92; - - /// @dev The storage layout is given by: - /// ``` - /// mstore(0x04, _ENUMERABLE_WORD_SET_SLOT_SEED) - /// mstore(0x00, set.slot) - /// let rootSlot := keccak256(0x00, 0x24) - /// mstore(0x20, rootSlot) - /// mstore(0x00, value) - /// let positionSlot := keccak256(0x00, 0x40) - /// let valueSlot := add(rootSlot, sload(positionSlot)) - /// let valueInStorage := sload(valueSlot) - /// let lazyLength := sload(not(rootSlot)) - /// ``` - uint256 private constant _ENUMERABLE_WORD_SET_SLOT_SEED = 0x18fb5864; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev An enumerable address set in storage. - struct AddressSet { - uint256 _spacer; - } - - /// @dev An enumerable bytes32 set in storage. - struct Bytes32Set { - uint256 _spacer; - } - - /// @dev An enumerable uint256 set in storage. - struct Uint256Set { - uint256 _spacer; - } - - /// @dev An enumerable int256 set in storage. - struct Int256Set { - uint256 _spacer; - } - - /// @dev An enumerable uint8 set in storage. Useful for enums. - struct Uint8Set { - uint256 data; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* GETTERS / SETTERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of elements in the set. - function length(AddressSet storage set) internal view returns (uint256 result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let rootPacked := sload(rootSlot) - let n := shr(160, shl(160, rootPacked)) - result := shr(1, n) - for {} iszero(or(iszero(shr(96, rootPacked)), n)) {} { - result := 1 - if iszero(sload(add(rootSlot, result))) { break } - result := 2 - if iszero(sload(add(rootSlot, result))) { break } - result := 3 - break - } - } - } - - /// @dev Returns the number of elements in the set. - function length(Bytes32Set storage set) internal view returns (uint256 result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let n := sload(not(rootSlot)) - result := shr(1, n) - for {} iszero(n) {} { - result := 0 - if iszero(sload(add(rootSlot, result))) { break } - result := 1 - if iszero(sload(add(rootSlot, result))) { break } - result := 2 - if iszero(sload(add(rootSlot, result))) { break } - result := 3 - break - } - } - } - - /// @dev Returns the number of elements in the set. - function length(Uint256Set storage set) internal view returns (uint256 result) { - result = length(_toBytes32Set(set)); - } - - /// @dev Returns the number of elements in the set. - function length(Int256Set storage set) internal view returns (uint256 result) { - result = length(_toBytes32Set(set)); - } - - /// @dev Returns the number of elements in the set. - function length(Uint8Set storage set) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - for { let packed := sload(set.slot) } packed { result := add(1, result) } { - packed := xor(packed, and(packed, add(1, not(packed)))) - } - } - } - - /// @dev Returns whether `value` is in the set. - function contains(AddressSet storage set, address value) internal view returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - value := shr(96, shl(96, value)) - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - let rootPacked := sload(rootSlot) - for {} 1 {} { - if iszero(shr(160, shl(160, rootPacked))) { - result := 1 - if eq(shr(96, rootPacked), value) { break } - if eq(shr(96, sload(add(rootSlot, 1))), value) { break } - if eq(shr(96, sload(add(rootSlot, 2))), value) { break } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := iszero(iszero(sload(keccak256(0x00, 0x40)))) - break - } - } - } - - /// @dev Returns whether `value` is in the set. - function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - for {} 1 {} { - if iszero(sload(not(rootSlot))) { - result := 1 - if eq(sload(rootSlot), value) { break } - if eq(sload(add(rootSlot, 1)), value) { break } - if eq(sload(add(rootSlot, 2)), value) { break } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := iszero(iszero(sload(keccak256(0x00, 0x40)))) - break - } - } - } - - /// @dev Returns whether `value` is in the set. - function contains(Uint256Set storage set, uint256 value) internal view returns (bool result) { - result = contains(_toBytes32Set(set), bytes32(value)); - } - - /// @dev Returns whether `value` is in the set. - function contains(Int256Set storage set, int256 value) internal view returns (bool result) { - result = contains(_toBytes32Set(set), bytes32(uint256(value))); - } - - /// @dev Returns whether `value` is in the set. - function contains(Uint8Set storage set, uint8 value) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := and(1, shr(and(0xff, value), sload(set.slot))) - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(AddressSet storage set, address value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - value := shr(96, shl(96, value)) - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - let rootPacked := sload(rootSlot) - for { let n := shr(160, shl(160, rootPacked)) } 1 {} { - mstore(0x20, rootSlot) - if iszero(n) { - let v0 := shr(96, rootPacked) - if iszero(v0) { - sstore(rootSlot, shl(96, value)) - result := 1 - break - } - if eq(v0, value) { break } - let v1 := shr(96, sload(add(rootSlot, 1))) - if iszero(v1) { - sstore(add(rootSlot, 1), shl(96, value)) - result := 1 - break - } - if eq(v1, value) { break } - let v2 := shr(96, sload(add(rootSlot, 2))) - if iszero(v2) { - sstore(add(rootSlot, 2), shl(96, value)) - result := 1 - break - } - if eq(v2, value) { break } - mstore(0x00, v0) - sstore(keccak256(0x00, 0x40), 1) - mstore(0x00, v1) - sstore(keccak256(0x00, 0x40), 2) - mstore(0x00, v2) - sstore(keccak256(0x00, 0x40), 3) - rootPacked := or(rootPacked, 7) - n := 7 - } - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - if iszero(sload(p)) { - n := shr(1, n) - result := 1 - sstore(p, add(1, n)) - if iszero(n) { - sstore(rootSlot, or(3, shl(96, value))) - break - } - sstore(add(rootSlot, n), shl(96, value)) - sstore(rootSlot, add(2, rootPacked)) - break - } - break - } - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Bytes32Set storage set, bytes32 value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - for { let n := sload(not(rootSlot)) } 1 {} { - mstore(0x20, rootSlot) - if iszero(n) { - let v0 := sload(rootSlot) - if iszero(v0) { - sstore(rootSlot, value) - result := 1 - break - } - if eq(v0, value) { break } - let v1 := sload(add(rootSlot, 1)) - if iszero(v1) { - sstore(add(rootSlot, 1), value) - result := 1 - break - } - if eq(v1, value) { break } - let v2 := sload(add(rootSlot, 2)) - if iszero(v2) { - sstore(add(rootSlot, 2), value) - result := 1 - break - } - if eq(v2, value) { break } - mstore(0x00, v0) - sstore(keccak256(0x00, 0x40), 1) - mstore(0x00, v1) - sstore(keccak256(0x00, 0x40), 2) - mstore(0x00, v2) - sstore(keccak256(0x00, 0x40), 3) - n := 7 - } - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - if iszero(sload(p)) { - n := shr(1, n) - sstore(add(rootSlot, n), value) - sstore(p, add(1, n)) - sstore(not(rootSlot), or(1, shl(1, add(1, n)))) - result := 1 - break - } - break - } - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Uint256Set storage set, uint256 value) internal returns (bool result) { - result = add(_toBytes32Set(set), bytes32(value)); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Int256Set storage set, int256 value) internal returns (bool result) { - result = add(_toBytes32Set(set), bytes32(uint256(value))); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Uint8Set storage set, uint8 value) internal returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(set.slot) - let mask := shl(and(0xff, value), 1) - sstore(set.slot, or(result, mask)) - result := iszero(and(result, mask)) - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(AddressSet storage set, address value, uint256 cap) - internal - returns (bool result) - { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Bytes32Set storage set, bytes32 value, uint256 cap) - internal - returns (bool result) - { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Uint256Set storage set, uint256 value, uint256 cap) - internal - returns (bool result) - { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Int256Set storage set, int256 value, uint256 cap) internal returns (bool result) { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Uint8Set storage set, uint8 value, uint256 cap) internal returns (bool result) { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(AddressSet storage set, address value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - value := shr(96, shl(96, value)) - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - let rootPacked := sload(rootSlot) - for { let n := shr(160, shl(160, rootPacked)) } 1 {} { - if iszero(n) { - result := 1 - if eq(shr(96, rootPacked), value) { - sstore(rootSlot, sload(add(rootSlot, 1))) - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(shr(96, sload(add(rootSlot, 1))), value) { - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(shr(96, sload(add(rootSlot, 2))), value) { - sstore(add(rootSlot, 2), 0) - break - } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - let position := sload(p) - if iszero(position) { break } - n := sub(shr(1, n), 1) - if iszero(eq(sub(position, 1), n)) { - let lastValue := shr(96, sload(add(rootSlot, n))) - sstore(add(rootSlot, sub(position, 1)), shl(96, lastValue)) - mstore(0x00, lastValue) - sstore(keccak256(0x00, 0x40), position) - } - sstore(rootSlot, or(shl(96, shr(96, sload(rootSlot))), or(shl(1, n), 1))) - sstore(p, 0) - result := 1 - break - } - } - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Bytes32Set storage set, bytes32 value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - for { let n := sload(not(rootSlot)) } 1 {} { - if iszero(n) { - result := 1 - if eq(sload(rootSlot), value) { - sstore(rootSlot, sload(add(rootSlot, 1))) - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(sload(add(rootSlot, 1)), value) { - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(sload(add(rootSlot, 2)), value) { - sstore(add(rootSlot, 2), 0) - break - } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - let position := sload(p) - if iszero(position) { break } - n := sub(shr(1, n), 1) - if iszero(eq(sub(position, 1), n)) { - let lastValue := sload(add(rootSlot, n)) - sstore(add(rootSlot, sub(position, 1)), lastValue) - mstore(0x00, lastValue) - sstore(keccak256(0x00, 0x40), position) - } - sstore(not(rootSlot), or(shl(1, n), 1)) - sstore(p, 0) - result := 1 - break - } - } - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Uint256Set storage set, uint256 value) internal returns (bool result) { - result = remove(_toBytes32Set(set), bytes32(value)); - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Int256Set storage set, int256 value) internal returns (bool result) { - result = remove(_toBytes32Set(set), bytes32(uint256(value))); - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Uint8Set storage set, uint8 value) internal returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(set.slot) - let mask := shl(and(0xff, value), 1) - sstore(set.slot, and(result, not(mask))) - result := iszero(iszero(and(result, mask))) - } - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(AddressSet storage set, address value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Bytes32Set storage set, bytes32 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Uint256Set storage set, uint256 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Int256Set storage set, int256 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Uint8Set storage set, uint8 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(AddressSet storage set) internal view returns (address[] memory result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let zs := _ZERO_SENTINEL - let rootPacked := sload(rootSlot) - let n := shr(160, shl(160, rootPacked)) - result := mload(0x40) - let o := add(0x20, result) - let v := shr(96, rootPacked) - mstore(o, mul(v, iszero(eq(v, zs)))) - for {} 1 {} { - if iszero(n) { - if v { - n := 1 - v := shr(96, sload(add(rootSlot, n))) - if v { - n := 2 - mstore(add(o, 0x20), mul(v, iszero(eq(v, zs)))) - v := shr(96, sload(add(rootSlot, n))) - if v { - n := 3 - mstore(add(o, 0x40), mul(v, iszero(eq(v, zs)))) - } - } - } - break - } - n := shr(1, n) - for { let i := 1 } lt(i, n) { i := add(i, 1) } { - v := shr(96, sload(add(rootSlot, i))) - mstore(add(o, shl(5, i)), mul(v, iszero(eq(v, zs)))) - } - break - } - mstore(result, n) - mstore(0x40, add(o, shl(5, n))) - } - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(Bytes32Set storage set) internal view returns (bytes32[] memory result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let zs := _ZERO_SENTINEL - let n := sload(not(rootSlot)) - result := mload(0x40) - let o := add(0x20, result) - for {} 1 {} { - if iszero(n) { - let v := sload(rootSlot) - if v { - n := 1 - mstore(o, mul(v, iszero(eq(v, zs)))) - v := sload(add(rootSlot, n)) - if v { - n := 2 - mstore(add(o, 0x20), mul(v, iszero(eq(v, zs)))) - v := sload(add(rootSlot, n)) - if v { - n := 3 - mstore(add(o, 0x40), mul(v, iszero(eq(v, zs)))) - } - } - } - break - } - n := shr(1, n) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - let v := sload(add(rootSlot, i)) - mstore(add(o, shl(5, i)), mul(v, iszero(eq(v, zs)))) - } - break - } - mstore(result, n) - mstore(0x40, add(o, shl(5, n))) - } - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(Uint256Set storage set) internal view returns (uint256[] memory result) { - result = _toUints(values(_toBytes32Set(set))); - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(Int256Set storage set) internal view returns (int256[] memory result) { - result = _toInts(values(_toBytes32Set(set))); - } - - /// @dev Returns all of the values in the set. - function values(Uint8Set storage set) internal view returns (uint8[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let ptr := add(result, 0x20) - let o := 0 - for { let packed := sload(set.slot) } packed {} { - if iszero(and(packed, 0xffff)) { - o := add(o, 16) - packed := shr(16, packed) - continue - } - mstore(ptr, o) - ptr := add(ptr, shl(5, and(packed, 1))) - o := add(o, 1) - packed := shr(1, packed) - } - mstore(result, shr(5, sub(ptr, add(result, 0x20)))) - mstore(0x40, ptr) - } - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(AddressSet storage set, uint256 i) internal view returns (address result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - result := shr(96, sload(add(rootSlot, i))) - result := mul(result, iszero(eq(result, _ZERO_SENTINEL))) - } - if (i >= length(set)) revert IndexOutOfBounds(); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Bytes32Set storage set, uint256 i) internal view returns (bytes32 result) { - result = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - result := sload(add(result, i)) - result := mul(result, iszero(eq(result, _ZERO_SENTINEL))) - } - if (i >= length(set)) revert IndexOutOfBounds(); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Uint256Set storage set, uint256 i) internal view returns (uint256 result) { - result = uint256(at(_toBytes32Set(set), i)); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Int256Set storage set, uint256 i) internal view returns (int256 result) { - result = int256(uint256(at(_toBytes32Set(set), i))); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Uint8Set storage set, uint256 i) internal view returns (uint8 result) { - /// @solidity memory-safe-assembly - assembly { - let packed := sload(set.slot) - for {} 1 { - mstore(0x00, 0x4e23d035) // `IndexOutOfBounds()`. - revert(0x1c, 0x04) - } { - if iszero(lt(i, 256)) { continue } - for { let j := 0 } iszero(eq(i, j)) {} { - packed := xor(packed, and(packed, add(1, not(packed)))) - j := add(j, 1) - } - if iszero(packed) { continue } - break - } - // Find first set subroutine, optimized for smaller bytecode size. - let x := and(packed, add(1, not(packed))) - let r := shl(7, iszero(iszero(shr(128, x)))) - r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x)))))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - // For the lower 5 bits of the result, use a De Bruijn lookup. - // forgefmt: disable-next-item - result := or(r, byte(and(div(0xd76453e0, shr(r, x)), 0x1f), - 0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405)) - } - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(AddressSet storage set, address value) - internal - view - returns (uint256 result) - { - result = NOT_FOUND; - if (uint160(value) == _ZERO_SENTINEL) return result; - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if iszero(value) { value := _ZERO_SENTINEL } - result := not(0) - let rootPacked := sload(rootSlot) - for {} 1 {} { - if iszero(shr(160, shl(160, rootPacked))) { - if eq(shr(96, rootPacked), value) { - result := 0 - break - } - if eq(shr(96, sload(add(rootSlot, 1))), value) { - result := 1 - break - } - if eq(shr(96, sload(add(rootSlot, 2))), value) { - result := 2 - break - } - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := sub(sload(keccak256(0x00, 0x40)), 1) - break - } - } - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Bytes32Set storage set, bytes32 value) - internal - view - returns (uint256 result) - { - result = NOT_FOUND; - if (uint256(value) == _ZERO_SENTINEL) return result; - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if iszero(value) { value := _ZERO_SENTINEL } - for {} 1 {} { - if iszero(sload(not(rootSlot))) { - if eq(sload(rootSlot), value) { - result := 0 - break - } - if eq(sload(add(rootSlot, 1)), value) { - result := 1 - break - } - if eq(sload(add(rootSlot, 2)), value) { - result := 2 - break - } - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := sub(sload(keccak256(0x00, 0x40)), 1) - break - } - } - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Uint256Set storage set, uint256 i) internal view returns (uint256 result) { - result = indexOf(_toBytes32Set(set), bytes32(i)); - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Int256Set storage set, int256 i) internal view returns (uint256 result) { - result = indexOf(_toBytes32Set(set), bytes32(uint256(i))); - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Uint8Set storage set, uint8 value) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := not(0) - let packed := sload(set.slot) - let m := shl(and(0xff, value), 1) - if and(packed, m) { - result := 0 - for { let p := and(packed, sub(m, 1)) } p {} { - p := xor(p, and(p, add(1, not(p)))) - result := add(result, 1) - } - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the root slot. - function _rootSlot(AddressSet storage s) private pure returns (bytes32 r) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ENUMERABLE_ADDRESS_SET_SLOT_SEED) - mstore(0x00, s.slot) - r := keccak256(0x00, 0x24) - } - } - - /// @dev Returns the root slot. - function _rootSlot(Bytes32Set storage s) private pure returns (bytes32 r) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ENUMERABLE_WORD_SET_SLOT_SEED) - mstore(0x00, s.slot) - r := keccak256(0x00, 0x24) - } - } - - /// @dev Casts to a Bytes32Set. - function _toBytes32Set(Uint256Set storage s) private pure returns (Bytes32Set storage c) { - /// @solidity memory-safe-assembly - assembly { - c.slot := s.slot - } - } - - /// @dev Casts to a Bytes32Set. - function _toBytes32Set(Int256Set storage s) private pure returns (Bytes32Set storage c) { - /// @solidity memory-safe-assembly - assembly { - c.slot := s.slot - } - } - - /// @dev Casts to a uint256 array. - function _toUints(bytes32[] memory a) private pure returns (uint256[] memory c) { - /// @solidity memory-safe-assembly - assembly { - c := a - } - } - - /// @dev Casts to a int256 array. - function _toInts(bytes32[] memory a) private pure returns (int256[] memory c) { - /// @solidity memory-safe-assembly - assembly { - c := a - } - } -} diff --git a/grouperBot/lib/solady/src/utils/FixedPointMathLib.sol b/grouperBot/lib/solady/src/utils/FixedPointMathLib.sol deleted file mode 100644 index 2353363..0000000 --- a/grouperBot/lib/solady/src/utils/FixedPointMathLib.sol +++ /dev/null @@ -1,1312 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Arithmetic library with operations for fixed-point numbers. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) -library FixedPointMathLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The operation failed, as the output exceeds the maximum value of uint256. - error ExpOverflow(); - - /// @dev The operation failed, as the output exceeds the maximum value of uint256. - error FactorialOverflow(); - - /// @dev The operation failed, due to an overflow. - error RPowOverflow(); - - /// @dev The mantissa is too big to fit. - error MantissaOverflow(); - - /// @dev The operation failed, due to an multiplication overflow. - error MulWadFailed(); - - /// @dev The operation failed, due to an multiplication overflow. - error SMulWadFailed(); - - /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero. - error DivWadFailed(); - - /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero. - error SDivWadFailed(); - - /// @dev The operation failed, either due to a multiplication overflow, or a division by a zero. - error MulDivFailed(); - - /// @dev The division failed, as the denominator is zero. - error DivFailed(); - - /// @dev The full precision multiply-divide operation failed, either due - /// to the result being larger than 256 bits, or a division by a zero. - error FullMulDivFailed(); - - /// @dev The output is undefined, as the input is less-than-or-equal to zero. - error LnWadUndefined(); - - /// @dev The input outside the acceptable domain. - error OutOfDomain(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The scalar of ETH and most ERC20s. - uint256 internal constant WAD = 1e18; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* SIMPLIFIED FIXED POINT OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `(x * y) / WAD` rounded down. - function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`. - if gt(x, div(not(0), y)) { - if y { - mstore(0x00, 0xbac65e5b) // `MulWadFailed()`. - revert(0x1c, 0x04) - } - } - z := div(mul(x, y), WAD) - } - } - - /// @dev Equivalent to `(x * y) / WAD` rounded down. - function sMulWad(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - // Equivalent to `require((x == 0 || z / x == y) && !(x == -1 && y == type(int256).min))`. - if iszero(gt(or(iszero(x), eq(sdiv(z, x), y)), lt(not(x), eq(y, shl(255, 1))))) { - mstore(0x00, 0xedcd4dd4) // `SMulWadFailed()`. - revert(0x1c, 0x04) - } - z := sdiv(z, WAD) - } - } - - /// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks. - function rawMulWad(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := div(mul(x, y), WAD) - } - } - - /// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks. - function rawSMulWad(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := sdiv(mul(x, y), WAD) - } - } - - /// @dev Equivalent to `(x * y) / WAD` rounded up. - function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`. - if iszero(eq(div(z, y), x)) { - if y { - mstore(0x00, 0xbac65e5b) // `MulWadFailed()`. - revert(0x1c, 0x04) - } - } - z := add(iszero(iszero(mod(z, WAD))), div(z, WAD)) - } - } - - /// @dev Equivalent to `(x * y) / WAD` rounded up, but without overflow checks. - function rawMulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD)) - } - } - - /// @dev Equivalent to `(x * WAD) / y` rounded down. - function divWad(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Equivalent to `require(y != 0 && x <= type(uint256).max / WAD)`. - if iszero(mul(y, lt(x, add(1, div(not(0), WAD))))) { - mstore(0x00, 0x7c5f487d) // `DivWadFailed()`. - revert(0x1c, 0x04) - } - z := div(mul(x, WAD), y) - } - } - - /// @dev Equivalent to `(x * WAD) / y` rounded down. - function sDivWad(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(x, WAD) - // Equivalent to `require(y != 0 && ((x * WAD) / WAD == x))`. - if iszero(mul(y, eq(sdiv(z, WAD), x))) { - mstore(0x00, 0x5c43740d) // `SDivWadFailed()`. - revert(0x1c, 0x04) - } - z := sdiv(z, y) - } - } - - /// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks. - function rawDivWad(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := div(mul(x, WAD), y) - } - } - - /// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks. - function rawSDivWad(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := sdiv(mul(x, WAD), y) - } - } - - /// @dev Equivalent to `(x * WAD) / y` rounded up. - function divWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Equivalent to `require(y != 0 && x <= type(uint256).max / WAD)`. - if iszero(mul(y, lt(x, add(1, div(not(0), WAD))))) { - mstore(0x00, 0x7c5f487d) // `DivWadFailed()`. - revert(0x1c, 0x04) - } - z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y)) - } - } - - /// @dev Equivalent to `(x * WAD) / y` rounded up, but without overflow and divide by zero checks. - function rawDivWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y)) - } - } - - /// @dev Equivalent to `x` to the power of `y`. - /// because `x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)`. - /// Note: This function is an approximation. - function powWad(int256 x, int256 y) internal pure returns (int256) { - // Using `ln(x)` means `x` must be greater than 0. - return expWad((lnWad(x) * y) / int256(WAD)); - } - - /// @dev Returns `exp(x)`, denominated in `WAD`. - /// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln - /// Note: This function is an approximation. Monotonically increasing. - function expWad(int256 x) internal pure returns (int256 r) { - unchecked { - // When the result is less than 0.5 we return zero. - // This happens when `x <= (log(1e-18) * 1e18) ~ -4.15e19`. - if (x <= -41446531673892822313) return r; - - /// @solidity memory-safe-assembly - assembly { - // When the result is greater than `(2**255 - 1) / 1e18` we can not represent it as - // an int. This happens when `x >= floor(log((2**255 - 1) / 1e18) * 1e18) ≈ 135`. - if iszero(slt(x, 135305999368893231589)) { - mstore(0x00, 0xa37bfec9) // `ExpOverflow()`. - revert(0x1c, 0x04) - } - } - - // `x` is now in the range `(-42, 136) * 1e18`. Convert to `(-42, 136) * 2**96` - // for more intermediate precision and a binary basis. This base conversion - // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. - x = (x << 78) / 5 ** 18; - - // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers - // of two such that exp(x) = exp(x') * 2**k, where k is an integer. - // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). - int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >> 96; - x = x - k * 54916777467707473351141471128; - - // `k` is in the range `[-61, 195]`. - - // Evaluate using a (6, 7)-term rational approximation. - // `p` is made monic, we'll multiply by a scale factor later. - int256 y = x + 1346386616545796478920950773328; - y = ((y * x) >> 96) + 57155421227552351082224309758442; - int256 p = y + x - 94201549194550492254356042504812; - p = ((p * y) >> 96) + 28719021644029726153956944680412240; - p = p * x + (4385272521454847904659076985693276 << 96); - - // We leave `p` in `2**192` basis so we don't need to scale it back up for the division. - int256 q = x - 2855989394907223263936484059900; - q = ((q * x) >> 96) + 50020603652535783019961831881945; - q = ((q * x) >> 96) - 533845033583426703283633433725380; - q = ((q * x) >> 96) + 3604857256930695427073651918091429; - q = ((q * x) >> 96) - 14423608567350463180887372962807573; - q = ((q * x) >> 96) + 26449188498355588339934803723976023; - - /// @solidity memory-safe-assembly - assembly { - // Div in assembly because solidity adds a zero check despite the unchecked. - // The q polynomial won't have zeros in the domain as all its roots are complex. - // No scaling is necessary because p is already `2**96` too large. - r := sdiv(p, q) - } - - // r should be in the range `(0.09, 0.25) * 2**96`. - - // We now need to multiply r by: - // - The scale factor `s ≈ 6.031367120`. - // - The `2**k` factor from the range reduction. - // - The `1e18 / 2**96` factor for base conversion. - // We do this all at once, with an intermediate result in `2**213` - // basis, so the final right shift is always by a positive amount. - r = int256( - (uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k) - ); - } - } - - /// @dev Returns `ln(x)`, denominated in `WAD`. - /// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln - /// Note: This function is an approximation. Monotonically increasing. - function lnWad(int256 x) internal pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // We want to convert `x` from `10**18` fixed point to `2**96` fixed point. - // We do this by multiplying by `2**96 / 10**18`. But since - // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here - // and add `ln(2**96 / 10**18)` at the end. - - // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`. - r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // We place the check here for more optimal stack operations. - if iszero(sgt(x, 0)) { - mstore(0x00, 0x1615e638) // `LnWadUndefined()`. - revert(0x1c, 0x04) - } - // forgefmt: disable-next-item - r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)), - 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff)) - - // Reduce range of x to (1, 2) * 2**96 - // ln(2^k * x) = k * ln(2) + ln(x) - x := shr(159, shl(r, x)) - - // Evaluate using a (8, 8)-term rational approximation. - // `p` is made monic, we will multiply by a scale factor later. - // forgefmt: disable-next-item - let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir. - sar(96, mul(add(43456485725739037958740375743393, - sar(96, mul(add(24828157081833163892658089445524, - sar(96, mul(add(3273285459638523848632254066296, - x), x))), x))), x)), 11111509109440967052023855526967) - p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857) - p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526) - p := sub(mul(p, x), shl(96, 795164235651350426258249787498)) - // We leave `p` in `2**192` basis so we don't need to scale it back up for the division. - - // `q` is monic by convention. - let q := add(5573035233440673466300451813936, x) - q := add(71694874799317883764090561454958, sar(96, mul(x, q))) - q := add(283447036172924575727196451306956, sar(96, mul(x, q))) - q := add(401686690394027663651624208769553, sar(96, mul(x, q))) - q := add(204048457590392012362485061816622, sar(96, mul(x, q))) - q := add(31853899698501571402653359427138, sar(96, mul(x, q))) - q := add(909429971244387300277376558375, sar(96, mul(x, q))) - - // `p / q` is in the range `(0, 0.125) * 2**96`. - - // Finalization, we need to: - // - Multiply by the scale factor `s = 5.549…`. - // - Add `ln(2**96 / 10**18)`. - // - Add `k * ln(2)`. - // - Multiply by `10**18 / 2**96 = 5**18 >> 78`. - - // The q polynomial is known not to have zeros in the domain. - // No scaling required because p is already `2**96` too large. - p := sdiv(p, q) - // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`. - p := mul(1677202110996718588342820967067443963516166, p) - // Add `ln(2) * k * 5**18 * 2**192`. - // forgefmt: disable-next-item - p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p) - // Add `ln(2**96 / 10**18) * 5**18 * 2**192`. - p := add(600920179829731861736702779321621459595472258049074101567377883020018308, p) - // Base conversion: mul `2**18 / 2**192`. - r := sar(174, p) - } - } - - /// @dev Returns `W_0(x)`, denominated in `WAD`. - /// See: https://en.wikipedia.org/wiki/Lambert_W_function - /// a.k.a. Product log function. This is an approximation of the principal branch. - /// Note: This function is an approximation. Monotonically increasing. - function lambertW0Wad(int256 x) internal pure returns (int256 w) { - // forgefmt: disable-next-item - unchecked { - if ((w = x) <= -367879441171442322) revert OutOfDomain(); // `x` less than `-1/e`. - (int256 wad, int256 p) = (int256(WAD), x); - uint256 c; // Whether we need to avoid catastrophic cancellation. - uint256 i = 4; // Number of iterations. - if (w <= 0x1ffffffffffff) { - if (-0x4000000000000 <= w) { - i = 1; // Inputs near zero only take one step to converge. - } else if (w <= -0x3ffffffffffffff) { - i = 32; // Inputs near `-1/e` take very long to converge. - } - } else if (uint256(w >> 63) == uint256(0)) { - /// @solidity memory-safe-assembly - assembly { - // Inline log2 for more performance, since the range is small. - let v := shr(49, w) - let l := shl(3, lt(0xff, v)) - l := add(or(l, byte(and(0x1f, shr(shr(l, v), 0x8421084210842108cc6318c6db6d54be)), - 0x0706060506020504060203020504030106050205030304010505030400000000)), 49) - w := sdiv(shl(l, 7), byte(sub(l, 31), 0x0303030303030303040506080c13)) - c := gt(l, 60) - i := add(2, add(gt(l, 53), c)) - } - } else { - int256 ll = lnWad(w = lnWad(w)); - /// @solidity memory-safe-assembly - assembly { - // `w = ln(x) - ln(ln(x)) + b * ln(ln(x)) / ln(x)`. - w := add(sdiv(mul(ll, 1023715080943847266), w), sub(w, ll)) - i := add(3, iszero(shr(68, x))) - c := iszero(shr(143, x)) - } - if (c == uint256(0)) { - do { // If `x` is big, use Newton's so that intermediate values won't overflow. - int256 e = expWad(w); - /// @solidity memory-safe-assembly - assembly { - let t := mul(w, div(e, wad)) - w := sub(w, sdiv(sub(t, x), div(add(e, t), wad))) - } - if (p <= w) break; - p = w; - } while (--i != uint256(0)); - /// @solidity memory-safe-assembly - assembly { - w := sub(w, sgt(w, 2)) - } - return w; - } - } - do { // Otherwise, use Halley's for faster convergence. - int256 e = expWad(w); - /// @solidity memory-safe-assembly - assembly { - let t := add(w, wad) - let s := sub(mul(w, e), mul(x, wad)) - w := sub(w, sdiv(mul(s, wad), sub(mul(e, t), sdiv(mul(add(t, wad), s), add(t, t))))) - } - if (p <= w) break; - p = w; - } while (--i != c); - /// @solidity memory-safe-assembly - assembly { - w := sub(w, sgt(w, 2)) - } - // For certain ranges of `x`, we'll use the quadratic-rate recursive formula of - // R. Iacono and J.P. Boyd for the last iteration, to avoid catastrophic cancellation. - if (c == uint256(0)) return w; - int256 t = w | 1; - /// @solidity memory-safe-assembly - assembly { - x := sdiv(mul(x, wad), t) - } - x = (t * (wad + lnWad(x))); - /// @solidity memory-safe-assembly - assembly { - w := sdiv(x, add(wad, t)) - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* GENERAL NUMBER UTILITIES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `a * b == x * y`, with full precision. - function fullMulEq(uint256 a, uint256 b, uint256 x, uint256 y) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - result := and(eq(mul(a, b), mul(x, y)), eq(mulmod(x, y, not(0)), mulmod(a, b, not(0)))) - } - } - - /// @dev Calculates `floor(x * y / d)` with full precision. - /// Throws if result overflows a uint256 or when `d` is zero. - /// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv - function fullMulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // 512-bit multiply `[p1 p0] = x * y`. - // Compute the product mod `2**256` and mod `2**256 - 1` - // then use the Chinese Remainder Theorem to reconstruct - // the 512 bit result. The result is stored in two 256 - // variables such that `product = p1 * 2**256 + p0`. - - // Temporarily use `z` as `p0` to save gas. - z := mul(x, y) // Lower 256 bits of `x * y`. - for {} 1 {} { - // If overflows. - if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) { - let mm := mulmod(x, y, not(0)) - let p1 := sub(mm, add(z, lt(mm, z))) // Upper 256 bits of `x * y`. - - /*------------------- 512 by 256 division --------------------*/ - - // Make division exact by subtracting the remainder from `[p1 p0]`. - let r := mulmod(x, y, d) // Compute remainder using mulmod. - let t := and(d, sub(0, d)) // The least significant bit of `d`. `t >= 1`. - // Make sure `z` is less than `2**256`. Also prevents `d == 0`. - // Placing the check here seems to give more optimal stack operations. - if iszero(gt(d, p1)) { - mstore(0x00, 0xae47f702) // `FullMulDivFailed()`. - revert(0x1c, 0x04) - } - d := div(d, t) // Divide `d` by `t`, which is a power of two. - // Invert `d mod 2**256` - // Now that `d` is an odd number, it has an inverse - // modulo `2**256` such that `d * inv = 1 mod 2**256`. - // Compute the inverse by starting with a seed that is correct - // correct for four bits. That is, `d * inv = 1 mod 2**4`. - let inv := xor(2, mul(3, d)) - // Now use Newton-Raphson iteration to improve the precision. - // Thanks to Hensel's lifting lemma, this also works in modular - // arithmetic, doubling the correct bits in each step. - inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**8 - inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**16 - inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**32 - inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**64 - inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**128 - z := - mul( - // Divide [p1 p0] by the factors of two. - // Shift in bits from `p1` into `p0`. For this we need - // to flip `t` such that it is `2**256 / t`. - or(mul(sub(p1, gt(r, z)), add(div(sub(0, t), t), 1)), div(sub(z, r), t)), - mul(sub(2, mul(d, inv)), inv) // inverse mod 2**256 - ) - break - } - z := div(z, d) - break - } - } - } - - /// @dev Calculates `floor(x * y / d)` with full precision. - /// Behavior is undefined if `d` is zero or the final result cannot fit in 256 bits. - /// Performs the full 512 bit calculation regardless. - function fullMulDivUnchecked(uint256 x, uint256 y, uint256 d) - internal - pure - returns (uint256 z) - { - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - let mm := mulmod(x, y, not(0)) - let p1 := sub(mm, add(z, lt(mm, z))) - let t := and(d, sub(0, d)) - let r := mulmod(x, y, d) - d := div(d, t) - let inv := xor(2, mul(3, d)) - inv := mul(inv, sub(2, mul(d, inv))) - inv := mul(inv, sub(2, mul(d, inv))) - inv := mul(inv, sub(2, mul(d, inv))) - inv := mul(inv, sub(2, mul(d, inv))) - inv := mul(inv, sub(2, mul(d, inv))) - z := - mul( - or(mul(sub(p1, gt(r, z)), add(div(sub(0, t), t), 1)), div(sub(z, r), t)), - mul(sub(2, mul(d, inv)), inv) - ) - } - } - - /// @dev Calculates `floor(x * y / d)` with full precision, rounded up. - /// Throws if result overflows a uint256 or when `d` is zero. - /// Credit to Uniswap-v3-core under MIT license: - /// https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/FullMath.sol - function fullMulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) { - z = fullMulDiv(x, y, d); - /// @solidity memory-safe-assembly - assembly { - if mulmod(x, y, d) { - z := add(z, 1) - if iszero(z) { - mstore(0x00, 0xae47f702) // `FullMulDivFailed()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Calculates `floor(x * y / 2 ** n)` with full precision. - /// Throws if result overflows a uint256. - /// Credit to Philogy under MIT license: - /// https://github.com/SorellaLabs/angstrom/blob/main/contracts/src/libraries/X128MathLib.sol - function fullMulDivN(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Temporarily use `z` as `p0` to save gas. - z := mul(x, y) // Lower 256 bits of `x * y`. We'll call this `z`. - for {} 1 {} { - if iszero(or(iszero(x), eq(div(z, x), y))) { - let k := and(n, 0xff) // `n`, cleaned. - let mm := mulmod(x, y, not(0)) - let p1 := sub(mm, add(z, lt(mm, z))) // Upper 256 bits of `x * y`. - // | p1 | z | - // Before: | p1_0 ¦ p1_1 | z_0 ¦ z_1 | - // Final: | 0 ¦ p1_0 | p1_1 ¦ z_0 | - // Check that final `z` doesn't overflow by checking that p1_0 = 0. - if iszero(shr(k, p1)) { - z := add(shl(sub(256, k), p1), shr(k, z)) - break - } - mstore(0x00, 0xae47f702) // `FullMulDivFailed()`. - revert(0x1c, 0x04) - } - z := shr(and(n, 0xff), z) - break - } - } - } - - /// @dev Returns `floor(x * y / d)`. - /// Reverts if `x * y` overflows, or `d` is zero. - function mulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - // Equivalent to `require(d != 0 && (y == 0 || x <= type(uint256).max / y))`. - if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) { - mstore(0x00, 0xad251c27) // `MulDivFailed()`. - revert(0x1c, 0x04) - } - z := div(z, d) - } - } - - /// @dev Returns `ceil(x * y / d)`. - /// Reverts if `x * y` overflows, or `d` is zero. - function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - // Equivalent to `require(d != 0 && (y == 0 || x <= type(uint256).max / y))`. - if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) { - mstore(0x00, 0xad251c27) // `MulDivFailed()`. - revert(0x1c, 0x04) - } - z := add(iszero(iszero(mod(z, d))), div(z, d)) - } - } - - /// @dev Returns `x`, the modular multiplicative inverse of `a`, such that `(a * x) % n == 1`. - function invMod(uint256 a, uint256 n) internal pure returns (uint256 x) { - /// @solidity memory-safe-assembly - assembly { - let g := n - let r := mod(a, n) - for { let y := 1 } 1 {} { - let q := div(g, r) - let t := g - g := r - r := sub(t, mul(r, q)) - let u := x - x := y - y := sub(u, mul(y, q)) - if iszero(r) { break } - } - x := mul(eq(g, 1), add(x, mul(slt(x, 0), n))) - } - } - - /// @dev Returns `ceil(x / d)`. - /// Reverts if `d` is zero. - function divUp(uint256 x, uint256 d) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - if iszero(d) { - mstore(0x00, 0x65244e4e) // `DivFailed()`. - revert(0x1c, 0x04) - } - z := add(iszero(iszero(mod(x, d))), div(x, d)) - } - } - - /// @dev Returns `max(0, x - y)`. Alias for `saturatingSub`. - function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(gt(x, y), sub(x, y)) - } - } - - /// @dev Returns `max(0, x - y)`. - function saturatingSub(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(gt(x, y), sub(x, y)) - } - } - - /// @dev Returns `min(2 ** 256 - 1, x + y)`. - function saturatingAdd(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := or(sub(0, lt(add(x, y), x)), add(x, y)) - } - } - - /// @dev Returns `min(2 ** 256 - 1, x * y)`. - function saturatingMul(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := or(sub(or(iszero(x), eq(div(mul(x, y), x), y)), 1), mul(x, y)) - } - } - - /// @dev Returns `condition ? x : y`, without branching. - function ternary(bool condition, uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, y), iszero(condition))) - } - } - - /// @dev Returns `condition ? x : y`, without branching. - function ternary(bool condition, bytes32 x, bytes32 y) internal pure returns (bytes32 z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, y), iszero(condition))) - } - } - - /// @dev Returns `condition ? x : y`, without branching. - function ternary(bool condition, address x, address y) internal pure returns (address z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, y), iszero(condition))) - } - } - - /// @dev Returns `x != 0 ? x : y`, without branching. - function coalesce(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := or(x, mul(y, iszero(x))) - } - } - - /// @dev Returns `x != bytes32(0) ? x : y`, without branching. - function coalesce(bytes32 x, bytes32 y) internal pure returns (bytes32 z) { - /// @solidity memory-safe-assembly - assembly { - z := or(x, mul(y, iszero(x))) - } - } - - /// @dev Returns `x != address(0) ? x : y`, without branching. - function coalesce(address x, address y) internal pure returns (address z) { - /// @solidity memory-safe-assembly - assembly { - z := or(x, mul(y, iszero(shl(96, x)))) - } - } - - /// @dev Exponentiate `x` to `y` by squaring, denominated in base `b`. - /// Reverts if the computation overflows. - function rpow(uint256 x, uint256 y, uint256 b) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mul(b, iszero(y)) // `0 ** 0 = 1`. Otherwise, `0 ** n = 0`. - if x { - z := xor(b, mul(xor(b, x), and(y, 1))) // `z = isEven(y) ? scale : x` - let half := shr(1, b) // Divide `b` by 2. - // Divide `y` by 2 every iteration. - for { y := shr(1, y) } y { y := shr(1, y) } { - let xx := mul(x, x) // Store x squared. - let xxRound := add(xx, half) // Round to the nearest number. - // Revert if `xx + half` overflowed, or if `x ** 2` overflows. - if or(lt(xxRound, xx), shr(128, x)) { - mstore(0x00, 0x49f7642b) // `RPowOverflow()`. - revert(0x1c, 0x04) - } - x := div(xxRound, b) // Set `x` to scaled `xxRound`. - // If `y` is odd: - if and(y, 1) { - let zx := mul(z, x) // Compute `z * x`. - let zxRound := add(zx, half) // Round to the nearest number. - // If `z * x` overflowed or `zx + half` overflowed: - if or(xor(div(zx, x), z), lt(zxRound, zx)) { - // Revert if `x` is non-zero. - if x { - mstore(0x00, 0x49f7642b) // `RPowOverflow()`. - revert(0x1c, 0x04) - } - } - z := div(zxRound, b) // Return properly scaled `zxRound`. - } - } - } - } - } - - /// @dev Returns the square root of `x`, rounded down. - function sqrt(uint256 x) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`. - z := 181 // The "correct" value is 1, but this saves a multiplication later. - - // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad - // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. - - // Let `y = x / 2**r`. We check `y >= 2**(k + 8)` - // but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`. - let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffffff, shr(r, x)))) - z := shl(shr(1, r), z) - - // Goal was to get `z*z*y` within a small factor of `x`. More iterations could - // get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`. - // We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small. - // That's not possible if `x < 256` but we can just verify those cases exhaustively. - - // Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`. - // Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`. - // Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps. - - // For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)` - // is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`, - // with largest error when `s = 1` and when `s = 256` or `1/256`. - - // Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`. - // Then we can estimate `sqrt(y)` using - // `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`. - - // There is no overflow risk here since `y < 2**136` after the first branch above. - z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181. - - // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - - // If `x+1` is a perfect square, the Babylonian method cycles between - // `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor. - // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division - z := sub(z, lt(div(x, z), z)) - } - } - - /// @dev Returns the cube root of `x`, rounded down. - /// Credit to bout3fiddy and pcaversaccio under AGPLv3 license: - /// https://github.com/pcaversaccio/snekmate/blob/main/src/snekmate/utils/math.vy - /// Formally verified by xuwinnie: - /// https://github.com/vectorized/solady/blob/main/audits/xuwinnie-solady-cbrt-proof.pdf - function cbrt(uint256 x) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // Makeshift lookup table to nudge the approximate log2 result. - z := div(shl(div(r, 3), shl(lt(0xf, shr(r, x)), 0xf)), xor(7, mod(r, 3))) - // Newton-Raphson's. - z := div(add(add(div(x, mul(z, z)), z), z), 3) - z := div(add(add(div(x, mul(z, z)), z), z), 3) - z := div(add(add(div(x, mul(z, z)), z), z), 3) - z := div(add(add(div(x, mul(z, z)), z), z), 3) - z := div(add(add(div(x, mul(z, z)), z), z), 3) - z := div(add(add(div(x, mul(z, z)), z), z), 3) - z := div(add(add(div(x, mul(z, z)), z), z), 3) - // Round down. - z := sub(z, lt(div(x, mul(z, z)), z)) - } - } - - /// @dev Returns the square root of `x`, denominated in `WAD`, rounded down. - function sqrtWad(uint256 x) internal pure returns (uint256 z) { - unchecked { - if (x <= type(uint256).max / 10 ** 18) return sqrt(x * 10 ** 18); - z = (1 + sqrt(x)) * 10 ** 9; - z = (fullMulDivUnchecked(x, 10 ** 18, z) + z) >> 1; - } - /// @solidity memory-safe-assembly - assembly { - z := sub(z, gt(999999999999999999, sub(mulmod(z, z, x), 1))) // Round down. - } - } - - /// @dev Returns the cube root of `x`, denominated in `WAD`, rounded down. - /// Formally verified by xuwinnie: - /// https://github.com/vectorized/solady/blob/main/audits/xuwinnie-solady-cbrt-proof.pdf - function cbrtWad(uint256 x) internal pure returns (uint256 z) { - unchecked { - if (x <= type(uint256).max / 10 ** 36) return cbrt(x * 10 ** 36); - z = (1 + cbrt(x)) * 10 ** 12; - z = (fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3; - } - /// @solidity memory-safe-assembly - assembly { - let p := x - for {} 1 {} { - if iszero(shr(229, p)) { - if iszero(shr(199, p)) { - p := mul(p, 100000000000000000) // 10 ** 17. - break - } - p := mul(p, 100000000) // 10 ** 8. - break - } - if iszero(shr(249, p)) { p := mul(p, 100) } - break - } - let t := mulmod(mul(z, z), z, p) - z := sub(z, gt(lt(t, shr(1, p)), iszero(t))) // Round down. - } - } - - /// @dev Returns `sqrt(x * y)`. Also called the geometric mean. - function mulSqrt(uint256 x, uint256 y) internal pure returns (uint256 z) { - if (x == y) return x; - uint256 p = rawMul(x, y); - if (y == rawDiv(p, x)) return sqrt(p); - for (z = saturatingMul(rawAdd(sqrt(x), 1), rawAdd(sqrt(y), 1));; z = avg(z, p)) { - if ((p = fullMulDivUnchecked(x, y, z)) >= z) break; - } - } - - /// @dev Returns the factorial of `x`. - function factorial(uint256 x) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := 1 - if iszero(lt(x, 58)) { - mstore(0x00, 0xaba0f2a2) // `FactorialOverflow()`. - revert(0x1c, 0x04) - } - for {} x { x := sub(x, 1) } { z := mul(z, x) } - } - } - - /// @dev Returns the log2 of `x`. - /// Equivalent to computing the index of the most significant bit (MSB) of `x`. - /// Returns 0 if `x` is zero. - function log2(uint256 x) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // forgefmt: disable-next-item - r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)), - 0x0706060506020504060203020504030106050205030304010505030400000000)) - } - } - - /// @dev Returns the log2 of `x`, rounded up. - /// Returns 0 if `x` is zero. - function log2Up(uint256 x) internal pure returns (uint256 r) { - r = log2(x); - /// @solidity memory-safe-assembly - assembly { - r := add(r, lt(shl(r, 1), x)) - } - } - - /// @dev Returns the log10 of `x`. - /// Returns 0 if `x` is zero. - function log10(uint256 x) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(x, 100000000000000000000000000000000000000)) { - x := div(x, 100000000000000000000000000000000000000) - r := 38 - } - if iszero(lt(x, 100000000000000000000)) { - x := div(x, 100000000000000000000) - r := add(r, 20) - } - if iszero(lt(x, 10000000000)) { - x := div(x, 10000000000) - r := add(r, 10) - } - if iszero(lt(x, 100000)) { - x := div(x, 100000) - r := add(r, 5) - } - r := add(r, add(gt(x, 9), add(gt(x, 99), add(gt(x, 999), gt(x, 9999))))) - } - } - - /// @dev Returns the log10 of `x`, rounded up. - /// Returns 0 if `x` is zero. - function log10Up(uint256 x) internal pure returns (uint256 r) { - r = log10(x); - /// @solidity memory-safe-assembly - assembly { - r := add(r, lt(exp(10, r), x)) - } - } - - /// @dev Returns the log256 of `x`. - /// Returns 0 if `x` is zero. - function log256(uint256 x) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(shr(3, r), lt(0xff, shr(r, x))) - } - } - - /// @dev Returns the log256 of `x`, rounded up. - /// Returns 0 if `x` is zero. - function log256Up(uint256 x) internal pure returns (uint256 r) { - r = log256(x); - /// @solidity memory-safe-assembly - assembly { - r := add(r, lt(shl(shl(3, r), 1), x)) - } - } - - /// @dev Returns the scientific notation format `mantissa * 10 ** exponent` of `x`. - /// Useful for compressing prices (e.g. using 25 bit mantissa and 7 bit exponent). - function sci(uint256 x) internal pure returns (uint256 mantissa, uint256 exponent) { - /// @solidity memory-safe-assembly - assembly { - mantissa := x - if mantissa { - if iszero(mod(mantissa, 1000000000000000000000000000000000)) { - mantissa := div(mantissa, 1000000000000000000000000000000000) - exponent := 33 - } - if iszero(mod(mantissa, 10000000000000000000)) { - mantissa := div(mantissa, 10000000000000000000) - exponent := add(exponent, 19) - } - if iszero(mod(mantissa, 1000000000000)) { - mantissa := div(mantissa, 1000000000000) - exponent := add(exponent, 12) - } - if iszero(mod(mantissa, 1000000)) { - mantissa := div(mantissa, 1000000) - exponent := add(exponent, 6) - } - if iszero(mod(mantissa, 10000)) { - mantissa := div(mantissa, 10000) - exponent := add(exponent, 4) - } - if iszero(mod(mantissa, 100)) { - mantissa := div(mantissa, 100) - exponent := add(exponent, 2) - } - if iszero(mod(mantissa, 10)) { - mantissa := div(mantissa, 10) - exponent := add(exponent, 1) - } - } - } - } - - /// @dev Convenience function for packing `x` into a smaller number using `sci`. - /// The `mantissa` will be in bits [7..255] (the upper 249 bits). - /// The `exponent` will be in bits [0..6] (the lower 7 bits). - /// Use `SafeCastLib` to safely ensure that the `packed` number is small - /// enough to fit in the desired unsigned integer type: - /// ``` - /// uint32 packed = SafeCastLib.toUint32(FixedPointMathLib.packSci(777 ether)); - /// ``` - function packSci(uint256 x) internal pure returns (uint256 packed) { - (x, packed) = sci(x); // Reuse for `mantissa` and `exponent`. - /// @solidity memory-safe-assembly - assembly { - if shr(249, x) { - mstore(0x00, 0xce30380c) // `MantissaOverflow()`. - revert(0x1c, 0x04) - } - packed := or(shl(7, x), packed) - } - } - - /// @dev Convenience function for unpacking a packed number from `packSci`. - function unpackSci(uint256 packed) internal pure returns (uint256 unpacked) { - unchecked { - unpacked = (packed >> 7) * 10 ** (packed & 0x7f); - } - } - - /// @dev Returns the average of `x` and `y`. Rounds towards zero. - function avg(uint256 x, uint256 y) internal pure returns (uint256 z) { - unchecked { - z = (x & y) + ((x ^ y) >> 1); - } - } - - /// @dev Returns the average of `x` and `y`. Rounds towards negative infinity. - function avg(int256 x, int256 y) internal pure returns (int256 z) { - unchecked { - z = (x >> 1) + (y >> 1) + (x & y & 1); - } - } - - /// @dev Returns the absolute value of `x`. - function abs(int256 x) internal pure returns (uint256 z) { - unchecked { - z = (uint256(x) + uint256(x >> 255)) ^ uint256(x >> 255); - } - } - - /// @dev Returns the absolute distance between `x` and `y`. - function dist(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := add(xor(sub(0, gt(x, y)), sub(y, x)), gt(x, y)) - } - } - - /// @dev Returns the absolute distance between `x` and `y`. - function dist(int256 x, int256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := add(xor(sub(0, sgt(x, y)), sub(y, x)), sgt(x, y)) - } - } - - /// @dev Returns the minimum of `x` and `y`. - function min(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, y), lt(y, x))) - } - } - - /// @dev Returns the minimum of `x` and `y`. - function min(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, y), slt(y, x))) - } - } - - /// @dev Returns the maximum of `x` and `y`. - function max(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, y), gt(y, x))) - } - } - - /// @dev Returns the maximum of `x` and `y`. - function max(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, y), sgt(y, x))) - } - } - - /// @dev Returns `x`, bounded to `minValue` and `maxValue`. - function clamp(uint256 x, uint256 minValue, uint256 maxValue) - internal - pure - returns (uint256 z) - { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, minValue), gt(minValue, x))) - z := xor(z, mul(xor(z, maxValue), lt(maxValue, z))) - } - } - - /// @dev Returns `x`, bounded to `minValue` and `maxValue`. - function clamp(int256 x, int256 minValue, int256 maxValue) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := xor(x, mul(xor(x, minValue), sgt(minValue, x))) - z := xor(z, mul(xor(z, maxValue), slt(maxValue, z))) - } - } - - /// @dev Returns greatest common divisor of `x` and `y`. - function gcd(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - for { z := x } y {} { - let t := y - y := mod(z, y) - z := t - } - } - } - - /// @dev Returns `a + (b - a) * (t - begin) / (end - begin)`, - /// with `t` clamped between `begin` and `end` (inclusive). - /// Agnostic to the order of (`a`, `b`) and (`end`, `begin`). - /// If `begins == end`, returns `t <= begin ? a : b`. - function lerp(uint256 a, uint256 b, uint256 t, uint256 begin, uint256 end) - internal - pure - returns (uint256) - { - if (begin > end) (t, begin, end) = (~t, ~begin, ~end); - if (t <= begin) return a; - if (t >= end) return b; - unchecked { - if (b >= a) return a + fullMulDiv(b - a, t - begin, end - begin); - return a - fullMulDiv(a - b, t - begin, end - begin); - } - } - - /// @dev Returns `a + (b - a) * (t - begin) / (end - begin)`. - /// with `t` clamped between `begin` and `end` (inclusive). - /// Agnostic to the order of (`a`, `b`) and (`end`, `begin`). - /// If `begins == end`, returns `t <= begin ? a : b`. - function lerp(int256 a, int256 b, int256 t, int256 begin, int256 end) - internal - pure - returns (int256) - { - if (begin > end) (t, begin, end) = (~t, ~begin, ~end); - if (t <= begin) return a; - if (t >= end) return b; - // forgefmt: disable-next-item - unchecked { - if (b >= a) return int256(uint256(a) + fullMulDiv(uint256(b - a), - uint256(t - begin), uint256(end - begin))); - return int256(uint256(a) - fullMulDiv(uint256(a - b), - uint256(t - begin), uint256(end - begin))); - } - } - - /// @dev Returns if `x` is an even number. Some people may need this. - function isEven(uint256 x) internal pure returns (bool) { - return x & uint256(1) == uint256(0); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RAW NUMBER OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `x + y`, without checking for overflow. - function rawAdd(uint256 x, uint256 y) internal pure returns (uint256 z) { - unchecked { - z = x + y; - } - } - - /// @dev Returns `x + y`, without checking for overflow. - function rawAdd(int256 x, int256 y) internal pure returns (int256 z) { - unchecked { - z = x + y; - } - } - - /// @dev Returns `x - y`, without checking for underflow. - function rawSub(uint256 x, uint256 y) internal pure returns (uint256 z) { - unchecked { - z = x - y; - } - } - - /// @dev Returns `x - y`, without checking for underflow. - function rawSub(int256 x, int256 y) internal pure returns (int256 z) { - unchecked { - z = x - y; - } - } - - /// @dev Returns `x * y`, without checking for overflow. - function rawMul(uint256 x, uint256 y) internal pure returns (uint256 z) { - unchecked { - z = x * y; - } - } - - /// @dev Returns `x * y`, without checking for overflow. - function rawMul(int256 x, int256 y) internal pure returns (int256 z) { - unchecked { - z = x * y; - } - } - - /// @dev Returns `x / y`, returning 0 if `y` is zero. - function rawDiv(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := div(x, y) - } - } - - /// @dev Returns `x / y`, returning 0 if `y` is zero. - function rawSDiv(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := sdiv(x, y) - } - } - - /// @dev Returns `x % y`, returning 0 if `y` is zero. - function rawMod(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mod(x, y) - } - } - - /// @dev Returns `x % y`, returning 0 if `y` is zero. - function rawSMod(int256 x, int256 y) internal pure returns (int256 z) { - /// @solidity memory-safe-assembly - assembly { - z := smod(x, y) - } - } - - /// @dev Returns `(x + y) % d`, return 0 if `d` if zero. - function rawAddMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := addmod(x, y, d) - } - } - - /// @dev Returns `(x * y) % d`, return 0 if `d` if zero. - function rawMulMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mulmod(x, y, d) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/GasBurnerLib.sol b/grouperBot/lib/solady/src/utils/GasBurnerLib.sol deleted file mode 100644 index 20573f5..0000000 --- a/grouperBot/lib/solady/src/utils/GasBurnerLib.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for burning gas without reverting. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/GasBurnerLib.sol) -/// -/// @dev Intended for Contract Secured Revenue (CSR). -/// -/// Recommendation: for the amount of gas to burn, -/// pass in an admin-controlled dynamic value instead of a hardcoded one. -/// This is so that you can adjust your contract as needed depending on market conditions, -/// and to give you and your users a leeway in case the L2 chain change the rules. -library GasBurnerLib { - /// @dev Burns approximately `x` amount of gas. - function burnPure(uint256 x) internal pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x10, or(1, x)) - let n := mul(gt(x, 120), div(x, 91)) - // We use keccak256 instead of blake2f precompile for better widespread compatibility. - for { let i := 0 } iszero(eq(i, n)) { i := add(i, 1) } { - mstore(0x10, keccak256(0x10, 0x10)) // Yes. - } - if iszero(mload(0x10)) { invalid() } - } - } - - /// @dev Burns approximately `x` amount of gas. - function burnView(uint256 x) internal view { - /// @solidity memory-safe-assembly - assembly { - let n := mul(gt(x, 3500), div(x, 3200)) - let m := mload(0x40) - mstore(0x00, xor(address(), xor(origin(), timestamp()))) - mstore(0x00, keccak256(0x00, 0x20)) - mstore(0x20, 27) // `v`. - mstore(0x40, 45) // `r`. - mstore(0x60, 10) // `s`. - for { let i := 0 } iszero(eq(i, n)) { i := add(i, 1) } { - pop(staticcall(gas(), 1, 0x00, 0x81, 0x00, 0x20)) - } - if iszero(mload(0x10)) { invalid() } - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Burns approximately `x` amount of gas. - function burn(uint256 x) internal { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mul(gt(x, 18000), div(x, 17700)) - mstore(m, xor(address(), xor(origin(), timestamp()))) - codecopy(add(m, 0x20), and(keccak256(m, 0x20), 0xff), 2080) - for { let i := 0 } 1 { i := add(i, 1) } { - let h := keccak256(m, 0x21) - mstore(m, h) - codecopy(add(m, and(h, 0x7ff)), and(0xff, h), 0xff) - mstore(add(m, 2048), not(h)) - if eq(i, n) { - n := shr(3, mod(x, 17700)) - n := mul(gt(n, 0x30), sub(n, 0x30)) - mstore(add(m, n), h) - log0(m, add(n, 0x20)) - break - } - log0(m, 2080) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/Initializable.sol b/grouperBot/lib/solady/src/utils/Initializable.sol deleted file mode 100644 index 821d548..0000000 --- a/grouperBot/lib/solady/src/utils/Initializable.sol +++ /dev/null @@ -1,196 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Initializable mixin for the upgradeable contracts. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Initializable.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/proxy/utils/Initializable.sol) -abstract contract Initializable { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The contract is already initialized. - error InvalidInitialization(); - - /// @dev The contract is not initializing. - error NotInitializing(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Triggered when the contract has been initialized. - event Initialized(uint64 version); - - /// @dev `keccak256(bytes("Initialized(uint64)"))`. - bytes32 private constant _INITIALIZED_EVENT_SIGNATURE = - 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The default initializable slot is given by: - /// `bytes32(~uint256(uint32(bytes4(keccak256("_INITIALIZABLE_SLOT")))))`. - /// - /// Bits Layout: - /// - [0] `initializing` - /// - [1..64] `initializedVersion` - bytes32 private constant _INITIALIZABLE_SLOT = - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf601132; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor() { - // Construction time check to ensure that `_initializableSlot()` is not - // overridden to zero. Will be optimized away if there is no revert. - require(_initializableSlot() != bytes32(0)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Override to return a non-zero custom storage slot if required. - function _initializableSlot() internal pure virtual returns (bytes32) { - return _INITIALIZABLE_SLOT; - } - - /// @dev Guards an initializer function so that it can be invoked at most once. - /// - /// You can guard a function with `onlyInitializing` such that it can be called - /// through a function guarded with `initializer`. - /// - /// This is similar to `reinitializer(1)`, except that in the context of a constructor, - /// an `initializer` guarded function can be invoked multiple times. - /// This can be useful during testing and is not expected to be used in production. - /// - /// Emits an {Initialized} event. - modifier initializer() virtual { - bytes32 s = _initializableSlot(); - /// @solidity memory-safe-assembly - assembly { - let i := sload(s) - // Set `initializing` to 1, `initializedVersion` to 1. - sstore(s, 3) - // If `!(initializing == 0 && initializedVersion == 0)`. - if i { - // If `!(address(this).code.length == 0 && initializedVersion == 1)`. - if iszero(lt(extcodesize(address()), eq(shr(1, i), 1))) { - mstore(0x00, 0xf92ee8a9) // `InvalidInitialization()`. - revert(0x1c, 0x04) - } - s := shl(shl(255, i), s) // Skip initializing if `initializing == 1`. - } - } - _; - /// @solidity memory-safe-assembly - assembly { - if s { - // Set `initializing` to 0, `initializedVersion` to 1. - sstore(s, 2) - // Emit the {Initialized} event. - mstore(0x20, 1) - log1(0x20, 0x20, _INITIALIZED_EVENT_SIGNATURE) - } - } - } - - /// @dev Guards a reinitializer function so that it can be invoked at most once. - /// - /// You can guard a function with `onlyInitializing` such that it can be called - /// through a function guarded with `reinitializer`. - /// - /// Emits an {Initialized} event. - modifier reinitializer(uint64 version) virtual { - bytes32 s = _initializableSlot(); - /// @solidity memory-safe-assembly - assembly { - // Clean upper bits, and shift left by 1 to make space for the initializing bit. - version := shl(1, and(version, 0xffffffffffffffff)) - let i := sload(s) - // If `initializing == 1 || initializedVersion >= version`. - if iszero(lt(and(i, 1), lt(i, version))) { - mstore(0x00, 0xf92ee8a9) // `InvalidInitialization()`. - revert(0x1c, 0x04) - } - // Set `initializing` to 1, `initializedVersion` to `version`. - sstore(s, or(1, version)) - } - _; - /// @solidity memory-safe-assembly - assembly { - // Set `initializing` to 0, `initializedVersion` to `version`. - sstore(s, version) - // Emit the {Initialized} event. - mstore(0x20, shr(1, version)) - log1(0x20, 0x20, _INITIALIZED_EVENT_SIGNATURE) - } - } - - /// @dev Guards a function such that it can only be called in the scope - /// of a function guarded with `initializer` or `reinitializer`. - modifier onlyInitializing() virtual { - _checkInitializing(); - _; - } - - /// @dev Reverts if the contract is not initializing. - function _checkInitializing() internal view virtual { - bytes32 s = _initializableSlot(); - /// @solidity memory-safe-assembly - assembly { - if iszero(and(1, sload(s))) { - mstore(0x00, 0xd7e6bcf8) // `NotInitializing()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Locks any future initializations by setting the initialized version to `2**64 - 1`. - /// - /// Calling this in the constructor will prevent the contract from being initialized - /// or reinitialized. It is recommended to use this to lock implementation contracts - /// that are designed to be called through proxies. - /// - /// Emits an {Initialized} event the first time it is successfully called. - function _disableInitializers() internal virtual { - bytes32 s = _initializableSlot(); - /// @solidity memory-safe-assembly - assembly { - let i := sload(s) - if and(i, 1) { - mstore(0x00, 0xf92ee8a9) // `InvalidInitialization()`. - revert(0x1c, 0x04) - } - let uint64max := 0xffffffffffffffff - if iszero(eq(shr(1, i), uint64max)) { - // Set `initializing` to 0, `initializedVersion` to `2**64 - 1`. - sstore(s, shl(1, uint64max)) - // Emit the {Initialized} event. - mstore(0x20, uint64max) - log1(0x20, 0x20, _INITIALIZED_EVENT_SIGNATURE) - } - } - } - - /// @dev Returns the highest version that has been initialized. - function _getInitializedVersion() internal view virtual returns (uint64 version) { - bytes32 s = _initializableSlot(); - /// @solidity memory-safe-assembly - assembly { - version := shr(1, sload(s)) - } - } - - /// @dev Returns whether the contract is currently initializing. - function _isInitializing() internal view virtual returns (bool result) { - bytes32 s = _initializableSlot(); - /// @solidity memory-safe-assembly - assembly { - result := and(1, sload(s)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/JSONParserLib.sol b/grouperBot/lib/solady/src/utils/JSONParserLib.sol deleted file mode 100644 index 881993b..0000000 --- a/grouperBot/lib/solady/src/utils/JSONParserLib.sol +++ /dev/null @@ -1,815 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for parsing JSONs. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/JSONParserLib.sol) -library JSONParserLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The input is invalid. - error ParsingFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // There are 6 types of variables in JSON (excluding undefined). - - /// @dev For denoting that an item has not been initialized. - /// A item returned from `parse` will never be of an undefined type. - /// Parsing an invalid JSON string will simply revert. - uint8 internal constant TYPE_UNDEFINED = 0; - - /// @dev Type representing an array (e.g. `[1,2,3]`). - uint8 internal constant TYPE_ARRAY = 1; - - /// @dev Type representing an object (e.g. `{"a":"A","b":"B"}`). - uint8 internal constant TYPE_OBJECT = 2; - - /// @dev Type representing a number (e.g. `-1.23e+21`). - uint8 internal constant TYPE_NUMBER = 3; - - /// @dev Type representing a string (e.g. `"hello"`). - uint8 internal constant TYPE_STRING = 4; - - /// @dev Type representing a boolean (i.e. `true` or `false`). - uint8 internal constant TYPE_BOOLEAN = 5; - - /// @dev Type representing null (i.e. `null`). - uint8 internal constant TYPE_NULL = 6; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A pointer to a parsed JSON node. - struct Item { - // Do NOT modify the `_data` directly. - uint256 _data; - } - - // Private constants for packing `_data`. - - uint256 private constant _BITPOS_STRING = 32 * 7 - 8; - uint256 private constant _BITPOS_KEY_LENGTH = 32 * 6 - 8; - uint256 private constant _BITPOS_KEY = 32 * 5 - 8; - uint256 private constant _BITPOS_VALUE_LENGTH = 32 * 4 - 8; - uint256 private constant _BITPOS_VALUE = 32 * 3 - 8; - uint256 private constant _BITPOS_CHILD = 32 * 2 - 8; - uint256 private constant _BITPOS_SIBLING_OR_PARENT = 32 * 1 - 8; - uint256 private constant _BITMASK_POINTER = 0xffffffff; - uint256 private constant _BITMASK_TYPE = 7; - uint256 private constant _KEY_INITED = 1 << 3; - uint256 private constant _VALUE_INITED = 1 << 4; - uint256 private constant _CHILDREN_INITED = 1 << 5; - uint256 private constant _PARENT_IS_ARRAY = 1 << 6; - uint256 private constant _PARENT_IS_OBJECT = 1 << 7; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* JSON PARSING OPERATION */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Parses the JSON string `s`, and returns the root. - /// Reverts if `s` is not a valid JSON as specified in RFC 8259. - /// Object items WILL simply contain all their children, inclusive of repeated keys, - /// in the same order which they appear in the JSON string. - /// - /// Note: For efficiency, this function WILL NOT make a copy of `s`. - /// The parsed tree WILL contain offsets to `s`. - /// Do NOT pass in a string that WILL be modified later on. - function parse(string memory s) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // We will use our own allocation instead. - } - bytes32 r = _query(_toInput(s), 255); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* JSON ITEM OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: - // - An item is a node in the JSON tree. - // - The value of a string item WILL be double-quoted, JSON encoded. - // - We make a distinction between `index` and `key`. - // - Items in arrays are located by `index` (uint256). - // - Items in objects are located by `key` (string). - // - Keys are always strings, double-quoted, JSON encoded. - // - // These design choices are made to balance between efficiency and ease-of-use. - - /// @dev Returns the string value of the item. - /// This is its exact string representation in the original JSON string. - /// The returned string WILL have leading and trailing whitespace trimmed. - /// All inner whitespace WILL be preserved, exactly as it is in the original JSON string. - /// If the item's type is string, the returned string WILL be double-quoted, JSON encoded. - /// - /// Note: This function lazily instantiates and caches the returned string. - /// Do NOT modify the returned string. - function value(Item memory item) internal pure returns (string memory result) { - bytes32 r = _query(_toInput(item), 0); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the index of the item in the array. - /// It the item's parent is not an array, returns 0. - function index(Item memory item) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - if and(mload(item), _PARENT_IS_ARRAY) { - result := and(_BITMASK_POINTER, shr(_BITPOS_KEY, mload(item))) - } - } - } - - /// @dev Returns the key of the item in the object. - /// It the item's parent is not an object, returns an empty string. - /// The returned string WILL be double-quoted, JSON encoded. - /// - /// Note: This function lazily instantiates and caches the returned string. - /// Do NOT modify the returned string. - function key(Item memory item) internal pure returns (string memory result) { - if (item._data & _PARENT_IS_OBJECT != 0) { - bytes32 r = _query(_toInput(item), 1); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - } - - /// @dev Returns the key of the item in the object. - /// It the item is neither an array nor object, returns an empty array. - /// - /// Note: This function lazily instantiates and caches the returned array. - /// Do NOT modify the returned array. - function children(Item memory item) internal pure returns (Item[] memory result) { - bytes32 r = _query(_toInput(item), 3); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the number of children. - /// It the item is neither an array nor object, returns zero. - function size(Item memory item) internal pure returns (uint256 result) { - bytes32 r = _query(_toInput(item), 3); - /// @solidity memory-safe-assembly - assembly { - result := mload(r) - } - } - - /// @dev Returns the item at index `i` for (array). - /// If `item` is not an array, the result's type WILL be undefined. - /// If there is no item with the index, the result's type WILL be undefined. - function at(Item memory item, uint256 i) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Free the default allocation. We'll allocate manually. - } - bytes32 r = _query(_toInput(item), 3); - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(r, 0x20), shl(5, i))) - if iszero(and(lt(i, mload(r)), eq(and(mload(item), _BITMASK_TYPE), TYPE_ARRAY))) { - result := 0x60 // Reset to the zero pointer. - } - } - } - - /// @dev Returns the item at key `k` for (object). - /// If `item` is not an object, the result's type WILL be undefined. - /// The key MUST be double-quoted, JSON encoded. This is for efficiency reasons. - /// - Correct : `item.at('"k"')`. - /// - Wrong : `item.at("k")`. - /// For duplicated keys, the last item with the key WILL be returned. - /// If there is no item with the key, the result's type WILL be undefined. - function at(Item memory item, string memory k) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Free the default allocation. We'll allocate manually. - result := 0x60 // Initialize to the zero pointer. - } - if (isObject(item)) { - bytes32 kHash = keccak256(bytes(k)); - Item[] memory r = children(item); - // We'll just do a linear search. The alternatives are very bloated. - for (uint256 i = r.length << 5; i != 0;) { - /// @solidity memory-safe-assembly - assembly { - item := mload(add(r, i)) - i := sub(i, 0x20) - } - if (keccak256(bytes(key(item))) != kHash) continue; - result = item; - break; - } - } - } - - /// @dev Returns the item's type. - function getType(Item memory item) internal pure returns (uint8 result) { - result = uint8(item._data & _BITMASK_TYPE); - } - - /// Note: All types are mutually exclusive. - - /// @dev Returns whether the item is of type undefined. - function isUndefined(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_UNDEFINED; - } - - /// @dev Returns whether the item is of type array. - function isArray(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_ARRAY; - } - - /// @dev Returns whether the item is of type object. - function isObject(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_OBJECT; - } - - /// @dev Returns whether the item is of type number. - function isNumber(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_NUMBER; - } - - /// @dev Returns whether the item is of type string. - function isString(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_STRING; - } - - /// @dev Returns whether the item is of type boolean. - function isBoolean(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_BOOLEAN; - } - - /// @dev Returns whether the item is of type null. - function isNull(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_NULL; - } - - /// @dev Returns the item's parent. - /// If the item does not have a parent, the result's type will be undefined. - function parent(Item memory item) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Free the default allocation. We've already allocated. - result := and(shr(_BITPOS_SIBLING_OR_PARENT, mload(item)), _BITMASK_POINTER) - if iszero(result) { result := 0x60 } // Reset to the zero pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UTILITY FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Parses an unsigned integer from a string (in decimal, i.e. base 10). - /// Reverts if `s` is not a valid uint256 string matching the RegEx `^[0-9]+$`, - /// or if the parsed number is too big for a uint256. - function parseUint(string memory s) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(s) - let preMulOverflowThres := div(not(0), 10) - for { let i := 0 } 1 {} { - i := add(i, 1) - let digit := sub(and(mload(add(s, i)), 0xff), 48) - let mulOverflowed := gt(result, preMulOverflowThres) - let product := mul(10, result) - result := add(product, digit) - n := mul(n, iszero(or(or(mulOverflowed, lt(result, product)), gt(digit, 9)))) - if iszero(lt(i, n)) { break } - } - if iszero(n) { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Parses a signed integer from a string (in decimal, i.e. base 10). - /// Reverts if `s` is not a valid int256 string matching the RegEx `^[+-]?[0-9]+$`, - /// or if the parsed number cannot fit within `[-2**255 .. 2**255 - 1]`. - function parseInt(string memory s) internal pure returns (int256 result) { - uint256 n = bytes(s).length; - uint256 sign; - uint256 isNegative; - /// @solidity memory-safe-assembly - assembly { - if n { - let c := and(mload(add(s, 1)), 0xff) - isNegative := eq(c, 45) - if or(eq(c, 43), isNegative) { - sign := c - s := add(s, 1) - mstore(s, sub(n, 1)) - } - if iszero(or(sign, lt(sub(c, 48), 10))) { s := 0x60 } - } - } - uint256 x = parseUint(s); - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(x, add(shl(255, 1), isNegative))) { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - if sign { - mstore(s, sign) - s := sub(s, 1) - mstore(s, n) - } - result := xor(x, mul(xor(x, add(not(x), 1)), isNegative)) - } - } - - /// @dev Parses an unsigned integer from a string (in hexadecimal, i.e. base 16). - /// Reverts if `s` is not a valid uint256 hex string matching the RegEx - /// `^(0[xX])?[0-9a-fA-F]+$`, or if the parsed number cannot fit within `[0 .. 2**256 - 1]`. - function parseUintFromHex(string memory s) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(s) - // Skip two if starts with '0x' or '0X'. - let i := shl(1, and(eq(0x3078, or(shr(240, mload(add(s, 0x20))), 0x20)), gt(n, 1))) - for {} 1 {} { - i := add(i, 1) - let c := - byte( - and(0x1f, shr(and(mload(add(s, i)), 0xff), 0x3e4088843e41bac000000000000)), - 0x3010a071000000b0104040208000c05090d060e0f - ) - n := mul(n, iszero(or(iszero(c), shr(252, result)))) - result := add(shl(4, result), sub(c, 1)) - if iszero(lt(i, n)) { break } - } - if iszero(n) { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Decodes a JSON encoded string. - /// The string MUST be double-quoted, JSON encoded. - /// Reverts if the string is invalid. - /// As you can see, it's pretty complex for a deceptively simple looking task. - function decodeString(string memory s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - function fail() { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - - function decodeUnicodeEscapeSequence(pIn_, end_) -> _unicode, _pOut { - _pOut := add(pIn_, 4) - let b_ := iszero(gt(_pOut, end_)) - let t_ := mload(pIn_) // Load the whole word. - for { let i_ := 0 } iszero(eq(i_, 4)) { i_ := add(i_, 1) } { - let c_ := sub(byte(i_, t_), 48) - if iszero(and(shr(c_, 0x7e0000007e03ff), b_)) { fail() } // Not hexadecimal. - c_ := sub(c_, add(mul(gt(c_, 16), 7), shl(5, gt(c_, 48)))) - _unicode := add(shl(4, _unicode), c_) - } - } - - function decodeUnicodeCodePoint(pIn_, end_) -> _unicode, _pOut { - _unicode, _pOut := decodeUnicodeEscapeSequence(pIn_, end_) - if iszero(or(lt(_unicode, 0xd800), gt(_unicode, 0xdbff))) { - let t_ := mload(_pOut) // Load the whole word. - end_ := mul(end_, eq(shr(240, t_), 0x5c75)) // Fail if not starting with '\\u'. - t_, _pOut := decodeUnicodeEscapeSequence(add(_pOut, 2), end_) - _unicode := add(0x10000, add(shl(10, and(0x3ff, _unicode)), and(0x3ff, t_))) - } - } - - function appendCodePointAsUTF8(pIn_, c_) -> _pOut { - if iszero(gt(c_, 0x7f)) { - mstore8(pIn_, c_) - _pOut := add(pIn_, 1) - leave - } - mstore8(0x1f, c_) - mstore8(0x1e, shr(6, c_)) - if iszero(gt(c_, 0x7ff)) { - mstore(pIn_, shl(240, or(0xc080, and(0x1f3f, mload(0x00))))) - _pOut := add(pIn_, 2) - leave - } - mstore8(0x1d, shr(12, c_)) - if iszero(gt(c_, 0xffff)) { - mstore(pIn_, shl(232, or(0xe08080, and(0x0f3f3f, mload(0x00))))) - _pOut := add(pIn_, 3) - leave - } - mstore8(0x1c, shr(18, c_)) - mstore(pIn_, shl(224, or(0xf0808080, and(0x073f3f3f, mload(0x00))))) - _pOut := add(pIn_, shl(2, lt(c_, 0x110000))) - } - - function chr(p_) -> _c { - _c := byte(0, mload(p_)) - } - - let n := mload(s) - let end := add(add(s, n), 0x1f) - if iszero(and(gt(n, 1), eq(0x2222, or(and(0xff00, mload(add(s, 2))), chr(end))))) { - fail() // Fail if not double-quoted. - } - let out := add(mload(0x40), 0x20) - for { let curr := add(s, 0x21) } iszero(eq(curr, end)) {} { - let c := chr(curr) - curr := add(curr, 1) - // Not '\\'. - if iszero(eq(c, 92)) { - // Not '"'. - if iszero(eq(c, 34)) { - mstore8(out, c) - out := add(out, 1) - continue - } - curr := end - } - if iszero(eq(curr, end)) { - let escape := chr(curr) - curr := add(curr, 1) - // '"', '/', '\\'. - if and(shr(escape, 0x100000000000800400000000), 1) { - mstore8(out, escape) - out := add(out, 1) - continue - } - // 'u'. - if eq(escape, 117) { - escape, curr := decodeUnicodeCodePoint(curr, end) - out := appendCodePointAsUTF8(out, escape) - continue - } - // `{'b':'\b', 'f':'\f', 'n':'\n', 'r':'\r', 't':'\t'}`. - escape := byte(sub(escape, 85), 0x080000000c000000000000000a0000000d0009) - if escape { - mstore8(out, escape) - out := add(out, 1) - continue - } - } - fail() - break - } - mstore(out, 0) // Zeroize the last slot. - result := mload(0x40) - mstore(result, sub(out, add(result, 0x20))) // Store the length. - mstore(0x40, add(out, 0x20)) // Allocate the memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Performs a query on the input with the given mode. - function _query(bytes32 input, uint256 mode) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - function fail() { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - - function chr(p_) -> _c { - _c := byte(0, mload(p_)) - } - - function skipWhitespace(pIn_, end_) -> _pOut { - for { _pOut := pIn_ } 1 { _pOut := add(_pOut, 1) } { - if iszero(and(shr(chr(_pOut), 0x100002600), 1)) { leave } // Not in ' \n\r\t'. - } - } - - function setP(packed_, bitpos_, p_) -> _packed { - // Perform an out-of-gas revert if `p_` exceeds `_BITMASK_POINTER`. - returndatacopy(returndatasize(), returndatasize(), gt(p_, _BITMASK_POINTER)) - _packed := or(and(not(shl(bitpos_, _BITMASK_POINTER)), packed_), shl(bitpos_, p_)) - } - - function getP(packed_, bitpos_) -> _p { - _p := and(_BITMASK_POINTER, shr(bitpos_, packed_)) - } - - function mallocItem(s_, packed_, pStart_, pCurr_, type_) -> _item { - _item := mload(0x40) - // forgefmt: disable-next-item - packed_ := setP(setP(packed_, _BITPOS_VALUE, sub(pStart_, add(s_, 0x20))), - _BITPOS_VALUE_LENGTH, sub(pCurr_, pStart_)) - mstore(_item, or(packed_, type_)) - mstore(0x40, add(_item, 0x20)) // Allocate memory. - } - - function parseValue(s_, sibling_, pIn_, end_) -> _item, _pOut { - let packed_ := setP(mload(0x00), _BITPOS_SIBLING_OR_PARENT, sibling_) - _pOut := skipWhitespace(pIn_, end_) - if iszero(lt(_pOut, end_)) { leave } - for { let c_ := chr(_pOut) } 1 {} { - // If starts with '"'. - if eq(c_, 34) { - let pStart_ := _pOut - _pOut := parseStringSub(s_, packed_, _pOut, end_) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_STRING) - break - } - // If starts with '['. - if eq(c_, 91) { - _item, _pOut := parseArray(s_, packed_, _pOut, end_) - break - } - // If starts with '{'. - if eq(c_, 123) { - _item, _pOut := parseObject(s_, packed_, _pOut, end_) - break - } - // If starts with any in '0123456789-'. - if and(shr(c_, shl(45, 0x1ff9)), 1) { - _item, _pOut := parseNumber(s_, packed_, _pOut, end_) - break - } - if iszero(gt(add(_pOut, 4), end_)) { - let pStart_ := _pOut - let w_ := shr(224, mload(_pOut)) - // 'true' in hex format. - if eq(w_, 0x74727565) { - _pOut := add(_pOut, 4) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_BOOLEAN) - break - } - // 'null' in hex format. - if eq(w_, 0x6e756c6c) { - _pOut := add(_pOut, 4) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_NULL) - break - } - } - if iszero(gt(add(_pOut, 5), end_)) { - let pStart_ := _pOut - let w_ := shr(216, mload(_pOut)) - // 'false' in hex format. - if eq(w_, 0x66616c7365) { - _pOut := add(_pOut, 5) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_BOOLEAN) - break - } - } - fail() - break - } - _pOut := skipWhitespace(_pOut, end_) - } - - function parseArray(s_, packed_, pIn_, end_) -> _item, _pOut { - let j_ := 0 - for { _pOut := add(pIn_, 1) } 1 { _pOut := add(_pOut, 1) } { - if iszero(lt(_pOut, end_)) { fail() } - if iszero(_item) { - _pOut := skipWhitespace(_pOut, end_) - if eq(chr(_pOut), 93) { break } // ']'. - } - _item, _pOut := parseValue(s_, _item, _pOut, end_) - if _item { - // forgefmt: disable-next-item - mstore(_item, setP(or(_PARENT_IS_ARRAY, mload(_item)), - _BITPOS_KEY, j_)) - j_ := add(j_, 1) - let c_ := chr(_pOut) - if eq(c_, 93) { break } // ']'. - if eq(c_, 44) { continue } // ','. - } - _pOut := end_ - } - _pOut := add(_pOut, 1) - packed_ := setP(packed_, _BITPOS_CHILD, _item) - _item := mallocItem(s_, packed_, pIn_, _pOut, TYPE_ARRAY) - } - - function parseObject(s_, packed_, pIn_, end_) -> _item, _pOut { - for { _pOut := add(pIn_, 1) } 1 { _pOut := add(_pOut, 1) } { - if iszero(lt(_pOut, end_)) { fail() } - if iszero(_item) { - _pOut := skipWhitespace(_pOut, end_) - if eq(chr(_pOut), 125) { break } // '}'. - } - _pOut := skipWhitespace(_pOut, end_) - let pKeyStart_ := _pOut - let pKeyEnd_ := parseStringSub(s_, _item, _pOut, end_) - _pOut := skipWhitespace(pKeyEnd_, end_) - // If ':'. - if eq(chr(_pOut), 58) { - _item, _pOut := parseValue(s_, _item, add(_pOut, 1), end_) - if _item { - // forgefmt: disable-next-item - mstore(_item, setP(setP(or(_PARENT_IS_OBJECT, mload(_item)), - _BITPOS_KEY_LENGTH, sub(pKeyEnd_, pKeyStart_)), - _BITPOS_KEY, sub(pKeyStart_, add(s_, 0x20)))) - let c_ := chr(_pOut) - if eq(c_, 125) { break } // '}'. - if eq(c_, 44) { continue } // ','. - } - } - _pOut := end_ - } - _pOut := add(_pOut, 1) - packed_ := setP(packed_, _BITPOS_CHILD, _item) - _item := mallocItem(s_, packed_, pIn_, _pOut, TYPE_OBJECT) - } - - function checkStringU(p_, o_) { - // If not in '0123456789abcdefABCDEF', revert. - if iszero(and(shr(sub(chr(add(p_, o_)), 48), 0x7e0000007e03ff), 1)) { fail() } - if iszero(eq(o_, 5)) { checkStringU(p_, add(o_, 1)) } - } - - function parseStringSub(s_, packed_, pIn_, end_) -> _pOut { - if iszero(lt(pIn_, end_)) { fail() } - for { _pOut := add(pIn_, 1) } 1 {} { - let c_ := chr(_pOut) - if eq(c_, 34) { break } // '"'. - // Not '\'. - if iszero(eq(c_, 92)) { - _pOut := add(_pOut, 1) - continue - } - c_ := chr(add(_pOut, 1)) - // '"', '\', '//', 'b', 'f', 'n', 'r', 't'. - if and(shr(sub(c_, 34), 0x510110400000000002001), 1) { - _pOut := add(_pOut, 2) - continue - } - // 'u'. - if eq(c_, 117) { - checkStringU(_pOut, 2) - _pOut := add(_pOut, 6) - continue - } - _pOut := end_ - break - } - if iszero(lt(_pOut, end_)) { fail() } - _pOut := add(_pOut, 1) - } - - function skip0To9s(pIn_, end_, atLeastOne_) -> _pOut { - for { _pOut := pIn_ } 1 { _pOut := add(_pOut, 1) } { - if iszero(lt(sub(chr(_pOut), 48), 10)) { break } // Not '0'..'9'. - } - if and(atLeastOne_, eq(pIn_, _pOut)) { fail() } - } - - function parseNumber(s_, packed_, pIn_, end_) -> _item, _pOut { - _pOut := pIn_ - if eq(chr(_pOut), 45) { _pOut := add(_pOut, 1) } // '-'. - if iszero(lt(sub(chr(_pOut), 48), 10)) { fail() } // Not '0'..'9'. - let c_ := chr(_pOut) - _pOut := add(_pOut, 1) - if iszero(eq(c_, 48)) { _pOut := skip0To9s(_pOut, end_, 0) } // Not '0'. - if eq(chr(_pOut), 46) { _pOut := skip0To9s(add(_pOut, 1), end_, 1) } // '.'. - let t_ := mload(_pOut) - // 'E', 'e'. - if eq(or(0x20, byte(0, t_)), 101) { - // forgefmt: disable-next-item - _pOut := skip0To9s(add(byte(sub(byte(1, t_), 14), 0x010001), // '+', '-'. - add(_pOut, 1)), end_, 1) - } - _item := mallocItem(s_, packed_, pIn_, _pOut, TYPE_NUMBER) - } - - function copyStr(s_, offset_, len_) -> _sCopy { - _sCopy := mload(0x40) - s_ := add(s_, offset_) - let w_ := not(0x1f) - for { let i_ := and(add(len_, 0x1f), w_) } 1 {} { - mstore(add(_sCopy, i_), mload(add(s_, i_))) - i_ := add(i_, w_) // `sub(i_, 0x20)`. - if iszero(i_) { break } - } - mstore(_sCopy, len_) // Copy the length. - mstore(add(add(_sCopy, 0x20), len_), 0) // Zeroize the last slot. - mstore(0x40, add(add(_sCopy, 0x40), len_)) // Allocate memory. - } - - function value(item_) -> _value { - let packed_ := mload(item_) - _value := getP(packed_, _BITPOS_VALUE) // The offset in the string. - if iszero(and(_VALUE_INITED, packed_)) { - let s_ := getP(packed_, _BITPOS_STRING) - _value := copyStr(s_, _value, getP(packed_, _BITPOS_VALUE_LENGTH)) - packed_ := setP(packed_, _BITPOS_VALUE, _value) - mstore(s_, or(_VALUE_INITED, packed_)) - } - } - - function children(item_) -> _arr { - _arr := 0x60 // Initialize to the zero pointer. - let packed_ := mload(item_) - for {} iszero(gt(and(_BITMASK_TYPE, packed_), TYPE_OBJECT)) {} { - if or(iszero(packed_), iszero(item_)) { break } - if and(packed_, _CHILDREN_INITED) { - _arr := getP(packed_, _BITPOS_CHILD) - break - } - _arr := mload(0x40) - let o_ := add(_arr, 0x20) - for { let h_ := getP(packed_, _BITPOS_CHILD) } h_ {} { - mstore(o_, h_) - let q_ := mload(h_) - let y_ := getP(q_, _BITPOS_SIBLING_OR_PARENT) - mstore(h_, setP(q_, _BITPOS_SIBLING_OR_PARENT, item_)) - h_ := y_ - o_ := add(o_, 0x20) - } - let w_ := not(0x1f) - let n_ := add(w_, sub(o_, _arr)) - mstore(_arr, shr(5, n_)) - mstore(0x40, o_) // Allocate memory. - packed_ := setP(packed_, _BITPOS_CHILD, _arr) - mstore(item_, or(_CHILDREN_INITED, packed_)) - // Reverse the array. - if iszero(lt(n_, 0x40)) { - let lo_ := add(_arr, 0x20) - let hi_ := add(_arr, n_) - for {} 1 {} { - let temp_ := mload(lo_) - mstore(lo_, mload(hi_)) - mstore(hi_, temp_) - hi_ := add(hi_, w_) - lo_ := add(lo_, 0x20) - if iszero(lt(lo_, hi_)) { break } - } - } - break - } - } - - function getStr(item_, bitpos_, bitposLength_, bitmaskInited_) -> _result { - _result := 0x60 // Initialize to the zero pointer. - let packed_ := mload(item_) - if or(iszero(item_), iszero(packed_)) { leave } - _result := getP(packed_, bitpos_) - if iszero(and(bitmaskInited_, packed_)) { - let s_ := getP(packed_, _BITPOS_STRING) - _result := copyStr(s_, _result, getP(packed_, bitposLength_)) - mstore(item_, or(bitmaskInited_, setP(packed_, bitpos_, _result))) - } - } - - switch mode - // Get value. - case 0 { result := getStr(input, _BITPOS_VALUE, _BITPOS_VALUE_LENGTH, _VALUE_INITED) } - // Get key. - case 1 { result := getStr(input, _BITPOS_KEY, _BITPOS_KEY_LENGTH, _KEY_INITED) } - // Get children. - case 3 { result := children(input) } - // Parse. - default { - let p := add(input, 0x20) - let e := add(p, mload(input)) - if iszero(eq(p, e)) { - let c := chr(e) - mstore8(e, 34) // Place a '"' at the end to speed up parsing. - // The `34 << 248` makes `mallocItem` preserve '"' at the end. - mstore(0x00, setP(shl(248, 34), _BITPOS_STRING, input)) - result, p := parseValue(input, 0, p, e) - mstore8(e, c) // Restore the original char at the end. - } - if or(lt(p, e), iszero(result)) { fail() } - } - } - } - - /// @dev Casts the input to a bytes32. - function _toInput(string memory input) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := input - } - } - - /// @dev Casts the input to a bytes32. - function _toInput(Item memory input) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := input - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibBit.sol b/grouperBot/lib/solady/src/utils/LibBit.sol deleted file mode 100644 index 4368325..0000000 --- a/grouperBot/lib/solady/src/utils/LibBit.sol +++ /dev/null @@ -1,309 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for bit twiddling and boolean operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol) -/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html) -library LibBit { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BIT TWIDDLING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Find last set. - /// Returns the index of the most significant bit of `x`, - /// counting from the least significant bit position. - /// If `x` is zero, returns 256. - function fls(uint256 x) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x))) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // forgefmt: disable-next-item - r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)), - 0x0706060506020504060203020504030106050205030304010505030400000000)) - } - } - - /// @dev Count leading zeros. - /// Returns the number of zeros preceding the most significant one bit. - /// If `x` is zero, returns 256. - function clz(uint256 x) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // forgefmt: disable-next-item - r := add(xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)), - 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff)), iszero(x)) - } - } - - /// @dev Find first set. - /// Returns the index of the least significant bit of `x`, - /// counting from the least significant bit position. - /// If `x` is zero, returns 256. - /// Equivalent to `ctz` (count trailing zeros), which gives - /// the number of zeros following the least significant one bit. - function ffs(uint256 x) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - // Isolate the least significant bit. - x := and(x, add(not(x), 1)) - // For the upper 3 bits of the result, use a De Bruijn-like lookup. - // Credit to adhusson: https://blog.adhusson.com/cheap-find-first-set-evm/ - // forgefmt: disable-next-item - r := shl(5, shr(252, shl(shl(2, shr(250, mul(x, - 0xb6db6db6ddddddddd34d34d349249249210842108c6318c639ce739cffffffff))), - 0x8040405543005266443200005020610674053026020000107506200176117077))) - // For the lower 5 bits of the result, use a De Bruijn lookup. - // forgefmt: disable-next-item - r := or(r, byte(and(div(0xd76453e0, shr(r, x)), 0x1f), - 0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405)) - } - } - - /// @dev Returns the number of set bits in `x`. - function popCount(uint256 x) internal pure returns (uint256 c) { - /// @solidity memory-safe-assembly - assembly { - let max := not(0) - let isMax := eq(x, max) - x := sub(x, and(shr(1, x), div(max, 3))) - x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5))) - x := and(add(x, shr(4, x)), div(max, 17)) - c := or(shl(8, isMax), shr(248, mul(x, div(max, 255)))) - } - } - - /// @dev Returns the number of zero bytes in `x`. - /// To get the number of non-zero bytes, simply do `32 - countZeroBytes(x)`. - function countZeroBytes(uint256 x) internal pure returns (uint256 c) { - /// @solidity memory-safe-assembly - assembly { - let m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f - c := byte(0, mul(shr(7, not(m)), shr(7, not(or(or(add(and(x, m), m), x), m))))) - } - } - - /// @dev Returns the number of zero bytes in `s`. - /// To get the number of non-zero bytes, simply do `s.length - countZeroBytes(s)`. - function countZeroBytes(bytes memory s) internal pure returns (uint256 c) { - /// @solidity memory-safe-assembly - assembly { - function czb(x_) -> _c { - let _m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f - _c := shr(7, not(or(or(add(and(x_, _m), _m), x_), _m))) - _c := byte(0, mul(shr(7, not(_m)), _c)) - } - let n := mload(s) - let l := shl(5, shr(5, n)) - s := add(s, 0x20) - for { let i } xor(i, l) { i := add(i, 0x20) } { c := add(czb(mload(add(s, i))), c) } - if lt(l, n) { c := add(czb(or(shr(shl(3, sub(n, l)), not(0)), mload(add(s, l)))), c) } - } - } - - /// @dev Returns the number of zero bytes in `s`. - /// To get the number of non-zero bytes, simply do `s.length - countZeroBytes(s)`. - function countZeroBytesCalldata(bytes calldata s) internal pure returns (uint256 c) { - /// @solidity memory-safe-assembly - assembly { - function czb(x_) -> _c { - let _m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f - _c := shr(7, not(or(or(add(and(x_, _m), _m), x_), _m))) - _c := byte(0, mul(shr(7, not(_m)), _c)) - } - let l := shl(5, shr(5, s.length)) - for { let i } xor(i, l) { i := add(i, 0x20) } { - c := add(czb(calldataload(add(s.offset, i))), c) - } - if lt(l, s.length) { - let m := shr(shl(3, sub(s.length, l)), not(0)) - c := add(czb(or(m, calldataload(add(s.offset, l)))), c) - } - } - } - - /// @dev Returns whether `x` is a power of 2. - function isPo2(uint256 x) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - // Equivalent to `x && !(x & (x - 1))`. - result := iszero(add(and(x, sub(x, 1)), iszero(x))) - } - } - - /// @dev Returns `x` reversed at the bit level. - function reverseBits(uint256 x) internal pure returns (uint256 r) { - uint256 m0 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; - uint256 m1 = m0 ^ (m0 << 2); - uint256 m2 = m1 ^ (m1 << 1); - r = reverseBytes(x); - r = (m2 & (r >> 1)) | ((m2 & r) << 1); - r = (m1 & (r >> 2)) | ((m1 & r) << 2); - r = (m0 & (r >> 4)) | ((m0 & r) << 4); - } - - /// @dev Returns `x` reversed at the byte level. - function reverseBytes(uint256 x) internal pure returns (uint256 r) { - unchecked { - // Computing masks on-the-fly reduces bytecode size by about 200 bytes. - uint256 m0 = 0x100000000000000000000000000000001 * (~toUint(x == uint256(0)) >> 192); - uint256 m1 = m0 ^ (m0 << 32); - uint256 m2 = m1 ^ (m1 << 16); - uint256 m3 = m2 ^ (m2 << 8); - r = (m3 & (x >> 8)) | ((m3 & x) << 8); - r = (m2 & (r >> 16)) | ((m2 & r) << 16); - r = (m1 & (r >> 32)) | ((m1 & r) << 32); - r = (m0 & (r >> 64)) | ((m0 & r) << 64); - r = (r >> 128) | (r << 128); - } - } - - /// @dev Returns the common prefix of `x` and `y` at the bit level. - function commonBitPrefix(uint256 x, uint256 y) internal pure returns (uint256) { - unchecked { - uint256 s = 256 - clz(x ^ y); - return (x >> s) << s; - } - } - - /// @dev Returns the common prefix of `x` and `y` at the nibble level. - function commonNibblePrefix(uint256 x, uint256 y) internal pure returns (uint256) { - unchecked { - uint256 s = (64 - (clz(x ^ y) >> 2)) << 2; - return (x >> s) << s; - } - } - - /// @dev Returns the common prefix of `x` and `y` at the byte level. - function commonBytePrefix(uint256 x, uint256 y) internal pure returns (uint256) { - unchecked { - uint256 s = (32 - (clz(x ^ y) >> 3)) << 3; - return (x >> s) << s; - } - } - - /// @dev hex"ABCD" -> hex"0A0B0C0D". - function toNibbles(bytes memory s) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let n := mload(s) - mstore(result, add(n, n)) // Store the new length. - s := add(s, 0x20) - let o := add(result, 0x20) - // forgefmt: disable-next-item - for { let i := 0 } lt(i, n) { i := add(i, 0x10) } { - let x := shr(128, mload(add(s, i))) - x := and(0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff, or(shl(64, x), x)) - x := and(0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff, or(shl(32, x), x)) - x := and(0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff, or(shl(16, x), x)) - x := and(0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff, or(shl(8, x), x)) - mstore(add(o, add(i, i)), - and(0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f, or(shl(4, x), x))) - } - mstore(add(o, add(s, s)), 0) // Zeroize slot after result. - mstore(0x40, add(0x40, add(o, add(s, s)))) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BOOLEAN OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // A Solidity bool on the stack or memory is represented as a 256-bit word. - // Non-zero values are true, zero is false. - // A clean bool is either 0 (false) or 1 (true) under the hood. - // Usually, if not always, the bool result of a regular Solidity expression, - // or the argument of a public/external function will be a clean bool. - // You can usually use the raw variants for more performance. - // If uncertain, test (best with exact compiler settings). - // Or use the non-raw variants (compiler can sometimes optimize out the double `iszero`s). - - /// @dev Returns `x & y`. Inputs must be clean. - function rawAnd(bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := and(x, y) - } - } - - /// @dev Returns `x & y`. - function and(bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := and(iszero(iszero(x)), iszero(iszero(y))) - } - } - - /// @dev Returns `w & x & y`. - function and(bool w, bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := iszero(or(iszero(w), or(iszero(x), iszero(y)))) - } - } - - /// @dev Returns `v & w & x & y`. - function and(bool v, bool w, bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := iszero(or(or(iszero(v), iszero(w)), or(iszero(x), iszero(y)))) - } - } - - /// @dev Returns `x | y`. Inputs must be clean. - function rawOr(bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := or(x, y) - } - } - - /// @dev Returns `x | y`. - function or(bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := iszero(iszero(or(x, y))) - } - } - - /// @dev Returns `w | x | y`. - function or(bool w, bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := iszero(iszero(or(w, or(x, y)))) - } - } - - /// @dev Returns `v | w | x | y`. - function or(bool v, bool w, bool x, bool y) internal pure returns (bool z) { - /// @solidity memory-safe-assembly - assembly { - z := iszero(iszero(or(v, or(w, or(x, y))))) - } - } - - /// @dev Returns 1 if `b` is true, else 0. Input must be clean. - function rawToUint(bool b) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := b - } - } - - /// @dev Returns 1 if `b` is true, else 0. - function toUint(bool b) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := iszero(iszero(b)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibBitmap.sol b/grouperBot/lib/solady/src/utils/LibBitmap.sol deleted file mode 100644 index c4094c5..0000000 --- a/grouperBot/lib/solady/src/utils/LibBitmap.sol +++ /dev/null @@ -1,236 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {LibBit} from "./LibBit.sol"; - -/// @notice Library for storage of packed unsigned booleans. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBitmap.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol) -/// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol) -library LibBitmap { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when a bitmap scan does not find a result. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A bitmap in storage. - struct Bitmap { - mapping(uint256 => uint256) map; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the boolean value of the bit at `index` in `bitmap`. - function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) { - // It is better to set `isSet` to either 0 or 1, than zero vs non-zero. - // Both cost the same amount of gas, but the former allows the returned value - // to be reused without cleaning the upper bits. - uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1; - /// @solidity memory-safe-assembly - assembly { - isSet := b - } - } - - /// @dev Updates the bit at `index` in `bitmap` to true. - function set(Bitmap storage bitmap, uint256 index) internal { - bitmap.map[index >> 8] |= (1 << (index & 0xff)); - } - - /// @dev Updates the bit at `index` in `bitmap` to false. - function unset(Bitmap storage bitmap, uint256 index) internal { - bitmap.map[index >> 8] &= ~(1 << (index & 0xff)); - } - - /// @dev Flips the bit at `index` in `bitmap`. - /// Returns the boolean result of the flipped bit. - function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, index)) - let storageSlot := keccak256(0x00, 0x40) - let shift := and(index, 0xff) - let storageValue := xor(sload(storageSlot), shl(shift, 1)) - // It makes sense to return the `newIsSet`, - // as it allow us to skip an additional warm `sload`, - // and it costs minimal gas (about 15), - // which may be optimized away if the returned value is unused. - newIsSet := and(1, shr(shift, storageValue)) - sstore(storageSlot, storageValue) - } - } - - /// @dev Updates the bit at `index` in `bitmap` to `shouldSet`. - function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, index)) - let storageSlot := keccak256(0x00, 0x40) - let storageValue := sload(storageSlot) - let shift := and(index, 0xff) - sstore( - storageSlot, - // Unsets the bit at `shift` via `and`, then sets its new value via `or`. - or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet)))) - ) - } - } - - /// @dev Consecutively sets `amount` of bits starting from the bit at `start`. - function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - let max := not(0) - let shift := and(start, 0xff) - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, start)) - if iszero(lt(add(shift, amount), 257)) { - let storageSlot := keccak256(0x00, 0x40) - sstore(storageSlot, or(sload(storageSlot), shl(shift, max))) - let bucket := add(mload(0x00), 1) - let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) - amount := and(add(amount, shift), 0xff) - shift := 0 - for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { - mstore(0x00, bucket) - sstore(keccak256(0x00, 0x40), max) - } - mstore(0x00, bucket) - } - let storageSlot := keccak256(0x00, 0x40) - sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max)))) - } - } - - /// @dev Consecutively unsets `amount` of bits starting from the bit at `start`. - function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - let shift := and(start, 0xff) - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, start)) - if iszero(lt(add(shift, amount), 257)) { - let storageSlot := keccak256(0x00, 0x40) - sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0))))) - let bucket := add(mload(0x00), 1) - let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) - amount := and(add(amount, shift), 0xff) - shift := 0 - for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { - mstore(0x00, bucket) - sstore(keccak256(0x00, 0x40), 0) - } - mstore(0x00, bucket) - } - let storageSlot := keccak256(0x00, 0x40) - sstore( - storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0))))) - ) - } - } - - /// @dev Returns number of set bits within a range by - /// scanning `amount` of bits starting from the bit at `start`. - function popCount(Bitmap storage bitmap, uint256 start, uint256 amount) - internal - view - returns (uint256 count) - { - unchecked { - uint256 bucket = start >> 8; - uint256 shift = start & 0xff; - if (!(amount + shift < 257)) { - count = LibBit.popCount(bitmap.map[bucket] >> shift); - uint256 bucketEnd = bucket + ((amount + shift) >> 8); - amount = (amount + shift) & 0xff; - shift = 0; - for (++bucket; bucket != bucketEnd; ++bucket) { - count += LibBit.popCount(bitmap.map[bucket]); - } - } - count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount)); - } - } - - /// @dev Returns the index of the most significant set bit in `[0..upTo]`. - /// If no set bit is found, returns `NOT_FOUND`. - function findLastSet(Bitmap storage bitmap, uint256 upTo) - internal - view - returns (uint256 setBitIndex) - { - setBitIndex = NOT_FOUND; - uint256 bucket = upTo >> 8; - uint256 bits; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, bucket) - mstore(0x20, bitmap.slot) - let offset := and(0xff, not(upTo)) // `256 - (255 & upTo) - 1`. - bits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40)))) - if iszero(or(bits, iszero(bucket))) { - for {} 1 {} { - bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`. - mstore(0x00, bucket) - bits := sload(keccak256(0x00, 0x40)) - if or(bits, iszero(bucket)) { break } - } - } - } - if (bits != 0) { - setBitIndex = (bucket << 8) | LibBit.fls(bits); - /// @solidity memory-safe-assembly - assembly { - setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, upTo))) - } - } - } - - /// @dev Returns the index of the least significant unset bit in `[begin..upTo]`. - /// If no unset bit is found, returns `NOT_FOUND`. - function findFirstUnset(Bitmap storage bitmap, uint256 begin, uint256 upTo) - internal - view - returns (uint256 unsetBitIndex) - { - unsetBitIndex = NOT_FOUND; - uint256 bucket = begin >> 8; - uint256 negBits; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, bucket) - mstore(0x20, bitmap.slot) - let offset := and(0xff, begin) - negBits := shl(offset, shr(offset, not(sload(keccak256(0x00, 0x40))))) - if iszero(negBits) { - let lastBucket := shr(8, upTo) - for {} 1 {} { - bucket := add(bucket, 1) - mstore(0x00, bucket) - negBits := not(sload(keccak256(0x00, 0x40))) - if or(negBits, gt(bucket, lastBucket)) { break } - } - if gt(bucket, lastBucket) { - negBits := shl(and(0xff, not(upTo)), shr(and(0xff, not(upTo)), negBits)) - } - } - } - if (negBits != 0) { - uint256 r = (bucket << 8) | LibBit.ffs(negBits); - /// @solidity memory-safe-assembly - assembly { - unsetBitIndex := or(r, sub(0, or(gt(r, upTo), lt(r, begin)))) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibBytes.sol b/grouperBot/lib/solady/src/utils/LibBytes.sol deleted file mode 100644 index 7541b5b..0000000 --- a/grouperBot/lib/solady/src/utils/LibBytes.sol +++ /dev/null @@ -1,888 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for byte related operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBytes.sol) -library LibBytes { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Goated bytes storage struct that totally MOGs, no cap, fr. - /// Uses less gas and bytecode than Solidity's native bytes storage. It's meta af. - /// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight. - struct BytesStorage { - bytes32 _spacer; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when the `search` is not found in the bytes. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTE STORAGE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the value of the bytes storage `$` to `s`. - function set(BytesStorage storage $, bytes memory s) internal { - /// @solidity memory-safe-assembly - assembly { - let n := mload(s) - let packed := or(0xff, shl(8, n)) - for { let i := 0 } 1 {} { - if iszero(gt(n, 0xfe)) { - i := 0x1f - packed := or(n, shl(8, mload(add(s, i)))) - if iszero(gt(n, i)) { break } - } - let o := add(s, 0x20) - mstore(0x00, $.slot) - for { let p := keccak256(0x00, 0x20) } 1 {} { - sstore(add(p, shr(5, i)), mload(add(o, i))) - i := add(i, 0x20) - if iszero(lt(i, n)) { break } - } - break - } - sstore($.slot, packed) - } - } - - /// @dev Sets the value of the bytes storage `$` to `s`. - function setCalldata(BytesStorage storage $, bytes calldata s) internal { - /// @solidity memory-safe-assembly - assembly { - let packed := or(0xff, shl(8, s.length)) - for { let i := 0 } 1 {} { - if iszero(gt(s.length, 0xfe)) { - i := 0x1f - packed := or(s.length, shl(8, shr(8, calldataload(s.offset)))) - if iszero(gt(s.length, i)) { break } - } - mstore(0x00, $.slot) - for { let p := keccak256(0x00, 0x20) } 1 {} { - sstore(add(p, shr(5, i)), calldataload(add(s.offset, i))) - i := add(i, 0x20) - if iszero(lt(i, s.length)) { break } - } - break - } - sstore($.slot, packed) - } - } - - /// @dev Sets the value of the bytes storage `$` to the empty bytes. - function clear(BytesStorage storage $) internal { - delete $._spacer; - } - - /// @dev Returns whether the value stored is `$` is the empty bytes "". - function isEmpty(BytesStorage storage $) internal view returns (bool) { - return uint256($._spacer) & 0xff == uint256(0); - } - - /// @dev Returns the length of the value stored in `$`. - function length(BytesStorage storage $) internal view returns (uint256 result) { - result = uint256($._spacer); - /// @solidity memory-safe-assembly - assembly { - let n := and(0xff, result) - result := or(mul(shr(8, result), eq(0xff, n)), mul(n, iszero(eq(0xff, n)))) - } - } - - /// @dev Returns the value stored in `$`. - function get(BytesStorage storage $) internal view returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let o := add(result, 0x20) - let packed := sload($.slot) - let n := shr(8, packed) - for { let i := 0 } 1 {} { - if iszero(eq(or(packed, 0xff), packed)) { - mstore(o, packed) - n := and(0xff, packed) - i := 0x1f - if iszero(gt(n, i)) { break } - } - mstore(0x00, $.slot) - for { let p := keccak256(0x00, 0x20) } 1 {} { - mstore(add(o, i), sload(add(p, shr(5, i)))) - i := add(i, 0x20) - if iszero(lt(i, n)) { break } - } - break - } - mstore(result, n) // Store the length of the memory. - mstore(add(o, n), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(o, n), 0x20)) // Allocate memory. - } - } - - /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0. - function uint8At(BytesStorage storage $, uint256 i) internal view returns (uint8 result) { - /// @solidity memory-safe-assembly - assembly { - for { let packed := sload($.slot) } 1 {} { - if iszero(eq(or(packed, 0xff), packed)) { - if iszero(gt(i, 0x1e)) { - result := byte(i, packed) - break - } - if iszero(gt(i, and(0xff, packed))) { - mstore(0x00, $.slot) - let j := sub(i, 0x1f) - result := byte(and(j, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, j)))) - } - break - } - if iszero(gt(i, shr(8, packed))) { - mstore(0x00, $.slot) - result := byte(and(i, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, i)))) - } - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTES OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`. - function replace(bytes memory subject, bytes memory needle, bytes memory replacement) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let needleLen := mload(needle) - let replacementLen := mload(replacement) - let d := sub(result, subject) // Memory difference. - let i := add(subject, 0x20) // Subject bytes pointer. - mstore(0x00, add(i, mload(subject))) // End of subject. - if iszero(gt(needleLen, mload(subject))) { - let subjectSearchEnd := add(sub(mload(0x00), needleLen), 1) - let h := 0 // The hash of `needle`. - if iszero(lt(needleLen, 0x20)) { h := keccak256(add(needle, 0x20), needleLen) } - let s := mload(add(needle, 0x20)) - for { let m := shl(3, sub(0x20, and(needleLen, 0x1f))) } 1 {} { - let t := mload(i) - // Whether the first `needleLen % 32` bytes of `subject` and `needle` matches. - if iszero(shr(m, xor(t, s))) { - if h { - if iszero(eq(keccak256(i, needleLen), h)) { - mstore(add(i, d), t) - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - // Copy the `replacement` one word at a time. - for { let j := 0 } 1 {} { - mstore(add(add(i, d), j), mload(add(add(replacement, 0x20), j))) - j := add(j, 0x20) - if iszero(lt(j, replacementLen)) { break } - } - d := sub(add(d, replacementLen), needleLen) - if needleLen { - i := add(i, needleLen) - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - mstore(add(i, d), t) - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - } - } - let end := mload(0x00) - let n := add(sub(d, add(result, 0x20)), end) - // Copy the rest of the bytes one word at a time. - for {} lt(i, end) { i := add(i, 0x20) } { mstore(add(i, d), mload(i)) } - let o := add(i, d) - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate memory. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(bytes memory subject, bytes memory needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) // Initialize to `NOT_FOUND`. - for { let subjectLen := mload(subject) } 1 {} { - if iszero(mload(needle)) { - result := from - if iszero(gt(from, subjectLen)) { break } - result := subjectLen - break - } - let needleLen := mload(needle) - let subjectStart := add(subject, 0x20) - - subject := add(subjectStart, from) - let end := add(sub(add(subjectStart, subjectLen), needleLen), 1) - let m := shl(3, sub(0x20, and(needleLen, 0x1f))) - let s := mload(add(needle, 0x20)) - - if iszero(and(lt(subject, end), lt(from, subjectLen))) { break } - - if iszero(lt(needleLen, 0x20)) { - for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} { - if iszero(shr(m, xor(mload(subject), s))) { - if eq(keccak256(subject, needleLen), h) { - result := sub(subject, subjectStart) - break - } - } - subject := add(subject, 1) - if iszero(lt(subject, end)) { break } - } - break - } - for {} 1 {} { - if iszero(shr(m, xor(mload(subject), s))) { - result := sub(subject, subjectStart) - break - } - subject := add(subject, 1) - if iszero(lt(subject, end)) { break } - } - break - } - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right, starting from `from`. Optimized for byte needles. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOfByte(bytes memory subject, bytes1 needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) // Initialize to `NOT_FOUND`. - if gt(mload(subject), from) { - let start := add(subject, 0x20) - let end := add(start, mload(subject)) - let m := div(not(0), 255) // `0x0101 ... `. - let h := mul(byte(0, needle), m) // Replicating needle mask. - m := not(shl(7, m)) // `0x7f7f ... `. - for { let i := add(start, from) } 1 {} { - let c := xor(mload(i), h) // Load 32-byte chunk and xor with mask. - c := not(or(or(add(and(c, m), m), c), m)) // Each needle byte will be `0x80`. - if c { - c := and(not(shr(shl(3, sub(end, i)), not(0))), c) // Truncate bytes past the end. - if c { - let r := shl(7, lt(0x8421084210842108cc6318c6db6d54be, c)) // Save bytecode. - r := or(shl(6, lt(0xffffffffffffffff, shr(r, c))), r) - // forgefmt: disable-next-item - result := add(sub(i, start), shr(3, xor(byte(and(0x1f, shr(byte(24, - mul(0x02040810204081, shr(r, c))), 0x8421084210842108cc6318c6db6d54be)), - 0xc0c8c8d0c8e8d0d8c8e8e0e8d0d8e0f0c8d0e8d0e0e0d8f0d0d0e0d8f8f8f8f8), r))) - break - } - } - i := add(i, 0x20) - if iszero(lt(i, end)) { break } - } - } - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right. Optimized for byte needles. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOfByte(bytes memory subject, bytes1 needle) - internal - pure - returns (uint256 result) - { - return indexOfByte(subject, needle, 0); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(bytes memory subject, bytes memory needle) internal pure returns (uint256) { - return indexOf(subject, needle, 0); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(bytes memory subject, bytes memory needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - result := not(0) // Initialize to `NOT_FOUND`. - let needleLen := mload(needle) - if gt(needleLen, mload(subject)) { break } - let w := result - - let fromMax := sub(mload(subject), needleLen) - if iszero(gt(fromMax, from)) { from := fromMax } - - let end := add(add(subject, 0x20), w) - subject := add(add(subject, 0x20), from) - if iszero(gt(subject, end)) { break } - // As this function is not too often used, - // we shall simply use keccak256 for smaller bytecode size. - for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} { - if eq(keccak256(subject, needleLen), h) { - result := sub(subject, add(end, 1)) - break - } - subject := add(subject, w) // `sub(subject, 1)`. - if iszero(gt(subject, end)) { break } - } - break - } - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(bytes memory subject, bytes memory needle) - internal - pure - returns (uint256) - { - return lastIndexOf(subject, needle, type(uint256).max); - } - - /// @dev Returns true if `needle` is found in `subject`, false otherwise. - function contains(bytes memory subject, bytes memory needle) internal pure returns (bool) { - return indexOf(subject, needle) != NOT_FOUND; - } - - /// @dev Returns whether `subject` starts with `needle`. - function startsWith(bytes memory subject, bytes memory needle) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(needle) - // Just using keccak256 directly is actually cheaper. - let t := eq(keccak256(add(subject, 0x20), n), keccak256(add(needle, 0x20), n)) - result := lt(gt(n, mload(subject)), t) - } - } - - /// @dev Returns whether `subject` ends with `needle`. - function endsWith(bytes memory subject, bytes memory needle) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(needle) - let notInRange := gt(n, mload(subject)) - // `subject + 0x20 + max(subject.length - needle.length, 0)`. - let t := add(add(subject, 0x20), mul(iszero(notInRange), sub(mload(subject), n))) - // Just using keccak256 directly is actually cheaper. - result := gt(eq(keccak256(t, n), keccak256(add(needle, 0x20), n)), notInRange) - } - } - - /// @dev Returns `subject` repeated `times`. - function repeat(bytes memory subject, uint256 times) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - let l := mload(subject) // Subject length. - if iszero(or(iszero(times), iszero(l))) { - result := mload(0x40) - subject := add(subject, 0x20) - let o := add(result, 0x20) - for {} 1 {} { - // Copy the `subject` one word at a time. - for { let j := 0 } 1 {} { - mstore(add(o, j), mload(add(subject, j))) - j := add(j, 0x20) - if iszero(lt(j, l)) { break } - } - o := add(o, l) - times := sub(times, 1) - if iszero(times) { break } - } - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate memory. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - } - } - } - - /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function slice(bytes memory subject, uint256 start, uint256 end) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - let l := mload(subject) // Subject length. - if iszero(gt(l, end)) { end := l } - if iszero(gt(l, start)) { start := l } - if lt(start, end) { - result := mload(0x40) - let n := sub(end, start) - let i := add(subject, start) - let w := not(0x1f) - // Copy the `subject` one word at a time, backwards. - for { let j := and(add(n, 0x1f), w) } 1 {} { - mstore(add(result, j), mload(add(i, j))) - j := add(j, w) // `sub(j, 0x20)`. - if iszero(j) { break } - } - let o := add(add(result, 0x20), n) - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate memory. - mstore(result, n) // Store the length. - } - } - } - - /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes. - /// `start` is a byte offset. - function slice(bytes memory subject, uint256 start) - internal - pure - returns (bytes memory result) - { - result = slice(subject, start, type(uint256).max); - } - - /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. Faster than Solidity's native slicing. - function sliceCalldata(bytes calldata subject, uint256 start, uint256 end) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - end := xor(end, mul(xor(end, subject.length), lt(subject.length, end))) - start := xor(start, mul(xor(start, subject.length), lt(subject.length, start))) - result.offset := add(subject.offset, start) - result.length := mul(lt(start, end), sub(end, start)) - } - } - - /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes. - /// `start` is a byte offset. Faster than Solidity's native slicing. - function sliceCalldata(bytes calldata subject, uint256 start) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - start := xor(start, mul(xor(start, subject.length), lt(subject.length, start))) - result.offset := add(subject.offset, start) - result.length := mul(lt(start, subject.length), sub(subject.length, start)) - } - } - - /// @dev Reduces the size of `subject` to `n`. - /// If `n` is greater than the size of `subject`, this will be a no-op. - function truncate(bytes memory subject, uint256 n) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := subject - mstore(mul(lt(n, mload(result)), result), n) - } - } - - /// @dev Returns a copy of `subject`, with the length reduced to `n`. - /// If `n` is greater than the size of `subject`, this will be a no-op. - function truncatedCalldata(bytes calldata subject, uint256 n) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - result.offset := subject.offset - result.length := xor(n, mul(xor(n, subject.length), lt(subject.length, n))) - } - } - - /// @dev Returns all the indices of `needle` in `subject`. - /// The indices are byte offsets. - function indicesOf(bytes memory subject, bytes memory needle) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - let searchLen := mload(needle) - if iszero(gt(searchLen, mload(subject))) { - result := mload(0x40) - let i := add(subject, 0x20) - let o := add(result, 0x20) - let subjectSearchEnd := add(sub(add(i, mload(subject)), searchLen), 1) - let h := 0 // The hash of `needle`. - if iszero(lt(searchLen, 0x20)) { h := keccak256(add(needle, 0x20), searchLen) } - let s := mload(add(needle, 0x20)) - for { let m := shl(3, sub(0x20, and(searchLen, 0x1f))) } 1 {} { - let t := mload(i) - // Whether the first `searchLen % 32` bytes of `subject` and `needle` matches. - if iszero(shr(m, xor(t, s))) { - if h { - if iszero(eq(keccak256(i, searchLen), h)) { - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - mstore(o, sub(i, add(subject, 0x20))) // Append to `result`. - o := add(o, 0x20) - i := add(i, searchLen) // Advance `i` by `searchLen`. - if searchLen { - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - } - mstore(result, shr(5, sub(o, add(result, 0x20)))) // Store the length of `result`. - // Allocate memory for result. - // We allocate one more word, so this array can be recycled for {split}. - mstore(0x40, add(o, 0x20)) - } - } - } - - /// @dev Returns an arrays of bytess based on the `delimiter` inside of the `subject` bytes. - function split(bytes memory subject, bytes memory delimiter) - internal - pure - returns (bytes[] memory result) - { - uint256[] memory indices = indicesOf(subject, delimiter); - /// @solidity memory-safe-assembly - assembly { - let w := not(0x1f) - let indexPtr := add(indices, 0x20) - let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1))) - mstore(add(indicesEnd, w), mload(subject)) - mstore(indices, add(mload(indices), 1)) - for { let prevIndex := 0 } 1 {} { - let index := mload(indexPtr) - mstore(indexPtr, 0x60) - if iszero(eq(index, prevIndex)) { - let element := mload(0x40) - let l := sub(index, prevIndex) - mstore(element, l) // Store the length of the element. - // Copy the `subject` one word at a time, backwards. - for { let o := and(add(l, 0x1f), w) } 1 {} { - mstore(add(element, o), mload(add(add(subject, prevIndex), o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(add(add(element, 0x20), l), 0) // Zeroize the slot after the bytes. - // Allocate memory for the length and the bytes, rounded up to a multiple of 32. - mstore(0x40, add(element, and(add(l, 0x3f), w))) - mstore(indexPtr, element) // Store the `element` into the array. - } - prevIndex := add(index, mload(delimiter)) - indexPtr := add(indexPtr, 0x20) - if iszero(lt(indexPtr, indicesEnd)) { break } - } - result := indices - if iszero(mload(delimiter)) { - result := add(indices, 0x20) - mstore(result, sub(mload(indices), 2)) - } - } - } - - /// @dev Returns a concatenated bytes of `a` and `b`. - /// Cheaper than `bytes.concat()` and does not de-align the free memory pointer. - function concat(bytes memory a, bytes memory b) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let w := not(0x1f) - let aLen := mload(a) - // Copy `a` one word at a time, backwards. - for { let o := and(add(aLen, 0x20), w) } 1 {} { - mstore(add(result, o), mload(add(a, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - let bLen := mload(b) - let output := add(result, aLen) - // Copy `b` one word at a time, backwards. - for { let o := and(add(bLen, 0x20), w) } 1 {} { - mstore(add(output, o), mload(add(b, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - let totalLen := add(aLen, bLen) - let last := add(add(result, 0x20), totalLen) - mstore(last, 0) // Zeroize the slot after the bytes. - mstore(result, totalLen) // Store the length. - mstore(0x40, add(last, 0x20)) // Allocate memory. - } - } - - /// @dev Returns whether `a` equals `b`. - function eq(bytes memory a, bytes memory b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b))) - } - } - - /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small bytes. - function eqs(bytes memory a, bytes32 b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - // These should be evaluated on compile time, as far as possible. - let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`. - let x := not(or(m, or(b, add(m, and(b, m))))) - let r := shl(7, iszero(iszero(shr(128, x)))) - r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x)))))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // forgefmt: disable-next-item - result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))), - xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20))))) - } - } - - /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`. - /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1. - function cmp(bytes memory a, bytes memory b) internal pure returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - let aLen := mload(a) - let bLen := mload(b) - let n := and(xor(aLen, mul(xor(aLen, bLen), lt(bLen, aLen))), not(0x1f)) - if n { - for { let i := 0x20 } 1 {} { - let x := mload(add(a, i)) - let y := mload(add(b, i)) - if iszero(or(xor(x, y), eq(i, n))) { - i := add(i, 0x20) - continue - } - result := sub(gt(x, y), lt(x, y)) - break - } - } - // forgefmt: disable-next-item - if iszero(result) { - let l := 0x201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201 - let x := and(mload(add(add(a, 0x20), n)), shl(shl(3, byte(sub(aLen, n), l)), not(0))) - let y := and(mload(add(add(b, 0x20), n)), shl(shl(3, byte(sub(bLen, n), l)), not(0))) - result := sub(gt(x, y), lt(x, y)) - if iszero(result) { result := sub(gt(aLen, bLen), lt(aLen, bLen)) } - } - } - } - - /// @dev Directly returns `a` without copying. - function directReturn(bytes memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - // Assumes that the bytes does not start from the scratch space. - let retStart := sub(a, 0x20) - let retUnpaddedSize := add(mload(a), 0x40) - // Right pad with zeroes. Just in case the bytes is produced - // by a method that doesn't zero right pad. - mstore(add(retStart, retUnpaddedSize), 0) - mstore(retStart, 0x20) // Store the return offset. - // End the transaction, returning the bytes. - return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize))) - } - } - - /// @dev Directly returns `a` with minimal copying. - function directReturn(bytes[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) // `a.length`. - let o := add(a, 0x20) // Start of elements in `a`. - let u := a // Highest memory slot. - let w := not(0x1f) - for { let i := 0 } iszero(eq(i, n)) { i := add(i, 1) } { - let c := add(o, shl(5, i)) // Location of pointer to `a[i]`. - let s := mload(c) // `a[i]`. - let l := mload(s) // `a[i].length`. - let r := and(l, 0x1f) // `a[i].length % 32`. - let z := add(0x20, and(l, w)) // Offset of last word in `a[i]` from `s`. - // If `s` comes before `o`, or `s` is not zero right padded. - if iszero(lt(lt(s, o), or(iszero(r), iszero(shl(shl(3, r), mload(add(s, z))))))) { - let m := mload(0x40) - mstore(m, l) // Copy `a[i].length`. - for {} 1 {} { - mstore(add(m, z), mload(add(s, z))) // Copy `a[i]`, backwards. - z := add(z, w) // `sub(z, 0x20)`. - if iszero(z) { break } - } - let e := add(add(m, 0x20), l) - mstore(e, 0) // Zeroize the slot after the copied bytes. - mstore(0x40, add(e, 0x20)) // Allocate memory. - s := m - } - mstore(c, sub(s, o)) // Convert to calldata offset. - let t := add(l, add(s, 0x20)) - if iszero(lt(t, u)) { u := t } - } - let retStart := add(a, w) // Assumes `a` doesn't start from scratch space. - mstore(retStart, 0x20) // Store the return offset. - return(retStart, add(0x40, sub(u, retStart))) // End the transaction. - } - } - - /// @dev Returns the word at `offset`, without any bounds checks. - function load(bytes memory a, uint256 offset) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), offset)) - } - } - - /// @dev Returns the word at `offset`, without any bounds checks. - function loadCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - result := calldataload(add(a.offset, offset)) - } - } - - /// @dev Returns a slice representing a static struct in the calldata. Performs bounds checks. - function staticStructInCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - let l := sub(a.length, 0x20) - result.offset := add(a.offset, offset) - result.length := sub(a.length, offset) - if or(shr(64, or(l, a.offset)), gt(offset, l)) { revert(l, 0x00) } - } - } - - /// @dev Returns a slice representing a dynamic struct in the calldata. Performs bounds checks. - function dynamicStructInCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - let l := sub(a.length, 0x20) - let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`. - result.offset := add(a.offset, s) - result.length := sub(a.length, s) - if or(shr(64, or(s, or(l, a.offset))), gt(offset, l)) { revert(l, 0x00) } - } - } - - /// @dev Returns bytes in calldata. Performs bounds checks. - function bytesInCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - let l := sub(a.length, 0x20) - let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`. - result.offset := add(add(a.offset, s), 0x20) - result.length := calldataload(add(a.offset, s)) - // forgefmt: disable-next-item - if or(shr(64, or(result.length, or(s, or(l, a.offset)))), - or(gt(add(s, result.length), l), gt(offset, l))) { revert(l, 0x00) } - } - } - - /// @dev Checks if `x` is in `a`. Assumes `a` has been checked. - function checkInCalldata(bytes calldata x, bytes calldata a) internal pure { - /// @solidity memory-safe-assembly - assembly { - if or( - or(lt(x.offset, a.offset), gt(add(x.offset, x.length), add(a.length, a.offset))), - shr(64, or(x.length, x.offset)) - ) { revert(0x00, 0x00) } - } - } - - /// @dev Checks if `x` is in `a`. Assumes `a` has been checked. - function checkInCalldata(bytes[] calldata x, bytes calldata a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let e := sub(add(a.length, a.offset), 0x20) - if or(lt(x.offset, a.offset), shr(64, x.offset)) { revert(0x00, 0x00) } - for { let i := 0 } iszero(eq(x.length, i)) { i := add(i, 1) } { - let o := calldataload(add(x.offset, shl(5, i))) - let t := add(o, x.offset) - let l := calldataload(t) - if or(shr(64, or(l, o)), gt(add(t, l), e)) { revert(0x00, 0x00) } - } - } - } - - /// @dev Returns empty calldata bytes. For silencing the compiler. - function emptyCalldata() internal pure returns (bytes calldata result) { - /// @solidity memory-safe-assembly - assembly { - result.length := 0 - } - } - - /// @dev Returns the most significant 20 bytes as an address. - function msbToAddress(bytes32 x) internal pure returns (address) { - return address(bytes20(x)); - } - - /// @dev Returns the least significant 20 bytes as an address. - function lsbToAddress(bytes32 x) internal pure returns (address) { - return address(uint160(uint256(x))); - } -} diff --git a/grouperBot/lib/solady/src/utils/LibCall.sol b/grouperBot/lib/solady/src/utils/LibCall.sol deleted file mode 100644 index 2314095..0000000 --- a/grouperBot/lib/solady/src/utils/LibCall.sol +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for making calls. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibCall.sol) -/// @author Modified from ExcessivelySafeCall (https://github.com/nomad-xyz/ExcessivelySafeCall) -/// -/// @dev Note: -/// - The arguments of the functions may differ from the libraries. -/// Please read the functions carefully before use. -library LibCall { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The target of the call is not a contract. - error TargetIsNotContract(); - - /// @dev The data is too short to contain a function selector. - error DataTooShort(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONTRACT CALL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // These functions will revert if called on a non-contract - // (i.e. address without code). - // They will bubble up the revert if the call fails. - - /// @dev Makes a call to `target`, with `data` and `value`. - function callContract(address target, uint256 value, bytes memory data) - internal - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - if iszero(call(gas(), target, value, add(data, 0x20), mload(data), codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - if iszero(returndatasize()) { - if iszero(extcodesize(target)) { - mstore(0x00, 0x5a836a5f) // `TargetIsNotContract()`. - revert(0x1c, 0x04) - } - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /// @dev Makes a call to `target`, with `data`. - function callContract(address target, bytes memory data) - internal - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - if iszero(call(gas(), target, 0, add(data, 0x20), mload(data), codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - if iszero(returndatasize()) { - if iszero(extcodesize(target)) { - mstore(0x00, 0x5a836a5f) // `TargetIsNotContract()`. - revert(0x1c, 0x04) - } - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /// @dev Makes a static call to `target`, with `data`. - function staticCallContract(address target, bytes memory data) - internal - view - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - if iszero(staticcall(gas(), target, add(data, 0x20), mload(data), codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - if iszero(returndatasize()) { - if iszero(extcodesize(target)) { - mstore(0x00, 0x5a836a5f) // `TargetIsNotContract()`. - revert(0x1c, 0x04) - } - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /// @dev Makes a delegate call to `target`, with `data`. - function delegateCallContract(address target, bytes memory data) - internal - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - if iszero(delegatecall(gas(), target, add(data, 0x20), mload(data), codesize(), 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(result, 0x00, returndatasize()) - revert(result, returndatasize()) - } - if iszero(returndatasize()) { - if iszero(extcodesize(target)) { - mstore(0x00, 0x5a836a5f) // `TargetIsNotContract()`. - revert(0x1c, 0x04) - } - } - mstore(result, returndatasize()) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, returndatasize()) // Copy the returndata. - mstore(0x40, add(o, returndatasize())) // Allocate the memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* TRY CALL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // These functions enable gas limited calls to be performed, - // with a cap on the number of return data bytes to be copied. - // The can be used to ensure that the calling contract will not - // run out-of-gas. - - /// @dev Makes a call to `target`, with `data` and `value`. - /// The call is given a gas limit of `gasStipend`, - /// and up to `maxCopy` bytes of return data can be copied. - function tryCall( - address target, - uint256 value, - uint256 gasStipend, - uint16 maxCopy, - bytes memory data - ) internal returns (bool success, bool exceededMaxCopy, bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - success := - call(gasStipend, target, value, add(data, 0x20), mload(data), codesize(), 0x00) - let n := returndatasize() - if gt(returndatasize(), and(0xffff, maxCopy)) { - n := and(0xffff, maxCopy) - exceededMaxCopy := 1 - } - mstore(result, n) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, n) // Copy the returndata. - mstore(0x40, add(o, n)) // Allocate the memory. - } - } - - /// @dev Makes a call to `target`, with `data`. - /// The call is given a gas limit of `gasStipend`, - /// and up to `maxCopy` bytes of return data can be copied. - function tryStaticCall(address target, uint256 gasStipend, uint16 maxCopy, bytes memory data) - internal - view - returns (bool success, bool exceededMaxCopy, bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - success := - staticcall(gasStipend, target, add(data, 0x20), mload(data), codesize(), 0x00) - let n := returndatasize() - if gt(returndatasize(), and(0xffff, maxCopy)) { - n := and(0xffff, maxCopy) - exceededMaxCopy := 1 - } - mstore(result, n) // Store the length. - let o := add(result, 0x20) - returndatacopy(o, 0x00, n) // Copy the returndata. - mstore(0x40, add(o, n)) // Allocate the memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Bubbles up the revert. - function bubbleUpRevert(bytes memory revertReturnData) internal pure { - /// @solidity memory-safe-assembly - assembly { - revert(add(0x20, revertReturnData), mload(revertReturnData)) - } - } - - /// @dev In-place replaces the function selector of encoded contract call data. - function setSelector(bytes4 newSelector, bytes memory data) internal pure { - /// @solidity memory-safe-assembly - assembly { - if iszero(gt(mload(data), 0x03)) { - mstore(0x00, 0x0acec8bd) // `DataTooShort()`. - revert(0x1c, 0x04) - } - let o := add(data, 0x20) - mstore(o, or(shr(32, shl(32, mload(o))), newSelector)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibClone.sol b/grouperBot/lib/solady/src/utils/LibClone.sol deleted file mode 100644 index 504e62c..0000000 --- a/grouperBot/lib/solady/src/utils/LibClone.sol +++ /dev/null @@ -1,2863 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Minimal proxy library. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibClone.sol) -/// @author Minimal proxy by 0age (https://github.com/0age) -/// @author Clones with immutable args by wighawag, zefram.eth, Saw-mon & Natalie -/// (https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args) -/// @author Minimal ERC1967 proxy by jtriley-eth (https://github.com/jtriley-eth/minimum-viable-proxy) -/// -/// @dev Minimal proxy: -/// Although the sw0nt pattern saves 5 gas over the ERC1167 pattern during runtime, -/// it is not supported out-of-the-box on Etherscan. Hence, we choose to use the 0age pattern, -/// which saves 4 gas over the ERC1167 pattern during runtime, and has the smallest bytecode. -/// - Automatically verified on Etherscan. -/// -/// @dev Minimal proxy (PUSH0 variant): -/// This is a new minimal proxy that uses the PUSH0 opcode introduced during Shanghai. -/// It is optimized first for minimal runtime gas, then for minimal bytecode. -/// The PUSH0 clone functions are intentionally postfixed with a jarring "_PUSH0" as -/// many EVM chains may not support the PUSH0 opcode in the early months after Shanghai. -/// Please use with caution. -/// - Automatically verified on Etherscan. -/// -/// @dev Clones with immutable args (CWIA): -/// The implementation of CWIA here does NOT append the immutable args into the calldata -/// passed into delegatecall. It is simply an ERC1167 minimal proxy with the immutable arguments -/// appended to the back of the runtime bytecode. -/// - Uses the identity precompile (0x4) to copy args during deployment. -/// -/// @dev Minimal ERC1967 proxy: -/// A minimal ERC1967 proxy, intended to be upgraded with UUPS. -/// This is NOT the same as ERC1967Factory's transparent proxy, which includes admin logic. -/// - Automatically verified on Etherscan. -/// -/// @dev Minimal ERC1967 proxy with immutable args: -/// - Uses the identity precompile (0x4) to copy args during deployment. -/// - Automatically verified on Etherscan. -/// -/// @dev ERC1967I proxy: -/// A variant of the minimal ERC1967 proxy, with a special code path that activates -/// if `calldatasize() == 1`. This code path skips the delegatecall and directly returns the -/// `implementation` address. The returned implementation is guaranteed to be valid if the -/// keccak256 of the proxy's code is equal to `ERC1967I_CODE_HASH`. -/// -/// @dev ERC1967I proxy with immutable args: -/// A variant of the minimal ERC1967 proxy, with a special code path that activates -/// if `calldatasize() == 1`. This code path skips the delegatecall and directly returns the -/// - Uses the identity precompile (0x4) to copy args during deployment. -/// -/// @dev Minimal ERC1967 beacon proxy: -/// A minimal beacon proxy, intended to be upgraded with an upgradable beacon. -/// - Automatically verified on Etherscan. -/// -/// @dev Minimal ERC1967 beacon proxy with immutable args: -/// - Uses the identity precompile (0x4) to copy args during deployment. -/// - Automatically verified on Etherscan. -/// -/// @dev ERC1967I beacon proxy: -/// A variant of the minimal ERC1967 beacon proxy, with a special code path that activates -/// if `calldatasize() == 1`. This code path skips the delegatecall and directly returns the -/// `implementation` address. The returned implementation is guaranteed to be valid if the -/// keccak256 of the proxy's code is equal to `ERC1967I_CODE_HASH`. -/// -/// @dev ERC1967I proxy with immutable args: -/// A variant of the minimal ERC1967 beacon proxy, with a special code path that activates -/// if `calldatasize() == 1`. This code path skips the delegatecall and directly returns the -/// - Uses the identity precompile (0x4) to copy args during deployment. -library LibClone { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The keccak256 of deployed code for the clone proxy, - /// with the implementation set to `address(0)`. - bytes32 internal constant CLONE_CODE_HASH = - 0x48db2cfdb2853fce0b464f1f93a1996469459df3ab6c812106074c4106a1eb1f; - - /// @dev The keccak256 of deployed code for the PUSH0 proxy, - /// with the implementation set to `address(0)`. - bytes32 internal constant PUSH0_CLONE_CODE_HASH = - 0x67bc6bde1b84d66e267c718ba44cf3928a615d29885537955cb43d44b3e789dc; - - /// @dev The keccak256 of deployed code for the ERC-1167 CWIA proxy, - /// with the implementation set to `address(0)`. - bytes32 internal constant CWIA_CODE_HASH = - 0x3cf92464268225a4513da40a34d967354684c32cd0edd67b5f668dfe3550e940; - - /// @dev The keccak256 of the deployed code for the ERC1967 proxy. - bytes32 internal constant ERC1967_CODE_HASH = - 0xaaa52c8cc8a0e3fd27ce756cc6b4e70c51423e9b597b11f32d3e49f8b1fc890d; - - /// @dev The keccak256 of the deployed code for the ERC1967I proxy. - bytes32 internal constant ERC1967I_CODE_HASH = - 0xce700223c0d4cea4583409accfc45adac4a093b3519998a9cbbe1504dadba6f7; - - /// @dev The keccak256 of the deployed code for the ERC1967 beacon proxy. - bytes32 internal constant ERC1967_BEACON_PROXY_CODE_HASH = - 0x14044459af17bc4f0f5aa2f658cb692add77d1302c29fe2aebab005eea9d1162; - - /// @dev The keccak256 of the deployed code for the ERC1967 beacon proxy. - bytes32 internal constant ERC1967I_BEACON_PROXY_CODE_HASH = - 0xf8c46d2793d5aa984eb827aeaba4b63aedcab80119212fce827309788735519a; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unable to deploy the clone. - error DeploymentFailed(); - - /// @dev The salt must start with either the zero address or `by`. - error SaltDoesNotStartWith(); - - /// @dev The ETH transfer has failed. - error ETHTransferFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MINIMAL PROXY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a clone of `implementation`. - function clone(address implementation) internal returns (address instance) { - instance = clone(0, implementation); - } - - /// @dev Deploys a clone of `implementation`. - /// Deposits `value` ETH during deployment. - function clone(uint256 value, address implementation) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - /** - * --------------------------------------------------------------------------+ - * CREATION (9 bytes) | - * --------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * --------------------------------------------------------------------------| - * 60 runSize | PUSH1 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * --------------------------------------------------------------------------| - * RUNTIME (44 bytes) | - * --------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * --------------------------------------------------------------------------| - * | - * ::: keep some values in stack ::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | | - * 3d | RETURNDATASIZE | 0 0 | | - * 3d | RETURNDATASIZE | 0 0 0 | | - * 3d | RETURNDATASIZE | 0 0 0 0 | | - * | - * ::: copy calldata to memory ::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds 0 0 0 0 | | - * 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | | - * 3d | RETURNDATASIZE | 0 0 cds 0 0 0 0 | | - * 37 | CALLDATACOPY | 0 0 0 0 | [0..cds): calldata | - * | - * ::: delegate call to the implementation contract :::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds 0 0 0 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | [0..cds): calldata | - * 73 addr | PUSH20 addr | addr 0 cds 0 0 0 0 | [0..cds): calldata | - * 5a | GAS | gas addr 0 cds 0 0 0 0 | [0..cds): calldata | - * f4 | DELEGATECALL | success 0 0 | [0..cds): calldata | - * | - * ::: copy return data to memory :::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds success 0 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | rds rds success 0 0 | [0..cds): calldata | - * 93 | SWAP4 | 0 rds success 0 rds | [0..cds): calldata | - * 80 | DUP1 | 0 0 rds success 0 rds | [0..cds): calldata | - * 3e | RETURNDATACOPY | success 0 rds | [0..rds): returndata | - * | - * 60 0x2a | PUSH1 0x2a | 0x2a success 0 rds | [0..rds): returndata | - * 57 | JUMPI | 0 rds | [0..rds): returndata | - * | - * ::: revert :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * fd | REVERT | | [0..rds): returndata | - * | - * ::: return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | 0 rds | [0..rds): returndata | - * f3 | RETURN | | [0..rds): returndata | - * --------------------------------------------------------------------------+ - */ - mstore(0x21, 0x5af43d3d93803e602a57fd5bf3) - mstore(0x14, implementation) - mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) - instance := create(value, 0x0c, 0x35) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Deploys a deterministic clone of `implementation` with `salt`. - function cloneDeterministic(address implementation, bytes32 salt) - internal - returns (address instance) - { - instance = cloneDeterministic(0, implementation, salt); - } - - /// @dev Deploys a deterministic clone of `implementation` with `salt`. - /// Deposits `value` ETH during deployment. - function cloneDeterministic(uint256 value, address implementation, bytes32 salt) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x21, 0x5af43d3d93803e602a57fd5bf3) - mstore(0x14, implementation) - mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) - instance := create2(value, 0x0c, 0x35, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the initialization code of the clone of `implementation`. - function initCode(address implementation) internal pure returns (bytes memory c) { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - mstore(add(c, 0x40), 0x5af43d3d93803e602a57fd5bf30000000000000000000000) - mstore(add(c, 0x28), implementation) - mstore(add(c, 0x14), 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) - mstore(c, 0x35) // Store the length. - mstore(0x40, add(c, 0x60)) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the clone of `implementation`. - function initCodeHash(address implementation) internal pure returns (bytes32 hash) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x21, 0x5af43d3d93803e602a57fd5bf3) - mstore(0x14, implementation) - mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) - hash := keccak256(0x0c, 0x35) - mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the address of the clone of `implementation`, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddress(address implementation, bytes32 salt, address deployer) - internal - pure - returns (address predicted) - { - bytes32 hash = initCodeHash(implementation); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MINIMAL PROXY OPERATIONS (PUSH0 VARIANT) */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a PUSH0 clone of `implementation`. - function clone_PUSH0(address implementation) internal returns (address instance) { - instance = clone_PUSH0(0, implementation); - } - - /// @dev Deploys a PUSH0 clone of `implementation`. - /// Deposits `value` ETH during deployment. - function clone_PUSH0(uint256 value, address implementation) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - /** - * --------------------------------------------------------------------------+ - * CREATION (9 bytes) | - * --------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * --------------------------------------------------------------------------| - * 60 runSize | PUSH1 runSize | r | | - * 5f | PUSH0 | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 5f | PUSH0 | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * --------------------------------------------------------------------------| - * RUNTIME (45 bytes) | - * --------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * --------------------------------------------------------------------------| - * | - * ::: keep some values in stack ::::::::::::::::::::::::::::::::::::::::::: | - * 5f | PUSH0 | 0 | | - * 5f | PUSH0 | 0 0 | | - * | - * ::: copy calldata to memory ::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds 0 0 | | - * 5f | PUSH0 | 0 cds 0 0 | | - * 5f | PUSH0 | 0 0 cds 0 0 | | - * 37 | CALLDATACOPY | 0 0 | [0..cds): calldata | - * | - * ::: delegate call to the implementation contract :::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds 0 0 | [0..cds): calldata | - * 5f | PUSH0 | 0 cds 0 0 | [0..cds): calldata | - * 73 addr | PUSH20 addr | addr 0 cds 0 0 | [0..cds): calldata | - * 5a | GAS | gas addr 0 cds 0 0 | [0..cds): calldata | - * f4 | DELEGATECALL | success | [0..cds): calldata | - * | - * ::: copy return data to memory :::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds success | [0..cds): calldata | - * 5f | PUSH0 | 0 rds success | [0..cds): calldata | - * 5f | PUSH0 | 0 0 rds success | [0..cds): calldata | - * 3e | RETURNDATACOPY | success | [0..rds): returndata | - * | - * 60 0x29 | PUSH1 0x29 | 0x29 success | [0..rds): returndata | - * 57 | JUMPI | | [0..rds): returndata | - * | - * ::: revert :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds | [0..rds): returndata | - * 5f | PUSH0 | 0 rds | [0..rds): returndata | - * fd | REVERT | | [0..rds): returndata | - * | - * ::: return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | | [0..rds): returndata | - * 3d | RETURNDATASIZE | rds | [0..rds): returndata | - * 5f | PUSH0 | 0 rds | [0..rds): returndata | - * f3 | RETURN | | [0..rds): returndata | - * --------------------------------------------------------------------------+ - */ - mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16 - mstore(0x14, implementation) // 20 - mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 - instance := create(value, 0x0e, 0x36) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x24, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Deploys a deterministic PUSH0 clone of `implementation` with `salt`. - function cloneDeterministic_PUSH0(address implementation, bytes32 salt) - internal - returns (address instance) - { - instance = cloneDeterministic_PUSH0(0, implementation, salt); - } - - /// @dev Deploys a deterministic PUSH0 clone of `implementation` with `salt`. - /// Deposits `value` ETH during deployment. - function cloneDeterministic_PUSH0(uint256 value, address implementation, bytes32 salt) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16 - mstore(0x14, implementation) // 20 - mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 - instance := create2(value, 0x0e, 0x36, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x24, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the initialization code of the PUSH0 clone of `implementation`. - function initCode_PUSH0(address implementation) internal pure returns (bytes memory c) { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - mstore(add(c, 0x40), 0x5af43d5f5f3e6029573d5ffd5b3d5ff300000000000000000000) // 16 - mstore(add(c, 0x26), implementation) // 20 - mstore(add(c, 0x12), 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 - mstore(c, 0x36) // Store the length. - mstore(0x40, add(c, 0x60)) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the PUSH0 clone of `implementation`. - function initCodeHash_PUSH0(address implementation) internal pure returns (bytes32 hash) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16 - mstore(0x14, implementation) // 20 - mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 - hash := keccak256(0x0e, 0x36) - mstore(0x24, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the address of the PUSH0 clone of `implementation`, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddress_PUSH0( - address implementation, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHash_PUSH0(implementation); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CLONES WITH IMMUTABLE ARGS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `args`. - function clone(address implementation, bytes memory args) internal returns (address instance) { - instance = clone(0, implementation, args); - } - - /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `args`. - /// Deposits `value` ETH during deployment. - function clone(uint256 value, address implementation, bytes memory args) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - /** - * ---------------------------------------------------------------------------+ - * CREATION (10 bytes) | - * ---------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------| - * 61 runSize | PUSH2 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * ---------------------------------------------------------------------------| - * RUNTIME (45 bytes + extraLength) | - * ---------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------| - * | - * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 3d | RETURNDATASIZE | 0 cds | | - * 3d | RETURNDATASIZE | 0 0 cds | | - * 37 | CALLDATACOPY | | [0..cds): calldata | - * | - * ::: delegate call to the implementation contract ::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 0 0 | [0..cds): calldata | - * 36 | CALLDATASIZE | cds 0 0 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | [0..cds): calldata | - * 73 addr | PUSH20 addr | addr 0 cds 0 0 0 0 | [0..cds): calldata | - * 5a | GAS | gas addr 0 cds 0 0 0 0 | [0..cds): calldata | - * f4 | DELEGATECALL | success 0 0 | [0..cds): calldata | - * | - * ::: copy return data to memory ::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds success 0 | [0..cds): calldata | - * 82 | DUP3 | 0 rds success 0 | [0..cds): calldata | - * 80 | DUP1 | 0 0 rds success 0 | [0..cds): calldata | - * 3e | RETURNDATACOPY | success 0 | [0..rds): returndata | - * 90 | SWAP1 | 0 success | [0..rds): returndata | - * 3d | RETURNDATASIZE | rds 0 success | [0..rds): returndata | - * 91 | SWAP2 | success 0 rds | [0..rds): returndata | - * | - * 60 0x2b | PUSH1 0x2b | 0x2b success 0 rds | [0..rds): returndata | - * 57 | JUMPI | 0 rds | [0..rds): returndata | - * | - * ::: revert ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * fd | REVERT | | [0..rds): returndata | - * | - * ::: return ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | 0 rds | [0..rds): returndata | - * f3 | RETURN | | [0..rds): returndata | - * ---------------------------------------------------------------------------+ - */ - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x43), n)) - mstore(add(m, 0x23), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(m, 0x14), implementation) - mstore(m, add(0xfe61002d3d81600a3d39f3363d3d373d3d3d363d73, shl(136, n))) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x2d = 0xffd2`. - instance := create(value, add(m, add(0x0b, lt(n, 0xffd3))), add(n, 0x37)) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Deploys a deterministic clone of `implementation` - /// with immutable arguments encoded in `args` and `salt`. - function cloneDeterministic(address implementation, bytes memory args, bytes32 salt) - internal - returns (address instance) - { - instance = cloneDeterministic(0, implementation, args, salt); - } - - /// @dev Deploys a deterministic clone of `implementation` - /// with immutable arguments encoded in `args` and `salt`. - function cloneDeterministic( - uint256 value, - address implementation, - bytes memory args, - bytes32 salt - ) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x43), n)) - mstore(add(m, 0x23), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(m, 0x14), implementation) - mstore(m, add(0xfe61002d3d81600a3d39f3363d3d373d3d3d363d73, shl(136, n))) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x2d = 0xffd2`. - instance := create2(value, add(m, add(0x0b, lt(n, 0xffd3))), add(n, 0x37), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Deploys a deterministic clone of `implementation` - /// with immutable arguments encoded in `args` and `salt`. - /// This method does not revert if the clone has already been deployed. - function createDeterministicClone(address implementation, bytes memory args, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicClone(0, implementation, args, salt); - } - - /// @dev Deploys a deterministic clone of `implementation` - /// with immutable arguments encoded in `args` and `salt`. - /// This method does not revert if the clone has already been deployed. - function createDeterministicClone( - uint256 value, - address implementation, - bytes memory args, - bytes32 salt - ) internal returns (bool alreadyDeployed, address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x43), n)) - mstore(add(m, 0x23), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(m, 0x14), implementation) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x2d = 0xffd2`. - // forgefmt: disable-next-item - mstore(add(m, gt(n, 0xffd2)), add(0xfe61002d3d81600a3d39f3363d3d373d3d3d363d73, shl(136, n))) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(add(m, 0x0c), add(n, 0x37))) - mstore(0x01, shl(96, address())) - mstore(0x15, salt) - instance := keccak256(0x00, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, add(m, 0x0c), add(n, 0x37), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the initialization code of the clone of `implementation` - /// using immutable arguments encoded in `args`. - function initCode(address implementation, bytes memory args) - internal - pure - returns (bytes memory c) - { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x2d = 0xffd2`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffd2)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(c, 0x57), i), mload(add(add(args, 0x20), i))) - } - mstore(add(c, 0x37), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(c, 0x28), implementation) - mstore(add(c, 0x14), add(0x61002d3d81600a3d39f3363d3d373d3d3d363d73, shl(136, n))) - mstore(c, add(0x37, n)) // Store the length. - mstore(add(c, add(n, 0x57)), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(c, add(n, 0x77))) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the clone of `implementation` - /// using immutable arguments encoded in `args`. - function initCodeHash(address implementation, bytes memory args) - internal - pure - returns (bytes32 hash) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x2d = 0xffd2`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffd2)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(m, 0x43), i), mload(add(add(args, 0x20), i))) - } - mstore(add(m, 0x23), 0x5af43d82803e903d91602b57fd5bf3) - mstore(add(m, 0x14), implementation) - mstore(m, add(0x61002d3d81600a3d39f3363d3d373d3d3d363d73, shl(136, n))) - hash := keccak256(add(m, 0x0c), add(n, 0x37)) - } - } - - /// @dev Returns the address of the clone of - /// `implementation` using immutable arguments encoded in `args`, with `salt`, by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddress( - address implementation, - bytes memory data, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHash(implementation, data); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /// @dev Equivalent to `argsOnClone(instance, 0, 2 ** 256 - 1)`. - function argsOnClone(address instance) internal view returns (bytes memory args) { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - mstore(args, and(0xffffffffff, sub(extcodesize(instance), 0x2d))) // Store the length. - extcodecopy(instance, add(args, 0x20), 0x2d, add(mload(args), 0x20)) - mstore(0x40, add(mload(args), add(args, 0x40))) // Allocate memory. - } - } - - /// @dev Equivalent to `argsOnClone(instance, start, 2 ** 256 - 1)`. - function argsOnClone(address instance, uint256 start) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - let n := and(0xffffffffff, sub(extcodesize(instance), 0x2d)) - let l := sub(n, and(0xffffff, mul(lt(start, n), start))) - extcodecopy(instance, args, add(start, 0x0d), add(l, 0x40)) - mstore(args, mul(sub(n, start), lt(start, n))) // Store the length. - mstore(0x40, add(args, add(0x40, mload(args)))) // Allocate memory. - } - } - - /// @dev Returns a slice of the immutable arguments on `instance` from `start` to `end`. - /// `start` and `end` will be clamped to the range `[0, args.length]`. - /// The `instance` MUST be deployed via the clone with immutable args functions. - /// Otherwise, the behavior is undefined. - /// Out-of-gas reverts if `instance` does not have any code. - function argsOnClone(address instance, uint256 start, uint256 end) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - if iszero(lt(end, 0xffff)) { end := 0xffff } - let d := mul(sub(end, start), lt(start, end)) - extcodecopy(instance, args, add(start, 0x0d), add(d, 0x20)) - if iszero(and(0xff, mload(add(args, d)))) { - let n := sub(extcodesize(instance), 0x2d) - returndatacopy(returndatasize(), returndatasize(), shr(40, n)) - d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n)))) - } - mstore(args, d) // Store the length. - mstore(add(add(args, 0x20), d), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(args, 0x40), d)) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MINIMAL ERC1967 PROXY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: The ERC1967 proxy here is intended to be upgraded with UUPS. - // This is NOT the same as ERC1967Factory's transparent proxy, which includes admin logic. - - /// @dev Deploys a minimal ERC1967 proxy with `implementation`. - function deployERC1967(address implementation) internal returns (address instance) { - instance = deployERC1967(0, implementation); - } - - /// @dev Deploys a minimal ERC1967 proxy with `implementation`. - /// Deposits `value` ETH during deployment. - function deployERC1967(uint256 value, address implementation) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - /** - * ---------------------------------------------------------------------------------+ - * CREATION (34 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * 60 runSize | PUSH1 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * 73 impl | PUSH20 impl | impl 0 r | [0..runSize): runtime code | - * 60 slotPos | PUSH1 slotPos | slotPos impl 0 r | [0..runSize): runtime code | - * 51 | MLOAD | slot impl 0 r | [0..runSize): runtime code | - * 55 | SSTORE | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * ---------------------------------------------------------------------------------| - * RUNTIME (61 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * | - * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 3d | RETURNDATASIZE | 0 cds | | - * 3d | RETURNDATASIZE | 0 0 cds | | - * 37 | CALLDATACOPY | | [0..calldatasize): calldata | - * | - * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | | - * 3d | RETURNDATASIZE | 0 0 | | - * 36 | CALLDATASIZE | cds 0 0 | [0..calldatasize): calldata | - * 3d | RETURNDATASIZE | 0 cds 0 0 | [0..calldatasize): calldata | - * 7f slot | PUSH32 slot | s 0 cds 0 0 | [0..calldatasize): calldata | - * 54 | SLOAD | i 0 cds 0 0 | [0..calldatasize): calldata | - * 5a | GAS | g i 0 cds 0 0 | [0..calldatasize): calldata | - * f4 | DELEGATECALL | succ | [0..calldatasize): calldata | - * | - * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds succ | [0..calldatasize): calldata | - * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..calldatasize): calldata | - * 80 | DUP1 | 0 0 rds succ | [0..calldatasize): calldata | - * 3e | RETURNDATACOPY | succ | [0..returndatasize): returndata | - * | - * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: | - * 60 0x38 | PUSH1 0x38 | dest succ | [0..returndatasize): returndata | - * 57 | JUMPI | | [0..returndatasize): returndata | - * | - * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * fd | REVERT | | [0..returndatasize): returndata | - * | - * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | | [0..returndatasize): returndata | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * f3 | RETURN | | [0..returndatasize): returndata | - * ---------------------------------------------------------------------------------+ - */ - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x20, 0x6009) - mstore(0x1e, implementation) - mstore(0x0a, 0x603d3d8160223d3973) - instance := create(value, 0x21, 0x5f) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation` and `salt`. - function deployDeterministicERC1967(address implementation, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967(0, implementation, salt); - } - - /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation` and `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967(uint256 value, address implementation, bytes32 salt) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x20, 0x6009) - mstore(0x1e, implementation) - mstore(0x0a, 0x603d3d8160223d3973) - instance := create2(value, 0x21, 0x5f, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation` and `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967(address implementation, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967(0, implementation, salt); - } - - /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation` and `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967(uint256 value, address implementation, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x20, 0x6009) - mstore(0x1e, implementation) - mstore(0x0a, 0x603d3d8160223d3973) - // Compute and store the bytecode hash. - mstore(add(m, 0x35), keccak256(0x21, 0x5f)) - mstore(m, shl(88, address())) - mstore8(m, 0xff) // Write the prefix. - mstore(add(m, 0x15), salt) - instance := keccak256(m, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, 0x21, 0x5f, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the initialization code of the minimal ERC1967 proxy of `implementation`. - function initCodeERC1967(address implementation) internal pure returns (bytes memory c) { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - mstore(add(c, 0x60), 0x3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f300) - mstore(add(c, 0x40), 0x55f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc) - mstore(add(c, 0x20), or(shl(24, implementation), 0x600951)) - mstore(add(c, 0x09), 0x603d3d8160223d3973) - mstore(c, 0x5f) // Store the length. - mstore(0x40, add(c, 0x80)) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the minimal ERC1967 proxy of `implementation`. - function initCodeHashERC1967(address implementation) internal pure returns (bytes32 hash) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x20, 0x6009) - mstore(0x1e, implementation) - mstore(0x0a, 0x603d3d8160223d3973) - hash := keccak256(0x21, 0x5f) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the address of the ERC1967 proxy of `implementation`, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967( - address implementation, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967(implementation); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MINIMAL ERC1967 PROXY WITH IMMUTABLE ARGS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a minimal ERC1967 proxy with `implementation` and `args`. - function deployERC1967(address implementation, bytes memory args) - internal - returns (address instance) - { - instance = deployERC1967(0, implementation, args); - } - - /// @dev Deploys a minimal ERC1967 proxy with `implementation` and `args`. - /// Deposits `value` ETH during deployment. - function deployERC1967(uint256 value, address implementation, bytes memory args) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x60), n)) - mstore(add(m, 0x40), 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(add(m, 0x20), 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x16, 0x6009) - mstore(0x14, implementation) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x3d = 0xffc2`. - mstore(gt(n, 0xffc2), add(0xfe61003d3d8160233d3973, shl(56, n))) - mstore(m, mload(0x16)) - instance := create(value, m, add(n, 0x60)) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation`, `args` and `salt`. - function deployDeterministicERC1967(address implementation, bytes memory args, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967(0, implementation, args, salt); - } - - /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation`, `args` and `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967( - uint256 value, - address implementation, - bytes memory args, - bytes32 salt - ) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x60), n)) - mstore(add(m, 0x40), 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(add(m, 0x20), 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x16, 0x6009) - mstore(0x14, implementation) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x3d = 0xffc2`. - mstore(gt(n, 0xffc2), add(0xfe61003d3d8160233d3973, shl(56, n))) - mstore(m, mload(0x16)) - instance := create2(value, m, add(n, 0x60), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation`, `args` and `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967(address implementation, bytes memory args, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967(0, implementation, args, salt); - } - - /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation`, `args` and `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967( - uint256 value, - address implementation, - bytes memory args, - bytes32 salt - ) internal returns (bool alreadyDeployed, address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x60), n)) - mstore(add(m, 0x40), 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(add(m, 0x20), 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x16, 0x6009) - mstore(0x14, implementation) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x3d = 0xffc2`. - mstore(gt(n, 0xffc2), add(0xfe61003d3d8160233d3973, shl(56, n))) - mstore(m, mload(0x16)) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(m, add(n, 0x60))) - mstore(0x01, shl(96, address())) - mstore(0x15, salt) - instance := keccak256(0x00, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, m, add(n, 0x60), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the initialization code of the minimal ERC1967 proxy of `implementation` and `args`. - function initCodeERC1967(address implementation, bytes memory args) - internal - pure - returns (bytes memory c) - { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x3d = 0xffc2`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffc2)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(c, 0x80), i), mload(add(add(args, 0x20), i))) - } - mstore(add(c, 0x60), 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(add(c, 0x40), 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(add(c, 0x20), 0x6009) - mstore(add(c, 0x1e), implementation) - mstore(add(c, 0x0a), add(0x61003d3d8160233d3973, shl(56, n))) - mstore(c, add(n, 0x60)) // Store the length. - mstore(add(c, add(n, 0x80)), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(c, add(n, 0xa0))) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the minimal ERC1967 proxy of `implementation` and `args`. - function initCodeHashERC1967(address implementation, bytes memory args) - internal - pure - returns (bytes32 hash) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x3d = 0xffc2`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffc2)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(m, 0x60), i), mload(add(add(args, 0x20), i))) - } - mstore(add(m, 0x40), 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) - mstore(add(m, 0x20), 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) - mstore(0x16, 0x6009) - mstore(0x14, implementation) - mstore(0x00, add(0x61003d3d8160233d3973, shl(56, n))) - mstore(m, mload(0x16)) - hash := keccak256(m, add(n, 0x60)) - } - } - - /// @dev Returns the address of the ERC1967 proxy of `implementation`, `args`, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967( - address implementation, - bytes memory args, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967(implementation, args); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /// @dev Equivalent to `argsOnERC1967(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967(address instance) internal view returns (bytes memory args) { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - mstore(args, and(0xffffffffff, sub(extcodesize(instance), 0x3d))) // Store the length. - extcodecopy(instance, add(args, 0x20), 0x3d, add(mload(args), 0x20)) - mstore(0x40, add(mload(args), add(args, 0x40))) // Allocate memory. - } - } - - /// @dev Equivalent to `argsOnERC1967(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967(address instance, uint256 start) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - let n := and(0xffffffffff, sub(extcodesize(instance), 0x3d)) - let l := sub(n, and(0xffffff, mul(lt(start, n), start))) - extcodecopy(instance, args, add(start, 0x1d), add(l, 0x40)) - mstore(args, mul(sub(n, start), lt(start, n))) // Store the length. - mstore(0x40, add(args, add(0x40, mload(args)))) // Allocate memory. - } - } - - /// @dev Returns a slice of the immutable arguments on `instance` from `start` to `end`. - /// `start` and `end` will be clamped to the range `[0, args.length]`. - /// The `instance` MUST be deployed via the ERC1967 with immutable args functions. - /// Otherwise, the behavior is undefined. - /// Out-of-gas reverts if `instance` does not have any code. - function argsOnERC1967(address instance, uint256 start, uint256 end) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - if iszero(lt(end, 0xffff)) { end := 0xffff } - let d := mul(sub(end, start), lt(start, end)) - extcodecopy(instance, args, add(start, 0x1d), add(d, 0x20)) - if iszero(and(0xff, mload(add(args, d)))) { - let n := sub(extcodesize(instance), 0x3d) - returndatacopy(returndatasize(), returndatasize(), shr(40, n)) - d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n)))) - } - mstore(args, d) // Store the length. - mstore(add(add(args, 0x20), d), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(args, 0x40), d)) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1967I PROXY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: This proxy has a special code path that activates if `calldatasize() == 1`. - // This code path skips the delegatecall and directly returns the `implementation` address. - // The returned implementation is guaranteed to be valid if the keccak256 of the - // proxy's code is equal to `ERC1967I_CODE_HASH`. - - /// @dev Deploys a ERC1967I proxy with `implementation`. - function deployERC1967I(address implementation) internal returns (address instance) { - instance = deployERC1967I(0, implementation); - } - - /// @dev Deploys a ERC1967I proxy with `implementation`. - /// Deposits `value` ETH during deployment. - function deployERC1967I(uint256 value, address implementation) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - /** - * ---------------------------------------------------------------------------------+ - * CREATION (34 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * 60 runSize | PUSH1 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * 73 impl | PUSH20 impl | impl 0 r | [0..runSize): runtime code | - * 60 slotPos | PUSH1 slotPos | slotPos impl 0 r | [0..runSize): runtime code | - * 51 | MLOAD | slot impl 0 r | [0..runSize): runtime code | - * 55 | SSTORE | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * ---------------------------------------------------------------------------------| - * RUNTIME (82 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * | - * ::: check calldatasize ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 58 | PC | 1 cds | | - * 14 | EQ | eqs | | - * 60 0x43 | PUSH1 0x43 | dest eqs | | - * 57 | JUMPI | | | - * | - * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 3d | RETURNDATASIZE | 0 cds | | - * 3d | RETURNDATASIZE | 0 0 cds | | - * 37 | CALLDATACOPY | | [0..calldatasize): calldata | - * | - * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | | - * 3d | RETURNDATASIZE | 0 0 | | - * 36 | CALLDATASIZE | cds 0 0 | [0..calldatasize): calldata | - * 3d | RETURNDATASIZE | 0 cds 0 0 | [0..calldatasize): calldata | - * 7f slot | PUSH32 slot | s 0 cds 0 0 | [0..calldatasize): calldata | - * 54 | SLOAD | i 0 cds 0 0 | [0..calldatasize): calldata | - * 5a | GAS | g i 0 cds 0 0 | [0..calldatasize): calldata | - * f4 | DELEGATECALL | succ | [0..calldatasize): calldata | - * | - * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds succ | [0..calldatasize): calldata | - * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..calldatasize): calldata | - * 80 | DUP1 | 0 0 rds succ | [0..calldatasize): calldata | - * 3e | RETURNDATACOPY | succ | [0..returndatasize): returndata | - * | - * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: | - * 60 0x3E | PUSH1 0x3E | dest succ | [0..returndatasize): returndata | - * 57 | JUMPI | | [0..returndatasize): returndata | - * | - * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * fd | REVERT | | [0..returndatasize): returndata | - * | - * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | | [0..returndatasize): returndata | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * f3 | RETURN | | [0..returndatasize): returndata | - * | - * ::: implementation , return :::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | | | - * 60 0x20 | PUSH1 0x20 | 32 | | - * 60 0x0F | PUSH1 0x0F | o 32 | | - * 3d | RETURNDATASIZE | 0 o 32 | | - * 39 | CODECOPY | | [0..32): implementation slot | - * 3d | RETURNDATASIZE | 0 | [0..32): implementation slot | - * 51 | MLOAD | slot | [0..32): implementation slot | - * 54 | SLOAD | impl | [0..32): implementation slot | - * 3d | RETURNDATASIZE | 0 impl | [0..32): implementation slot | - * 52 | MSTORE | | [0..32): implementation address | - * 59 | MSIZE | 32 | [0..32): implementation address | - * 3d | RETURNDATASIZE | 0 32 | [0..32): implementation address | - * f3 | RETURN | | [0..32): implementation address | - * ---------------------------------------------------------------------------------+ - */ - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) - instance := create(value, 0x0c, 0x74) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Deploys a deterministic ERC1967I proxy with `implementation` and `salt`. - function deployDeterministicERC1967I(address implementation, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967I(0, implementation, salt); - } - - /// @dev Deploys a deterministic ERC1967I proxy with `implementation` and `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967I(uint256 value, address implementation, bytes32 salt) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) - instance := create2(value, 0x0c, 0x74, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Creates a deterministic ERC1967I proxy with `implementation` and `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967I(address implementation, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967I(0, implementation, salt); - } - - /// @dev Creates a deterministic ERC1967I proxy with `implementation` and `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967I(uint256 value, address implementation, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) - // Compute and store the bytecode hash. - mstore(add(m, 0x35), keccak256(0x0c, 0x74)) - mstore(m, shl(88, address())) - mstore8(m, 0xff) // Write the prefix. - mstore(add(m, 0x15), salt) - instance := keccak256(m, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, 0x0c, 0x74, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the initialization code of the ERC1967I proxy of `implementation`. - function initCodeERC1967I(address implementation) internal pure returns (bytes memory c) { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - mstore(add(c, 0x74), 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(add(c, 0x54), 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(add(c, 0x34), 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(add(c, 0x1d), implementation) - mstore(add(c, 0x09), 0x60523d8160223d3973) - mstore(add(c, 0x94), 0) - mstore(c, 0x74) // Store the length. - mstore(0x40, add(c, 0xa0)) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the ERC1967I proxy of `implementation`. - function initCodeHashERC1967I(address implementation) internal pure returns (bytes32 hash) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) - hash := keccak256(0x0c, 0x74) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the address of the ERC1967I proxy of `implementation`, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967I( - address implementation, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967I(implementation); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1967I PROXY WITH IMMUTABLE ARGS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a minimal ERC1967I proxy with `implementation` and `args`. - function deployERC1967I(address implementation, bytes memory args) internal returns (address) { - return deployERC1967I(0, implementation, args); - } - - /// @dev Deploys a minimal ERC1967I proxy with `implementation` and `args`. - /// Deposits `value` ETH during deployment. - function deployERC1967I(uint256 value, address implementation, bytes memory args) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x8b), n)) - - mstore(add(m, 0x6b), 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(add(m, 0x4b), 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(add(m, 0x2b), 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(add(m, 0x14), implementation) - mstore(m, add(0xfe6100523d8160233d3973, shl(56, n))) - - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - instance := create(value, add(m, add(0x15, lt(n, 0xffae))), add(0x75, n)) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Deploys a deterministic ERC1967I proxy with `implementation`, `args`, and `salt`. - function deployDeterministicERC1967I(address implementation, bytes memory args, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967I(0, implementation, args, salt); - } - - /// @dev Deploys a deterministic ERC1967I proxy with `implementation`, `args`, and `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967I( - uint256 value, - address implementation, - bytes memory args, - bytes32 salt - ) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x8b), n)) - - mstore(add(m, 0x6b), 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(add(m, 0x4b), 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(add(m, 0x2b), 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(add(m, 0x14), implementation) - mstore(m, add(0xfe6100523d8160233d3973, shl(56, n))) - - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - instance := create2(value, add(m, add(0x15, lt(n, 0xffae))), add(0x75, n), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Creates a deterministic ERC1967I proxy with `implementation`, `args` and `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967I(address implementation, bytes memory args, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967I(0, implementation, args, salt); - } - - /// @dev Creates a deterministic ERC1967I proxy with `implementation`, `args` and `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967I( - uint256 value, - address implementation, - bytes memory args, - bytes32 salt - ) internal returns (bool alreadyDeployed, address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x75), n)) - mstore(add(m, 0x55), 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(add(m, 0x35), 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(add(m, 0x15), 0x5155f3365814604357363d3d373d3d363d7f360894) - mstore(0x16, 0x600f) - mstore(0x14, implementation) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - mstore(gt(n, 0xffad), add(0xfe6100523d8160233d3973, shl(56, n))) - mstore(m, mload(0x16)) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(m, add(n, 0x75))) - mstore(0x01, shl(96, address())) - mstore(0x15, salt) - instance := keccak256(0x00, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, m, add(0x75, n), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the initialization code of the ERC1967I proxy of `implementation` and `args`. - function initCodeERC1967I(address implementation, bytes memory args) - internal - pure - returns (bytes memory c) - { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffad)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(c, 0x95), i), mload(add(add(args, 0x20), i))) - } - - mstore(add(c, 0x75), 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(add(c, 0x55), 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(add(c, 0x35), 0x600f5155f3365814604357363d3d373d3d363d7f360894) - mstore(add(c, 0x1e), implementation) - mstore(add(c, 0x0a), add(0x6100523d8160233d3973, shl(56, n))) - mstore(add(c, add(n, 0x95)), 0) - mstore(c, add(0x75, n)) // Store the length. - mstore(0x40, add(c, add(n, 0xb5))) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the ERC1967I proxy of `implementation` and `args. - function initCodeHashERC1967I(address implementation, bytes memory args) - internal - pure - returns (bytes32 hash) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffad)) - - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(m, 0x75), i), mload(add(add(args, 0x20), i))) - } - - mstore(add(m, 0x55), 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) - mstore(add(m, 0x35), 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) - mstore(add(m, 0x15), 0x5155f3365814604357363d3d373d3d363d7f360894) - mstore(0x16, 0x600f) - mstore(0x14, implementation) - mstore(0x00, add(0x6100523d8160233d3973, shl(56, n))) - mstore(m, mload(0x16)) - hash := keccak256(m, add(0x75, n)) - } - } - - /// @dev Returns the address of the ERC1967I proxy of `implementation`, `args` with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967I( - address implementation, - bytes memory args, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967I(implementation, args); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /// @dev Equivalent to `argsOnERC1967I(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967I(address instance) internal view returns (bytes memory args) { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - mstore(args, and(0xffffffffff, sub(extcodesize(instance), 0x52))) // Store the length. - extcodecopy(instance, add(args, 0x20), 0x52, add(mload(args), 0x20)) - mstore(0x40, add(mload(args), add(args, 0x40))) // Allocate memory. - } - } - - /// @dev Equivalent to `argsOnERC1967I(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967I(address instance, uint256 start) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - let n := and(0xffffffffff, sub(extcodesize(instance), 0x52)) - let l := sub(n, and(0xffffff, mul(lt(start, n), start))) - extcodecopy(instance, args, add(start, 0x32), add(l, 0x40)) - mstore(args, mul(sub(n, start), lt(start, n))) // Store the length. - mstore(0x40, add(mload(args), add(args, 0x40))) // Allocate memory. - } - } - - /// @dev Returns a slice of the immutable arguments on `instance` from `start` to `end`. - /// `start` and `end` will be clamped to the range `[0, args.length]`. - /// The `instance` MUST be deployed via the ERC1967 with immutable args functions. - /// Otherwise, the behavior is undefined. - /// Out-of-gas reverts if `instance` does not have any code. - function argsOnERC1967I(address instance, uint256 start, uint256 end) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - if iszero(lt(end, 0xffff)) { end := 0xffff } - let d := mul(sub(end, start), lt(start, end)) - extcodecopy(instance, args, add(start, 0x32), add(d, 0x20)) - if iszero(and(0xff, mload(add(args, d)))) { - let n := sub(extcodesize(instance), 0x52) - returndatacopy(returndatasize(), returndatasize(), shr(40, n)) - d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n)))) - } - mstore(args, d) // Store the length. - mstore(add(add(args, 0x20), d), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(args, 0x40), d)) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1967 BOOTSTRAP OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // A bootstrap is a minimal UUPS implementation that allows an ERC1967 proxy - // pointing to it to be upgraded. The ERC1967 proxy can then be deployed to a - // deterministic address independent of the implementation: - // ``` - // address bootstrap = LibClone.erc1967Bootstrap(); - // address instance = LibClone.deployDeterministicERC1967(0, bootstrap, salt); - // LibClone.bootstrapERC1967(bootstrap, implementation); - // ``` - - /// @dev Deploys the ERC1967 bootstrap if it has not been deployed. - function erc1967Bootstrap() internal returns (address) { - return erc1967Bootstrap(address(this)); - } - - /// @dev Deploys the ERC1967 bootstrap if it has not been deployed. - function erc1967Bootstrap(address authorizedUpgrader) internal returns (address bootstrap) { - bytes memory c = initCodeERC1967Bootstrap(authorizedUpgrader); - bootstrap = predictDeterministicAddress(keccak256(c), bytes32(0), address(this)); - /// @solidity memory-safe-assembly - assembly { - if iszero(extcodesize(bootstrap)) { - if iszero(create2(0, add(c, 0x20), mload(c), 0)) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - } - - /// @dev Replaces the implementation at `instance`. - function bootstrapERC1967(address instance, address implementation) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, implementation) - if iszero(call(gas(), instance, 0, 0x0c, 0x14, codesize(), 0x00)) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Replaces the implementation at `instance`, and then call it with `data`. - function bootstrapERC1967AndCall(address instance, address implementation, bytes memory data) - internal - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(data) - mstore(data, implementation) - if iszero(call(gas(), instance, 0, add(data, 0x0c), add(n, 0x14), codesize(), 0x00)) { - if iszero(returndatasize()) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - returndatacopy(mload(0x40), 0x00, returndatasize()) - revert(mload(0x40), returndatasize()) - } - mstore(data, n) // Restore the length of `data`. - } - } - - /// @dev Returns the implementation address of the ERC1967 bootstrap for this contract. - function predictDeterministicAddressERC1967Bootstrap() internal view returns (address) { - return predictDeterministicAddressERC1967Bootstrap(address(this), address(this)); - } - - /// @dev Returns the implementation address of the ERC1967 bootstrap for this contract. - function predictDeterministicAddressERC1967Bootstrap( - address authorizedUpgrader, - address deployer - ) internal pure returns (address) { - bytes32 hash = initCodeHashERC1967Bootstrap(authorizedUpgrader); - return predictDeterministicAddress(hash, bytes32(0), deployer); - } - - /// @dev Returns the initialization code of the ERC1967 bootstrap. - function initCodeERC1967Bootstrap(address authorizedUpgrader) - internal - pure - returns (bytes memory c) - { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - mstore(add(c, 0x80), 0x3d3560601c5af46047573d6000383e3d38fd0000000000000000000000000000) - mstore(add(c, 0x60), 0xa920a3ca505d382bbc55601436116049575b005b363d3d373d3d601436036014) - mstore(add(c, 0x40), 0x0338573d3560601c7f360894a13ba1a3210667c828492db98dca3e2076cc3735) - mstore(add(c, 0x20), authorizedUpgrader) - mstore(add(c, 0x0c), 0x606880600a3d393df3fe3373) - mstore(c, 0x72) - mstore(0x40, add(c, 0xa0)) - } - } - - /// @dev Returns the initialization code hash of the ERC1967 bootstrap. - function initCodeHashERC1967Bootstrap(address authorizedUpgrader) - internal - pure - returns (bytes32) - { - return keccak256(initCodeERC1967Bootstrap(authorizedUpgrader)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MINIMAL ERC1967 BEACON PROXY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: If you use this proxy, you MUST make sure that the beacon is a - // valid ERC1967 beacon. This means that the beacon must always return a valid - // address upon a staticcall to `implementation()`, given sufficient gas. - // For performance, the deployment operations and the proxy assumes that the - // beacon is always valid and will NOT validate it. - - /// @dev Deploys a minimal ERC1967 beacon proxy. - function deployERC1967BeaconProxy(address beacon) internal returns (address instance) { - instance = deployERC1967BeaconProxy(0, beacon); - } - - /// @dev Deploys a minimal ERC1967 beacon proxy. - /// Deposits `value` ETH during deployment. - function deployERC1967BeaconProxy(uint256 value, address beacon) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - /** - * ---------------------------------------------------------------------------------+ - * CREATION (34 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * 60 runSize | PUSH1 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * 73 beac | PUSH20 beac | beac 0 r | [0..runSize): runtime code | - * 60 slotPos | PUSH1 slotPos | slotPos beac 0 r | [0..runSize): runtime code | - * 51 | MLOAD | slot beac 0 r | [0..runSize): runtime code | - * 55 | SSTORE | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * ---------------------------------------------------------------------------------| - * RUNTIME (82 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * | - * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 3d | RETURNDATASIZE | 0 cds | | - * 3d | RETURNDATASIZE | 0 0 cds | | - * 37 | CALLDATACOPY | | [0..calldatasize): calldata | - * | - * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | | - * 3d | RETURNDATASIZE | 0 0 | | - * 36 | CALLDATASIZE | cds 0 0 | [0..calldatasize): calldata | - * 3d | RETURNDATASIZE | 0 cds 0 0 | [0..calldatasize): calldata | - * | - * ~~~~~~~ beacon staticcall sub procedure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | - * 60 0x20 | PUSH1 0x20 | 32 | | - * 36 | CALLDATASIZE | cds 32 | | - * 60 0x04 | PUSH1 0x04 | 4 cds 32 | | - * 36 | CALLDATASIZE | cds 4 cds 32 | | - * 63 0x5c60da1b | PUSH4 0x5c60da1b | 0x5c60da1b cds 4 cds 32 | | - * 60 0xe0 | PUSH1 0xe0 | 224 0x5c60da1b cds 4 cds 32 | | - * 1b | SHL | sel cds 4 cds 32 | | - * 36 | CALLDATASIZE | cds sel cds 4 cds 32 | | - * 52 | MSTORE | cds 4 cds 32 | sel | - * 7f slot | PUSH32 slot | s cds 4 cds 32 | sel | - * 54 | SLOAD | beac cds 4 cds 32 | sel | - * 5a | GAS | g beac cds 4 cds 32 | sel | - * fa | STATICCALL | succ | impl | - * 50 | POP | | impl | - * 36 | CALLDATASIZE | cds | impl | - * 51 | MLOAD | impl | impl | - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | - * 5a | GAS | g impl 0 cds 0 0 | [0..calldatasize): calldata | - * f4 | DELEGATECALL | succ | [0..calldatasize): calldata | - * | - * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds succ | [0..calldatasize): calldata | - * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..calldatasize): calldata | - * 80 | DUP1 | 0 0 rds succ | [0..calldatasize): calldata | - * 3e | RETURNDATACOPY | succ | [0..returndatasize): returndata | - * | - * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: | - * 60 0x4d | PUSH1 0x4d | dest succ | [0..returndatasize): returndata | - * 57 | JUMPI | | [0..returndatasize): returndata | - * | - * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * fd | REVERT | | [0..returndatasize): returndata | - * | - * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | | [0..returndatasize): returndata | - * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | - * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | - * f3 | RETURN | | [0..returndatasize): returndata | - * ---------------------------------------------------------------------------------+ - */ - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(0x40, 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, beacon)))) - instance := create(value, 0x0c, 0x74) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Deploys a deterministic minimal ERC1967 beacon proxy with `salt`. - function deployDeterministicERC1967BeaconProxy(address beacon, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967BeaconProxy(0, beacon, salt); - } - - /// @dev Deploys a deterministic minimal ERC1967 beacon proxy with `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967BeaconProxy(uint256 value, address beacon, bytes32 salt) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(0x40, 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, beacon)))) - instance := create2(value, 0x0c, 0x74, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Creates a deterministic minimal ERC1967 beacon proxy with `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967BeaconProxy(address beacon, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967BeaconProxy(0, beacon, salt); - } - - /// @dev Creates a deterministic minimal ERC1967 beacon proxy with `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967BeaconProxy(uint256 value, address beacon, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(0x40, 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, beacon)))) - // Compute and store the bytecode hash. - mstore(add(m, 0x35), keccak256(0x0c, 0x74)) - mstore(m, shl(88, address())) - mstore8(m, 0xff) // Write the prefix. - mstore(add(m, 0x15), salt) - instance := keccak256(m, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, 0x0c, 0x74, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the initialization code of the minimal ERC1967 beacon proxy. - function initCodeERC1967BeaconProxy(address beacon) internal pure returns (bytes memory c) { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - mstore(add(c, 0x74), 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(add(c, 0x54), 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(add(c, 0x34), 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(add(c, 0x1d), beacon) - mstore(add(c, 0x09), 0x60523d8160223d3973) - mstore(add(c, 0x94), 0) - mstore(c, 0x74) // Store the length. - mstore(0x40, add(c, 0xa0)) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the minimal ERC1967 beacon proxy. - function initCodeHashERC1967BeaconProxy(address beacon) internal pure returns (bytes32 hash) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(0x40, 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, beacon)))) - hash := keccak256(0x0c, 0x74) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the address of the ERC1967 beacon proxy, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967BeaconProxy( - address beacon, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967BeaconProxy(beacon); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1967 BEACON PROXY WITH IMMUTABLE ARGS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a minimal ERC1967 beacon proxy with `args`. - function deployERC1967BeaconProxy(address beacon, bytes memory args) - internal - returns (address instance) - { - instance = deployERC1967BeaconProxy(0, beacon, args); - } - - /// @dev Deploys a minimal ERC1967 beacon proxy with `args`. - /// Deposits `value` ETH during deployment. - function deployERC1967BeaconProxy(uint256 value, address beacon, bytes memory args) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x8b), n)) - mstore(add(m, 0x6b), 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(add(m, 0x4b), 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(add(m, 0x2b), 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(add(m, 0x14), beacon) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - mstore(add(m, gt(n, 0xffad)), add(0xfe6100523d8160233d3973, shl(56, n))) - instance := create(value, add(m, 0x16), add(n, 0x75)) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Deploys a deterministic minimal ERC1967 beacon proxy with `args` and `salt`. - function deployDeterministicERC1967BeaconProxy(address beacon, bytes memory args, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967BeaconProxy(0, beacon, args, salt); - } - - /// @dev Deploys a deterministic minimal ERC1967 beacon proxy with `args` and `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967BeaconProxy( - uint256 value, - address beacon, - bytes memory args, - bytes32 salt - ) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x8b), n)) - mstore(add(m, 0x6b), 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(add(m, 0x4b), 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(add(m, 0x2b), 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(add(m, 0x14), beacon) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - mstore(add(m, gt(n, 0xffad)), add(0xfe6100523d8160233d3973, shl(56, n))) - instance := create2(value, add(m, 0x16), add(n, 0x75), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Creates a deterministic minimal ERC1967 beacon proxy with `args` and `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967BeaconProxy(address beacon, bytes memory args, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967BeaconProxy(0, beacon, args, salt); - } - - /// @dev Creates a deterministic minimal ERC1967 beacon proxy with `args` and `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967BeaconProxy( - uint256 value, - address beacon, - bytes memory args, - bytes32 salt - ) internal returns (bool alreadyDeployed, address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x8b), n)) - mstore(add(m, 0x6b), 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(add(m, 0x4b), 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(add(m, 0x2b), 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(add(m, 0x14), beacon) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - mstore(add(m, gt(n, 0xffad)), add(0xfe6100523d8160233d3973, shl(56, n))) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(add(m, 0x16), add(n, 0x75))) - mstore(0x01, shl(96, address())) - mstore(0x15, salt) - instance := keccak256(0x00, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, add(m, 0x16), add(n, 0x75), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the initialization code of the minimal ERC1967 beacon proxy. - function initCodeERC1967BeaconProxy(address beacon, bytes memory args) - internal - pure - returns (bytes memory c) - { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffad)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(c, 0x95), i), mload(add(add(args, 0x20), i))) - } - mstore(add(c, 0x75), 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(add(c, 0x55), 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(add(c, 0x35), 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(add(c, 0x1e), beacon) - mstore(add(c, 0x0a), add(0x6100523d8160233d3973, shl(56, n))) - mstore(c, add(n, 0x75)) // Store the length. - mstore(add(c, add(n, 0x95)), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(c, add(n, 0xb5))) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the minimal ERC1967 beacon proxy with `args`. - function initCodeHashERC1967BeaconProxy(address beacon, bytes memory args) - internal - pure - returns (bytes32 hash) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x52 = 0xffad`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffad)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(m, 0x8b), i), mload(add(add(args, 0x20), i))) - } - mstore(add(m, 0x6b), 0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3) - mstore(add(m, 0x4b), 0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c) - mstore(add(m, 0x2b), 0x60195155f3363d3d373d3d363d602036600436635c60da) - mstore(add(m, 0x14), beacon) - mstore(m, add(0x6100523d8160233d3973, shl(56, n))) - hash := keccak256(add(m, 0x16), add(n, 0x75)) - } - } - - /// @dev Returns the address of the ERC1967 beacon proxy with `args`, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967BeaconProxy( - address beacon, - bytes memory args, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967BeaconProxy(beacon, args); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /// @dev Equivalent to `argsOnERC1967BeaconProxy(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967BeaconProxy(address instance) internal view returns (bytes memory args) { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - mstore(args, and(0xffffffffff, sub(extcodesize(instance), 0x52))) // Store the length. - extcodecopy(instance, add(args, 0x20), 0x52, add(mload(args), 0x20)) - mstore(0x40, add(mload(args), add(args, 0x40))) // Allocate memory. - } - } - - /// @dev Equivalent to `argsOnERC1967BeaconProxy(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967BeaconProxy(address instance, uint256 start) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - let n := and(0xffffffffff, sub(extcodesize(instance), 0x52)) - let l := sub(n, and(0xffffff, mul(lt(start, n), start))) - extcodecopy(instance, args, add(start, 0x32), add(l, 0x40)) - mstore(args, mul(sub(n, start), lt(start, n))) // Store the length. - mstore(0x40, add(args, add(0x40, mload(args)))) // Allocate memory. - } - } - - /// @dev Returns a slice of the immutable arguments on `instance` from `start` to `end`. - /// `start` and `end` will be clamped to the range `[0, args.length]`. - /// The `instance` MUST be deployed via the ERC1967 beacon proxy with immutable args functions. - /// Otherwise, the behavior is undefined. - /// Out-of-gas reverts if `instance` does not have any code. - function argsOnERC1967BeaconProxy(address instance, uint256 start, uint256 end) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - if iszero(lt(end, 0xffff)) { end := 0xffff } - let d := mul(sub(end, start), lt(start, end)) - extcodecopy(instance, args, add(start, 0x32), add(d, 0x20)) - if iszero(and(0xff, mload(add(args, d)))) { - let n := sub(extcodesize(instance), 0x52) - returndatacopy(returndatasize(), returndatasize(), shr(40, n)) - d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n)))) - } - mstore(args, d) // Store the length. - mstore(add(add(args, 0x20), d), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(args, 0x40), d)) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1967I BEACON PROXY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: This proxy has a special code path that activates if `calldatasize() == 1`. - // This code path skips the delegatecall and directly returns the `implementation` address. - // The returned implementation is guaranteed to be valid if the keccak256 of the - // proxy's code is equal to `ERC1967_BEACON_PROXY_CODE_HASH`. - // - // If you use this proxy, you MUST make sure that the beacon is a - // valid ERC1967 beacon. This means that the beacon must always return a valid - // address upon a staticcall to `implementation()`, given sufficient gas. - // For performance, the deployment operations and the proxy assumes that the - // beacon is always valid and will NOT validate it. - - /// @dev Deploys a ERC1967I beacon proxy. - function deployERC1967IBeaconProxy(address beacon) internal returns (address instance) { - instance = deployERC1967IBeaconProxy(0, beacon); - } - - /// @dev Deploys a ERC1967I beacon proxy. - /// Deposits `value` ETH during deployment. - function deployERC1967IBeaconProxy(uint256 value, address beacon) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - /** - * ---------------------------------------------------------------------------------+ - * CREATION (34 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * 60 runSize | PUSH1 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * 73 beac | PUSH20 beac | beac 0 r | [0..runSize): runtime code | - * 60 slotPos | PUSH1 slotPos | slotPos beac 0 r | [0..runSize): runtime code | - * 51 | MLOAD | slot beac 0 r | [0..runSize): runtime code | - * 55 | SSTORE | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * ---------------------------------------------------------------------------------| - * RUNTIME (87 bytes) | - * ---------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------| - * | - * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 3d | RETURNDATASIZE | 0 cds | | - * 3d | RETURNDATASIZE | 0 0 cds | | - * 37 | CALLDATACOPY | | [0..calldatasize): calldata | - * | - * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | | - * 3d | RETURNDATASIZE | 0 0 | | - * 36 | CALLDATASIZE | cds 0 0 | [0..calldatasize): calldata | - * 3d | RETURNDATASIZE | 0 cds 0 0 | [0..calldatasize): calldata | - * | - * ~~~~~~~ beacon staticcall sub procedure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | - * 60 0x20 | PUSH1 0x20 | 32 | | - * 36 | CALLDATASIZE | cds 32 | | - * 60 0x04 | PUSH1 0x04 | 4 cds 32 | | - * 36 | CALLDATASIZE | cds 4 cds 32 | | - * 63 0x5c60da1b | PUSH4 0x5c60da1b | 0x5c60da1b cds 4 cds 32 | | - * 60 0xe0 | PUSH1 0xe0 | 224 0x5c60da1b cds 4 cds 32 | | - * 1b | SHL | sel cds 4 cds 32 | | - * 36 | CALLDATASIZE | cds sel cds 4 cds 32 | | - * 52 | MSTORE | cds 4 cds 32 | sel | - * 7f slot | PUSH32 slot | s cds 4 cds 32 | sel | - * 54 | SLOAD | beac cds 4 cds 32 | sel | - * 5a | GAS | g beac cds 4 cds 32 | sel | - * fa | STATICCALL | succ | impl | - * ~~~~~~ check calldatasize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | - * 36 | CALLDATASIZE | cds succ | | - * 14 | EQ | | impl | - * 60 0x52 | PUSH1 0x52 | | impl | - * 57 | JUMPI | | impl | - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | - * 36 | CALLDATASIZE | cds | impl | - * 51 | MLOAD | impl | impl | - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | - * 5a | GAS | g impl 0 cds 0 0 | [0..calldatasize): calldata | - * f4 | DELEGATECALL | succ | [0..calldatasize): calldata | - * | - * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds succ | [0..calldatasize): calldata | - * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..calldatasize): calldata | - * 60 0x01 | PUSH1 0x01 | 1 0 rds succ | [0..calldatasize): calldata | - * 3e | RETURNDATACOPY | succ | [1..returndatasize): returndata | - * | - * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: | - * 60 0x52 | PUSH1 0x52 | dest succ | [1..returndatasize): returndata | - * 57 | JUMPI | | [1..returndatasize): returndata | - * | - * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds | [1..returndatasize): returndata | - * 60 0x01 | PUSH1 0x01 | 1 rds | [1..returndatasize): returndata | - * fd | REVERT | | [1..returndatasize): returndata | - * | - * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | | [1..returndatasize): returndata | - * 3d | RETURNDATASIZE | rds | [1..returndatasize): returndata | - * 60 0x01 | PUSH1 0x01 | 1 rds | [1..returndatasize): returndata | - * f3 | RETURN | | [1..returndatasize): returndata | - * ---------------------------------------------------------------------------------+ - */ - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(0x40, 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(0x04, or(shl(160, 0x60573d8160223d3973), shr(96, shl(96, beacon)))) - instance := create(value, 0x07, 0x79) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Deploys a deterministic ERC1967I beacon proxy with `salt`. - function deployDeterministicERC1967IBeaconProxy(address beacon, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967IBeaconProxy(0, beacon, salt); - } - - /// @dev Deploys a deterministic ERC1967I beacon proxy with `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967IBeaconProxy(uint256 value, address beacon, bytes32 salt) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(0x40, 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(0x04, or(shl(160, 0x60573d8160223d3973), shr(96, shl(96, beacon)))) - instance := create2(value, 0x07, 0x79, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Creates a deterministic ERC1967I beacon proxy with `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967IBeaconProxy(address beacon, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967IBeaconProxy(0, beacon, salt); - } - - /// @dev Creates a deterministic ERC1967I beacon proxy with `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967IBeaconProxy(uint256 value, address beacon, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(0x40, 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(0x04, or(shl(160, 0x60573d8160223d3973), shr(96, shl(96, beacon)))) - // Compute and store the bytecode hash. - mstore(add(m, 0x35), keccak256(0x07, 0x79)) - mstore(m, shl(88, address())) - mstore8(m, 0xff) // Write the prefix. - mstore(add(m, 0x15), salt) - instance := keccak256(m, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, 0x07, 0x79, salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the initialization code of the ERC1967I beacon proxy. - function initCodeERC1967IBeaconProxy(address beacon) internal pure returns (bytes memory c) { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - mstore(add(c, 0x79), 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(add(c, 0x59), 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(add(c, 0x39), 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(add(c, 0x1d), beacon) - mstore(add(c, 0x09), 0x60573d8160223d3973) - mstore(add(c, 0x99), 0) - mstore(c, 0x79) // Store the length. - mstore(0x40, add(c, 0xa0)) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the ERC1967I beacon proxy. - function initCodeHashERC1967IBeaconProxy(address beacon) internal pure returns (bytes32 hash) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(0x40, 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(0x20, 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(0x04, or(shl(160, 0x60573d8160223d3973), shr(96, shl(96, beacon)))) - hash := keccak256(0x07, 0x79) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero slot. - } - } - - /// @dev Returns the address of the ERC1967I beacon proxy, with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967IBeaconProxy( - address beacon, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967IBeaconProxy(beacon); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1967I BEACON PROXY WITH IMMUTABLE ARGS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a ERC1967I beacon proxy with `args. - function deployERC1967IBeaconProxy(address beacon, bytes memory args) - internal - returns (address instance) - { - instance = deployERC1967IBeaconProxy(0, beacon, args); - } - - /// @dev Deploys a ERC1967I beacon proxy with `args. - /// Deposits `value` ETH during deployment. - function deployERC1967IBeaconProxy(uint256 value, address beacon, bytes memory args) - internal - returns (address instance) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x90), n)) - mstore(add(m, 0x70), 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(add(m, 0x50), 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(add(m, 0x30), 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(add(m, 0x14), beacon) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x57 = 0xffa8`. - mstore(add(m, gt(n, 0xffa8)), add(0xfe6100573d8160233d3973, shl(56, n))) - instance := create(value, add(m, 0x16), add(n, 0x7a)) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Deploys a deterministic ERC1967I beacon proxy with `args` and `salt`. - function deployDeterministicERC1967IBeaconProxy(address beacon, bytes memory args, bytes32 salt) - internal - returns (address instance) - { - instance = deployDeterministicERC1967IBeaconProxy(0, beacon, args, salt); - } - - /// @dev Deploys a deterministic ERC1967I beacon proxy with `args` and `salt`. - /// Deposits `value` ETH during deployment. - function deployDeterministicERC1967IBeaconProxy( - uint256 value, - address beacon, - bytes memory args, - bytes32 salt - ) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x90), n)) - mstore(add(m, 0x70), 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(add(m, 0x50), 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(add(m, 0x30), 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(add(m, 0x14), beacon) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x57 = 0xffa8`. - mstore(add(m, gt(n, 0xffa8)), add(0xfe6100573d8160233d3973, shl(56, n))) - instance := create2(value, add(m, 0x16), add(n, 0x7a), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Creates a deterministic ERC1967I beacon proxy with `args` and `salt`. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967IBeaconProxy(address beacon, bytes memory args, bytes32 salt) - internal - returns (bool alreadyDeployed, address instance) - { - return createDeterministicERC1967IBeaconProxy(0, beacon, args, salt); - } - - /// @dev Creates a deterministic ERC1967I beacon proxy with `args` and `salt`. - /// Deposits `value` ETH during deployment. - /// Note: This method is intended for use in ERC4337 factories, - /// which are expected to NOT revert if the proxy is already deployed. - function createDeterministicERC1967IBeaconProxy( - uint256 value, - address beacon, - bytes memory args, - bytes32 salt - ) internal returns (bool alreadyDeployed, address instance) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(args) - pop(staticcall(gas(), 4, add(args, 0x20), n, add(m, 0x90), n)) - mstore(add(m, 0x70), 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(add(m, 0x50), 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(add(m, 0x30), 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(add(m, 0x14), beacon) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x57 = 0xffa8`. - mstore(add(m, gt(n, 0xffa8)), add(0xfe6100573d8160233d3973, shl(56, n))) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(add(m, 0x16), add(n, 0x7a))) - mstore(0x01, shl(96, address())) - mstore(0x15, salt) - instance := keccak256(0x00, 0x55) - for {} 1 {} { - if iszero(extcodesize(instance)) { - instance := create2(value, add(m, 0x16), add(n, 0x7a), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - break - } - alreadyDeployed := 1 - if iszero(value) { break } - if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - break - } - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the initialization code of the ERC1967I beacon proxy with `args`. - function initCodeERC1967IBeaconProxy(address beacon, bytes memory args) - internal - pure - returns (bytes memory c) - { - /// @solidity memory-safe-assembly - assembly { - c := mload(0x40) - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x57 = 0xffa8`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffa8)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(c, 0x9a), i), mload(add(add(args, 0x20), i))) - } - mstore(add(c, 0x7a), 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(add(c, 0x5a), 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(add(c, 0x3a), 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(add(c, 0x1e), beacon) - mstore(add(c, 0x0a), add(0x6100573d8160233d3973, shl(56, n))) - mstore(add(c, add(n, 0x9a)), 0) - mstore(c, add(n, 0x7a)) // Store the length. - mstore(0x40, add(c, add(n, 0xba))) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the ERC1967I beacon proxy with `args`. - function initCodeHashERC1967IBeaconProxy(address beacon, bytes memory args) - internal - pure - returns (bytes32 hash) - { - /// @solidity memory-safe-assembly - assembly { - let c := mload(0x40) // Cache the free memory pointer. - let n := mload(args) - // Do a out-of-gas revert if `n` is greater than `0xffff - 0x57 = 0xffa8`. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xffa8)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(c, 0x90), i), mload(add(add(args, 0x20), i))) - } - mstore(add(c, 0x70), 0x3d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3) - mstore(add(c, 0x50), 0x527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b3513) - mstore(add(c, 0x30), 0x60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36) - mstore(add(c, 0x14), beacon) - mstore(c, add(0x6100573d8160233d3973, shl(56, n))) - hash := keccak256(add(c, 0x16), add(n, 0x7a)) - } - } - - /// @dev Returns the address of the ERC1967I beacon proxy, with `args` and salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddressERC1967IBeaconProxy( - address beacon, - bytes memory args, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHashERC1967IBeaconProxy(beacon, args); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /// @dev Equivalent to `argsOnERC1967IBeaconProxy(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967IBeaconProxy(address instance) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - mstore(args, and(0xffffffffff, sub(extcodesize(instance), 0x57))) // Store the length. - extcodecopy(instance, add(args, 0x20), 0x57, add(mload(args), 0x20)) - mstore(0x40, add(mload(args), add(args, 0x40))) // Allocate memory. - } - } - - /// @dev Equivalent to `argsOnERC1967IBeaconProxy(instance, start, 2 ** 256 - 1)`. - function argsOnERC1967IBeaconProxy(address instance, uint256 start) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - let n := and(0xffffffffff, sub(extcodesize(instance), 0x57)) - let l := sub(n, and(0xffffff, mul(lt(start, n), start))) - extcodecopy(instance, args, add(start, 0x37), add(l, 0x40)) - mstore(args, mul(sub(n, start), lt(start, n))) // Store the length. - mstore(0x40, add(args, add(0x40, mload(args)))) // Allocate memory. - } - } - - /// @dev Returns a slice of the immutable arguments on `instance` from `start` to `end`. - /// `start` and `end` will be clamped to the range `[0, args.length]`. - /// The `instance` MUST be deployed via the ERC1967I beacon proxy with immutable args functions. - /// Otherwise, the behavior is undefined. - /// Out-of-gas reverts if `instance` does not have any code. - function argsOnERC1967IBeaconProxy(address instance, uint256 start, uint256 end) - internal - view - returns (bytes memory args) - { - /// @solidity memory-safe-assembly - assembly { - args := mload(0x40) - if iszero(lt(end, 0xffff)) { end := 0xffff } - let d := mul(sub(end, start), lt(start, end)) - extcodecopy(instance, args, add(start, 0x37), add(d, 0x20)) - if iszero(and(0xff, mload(add(args, d)))) { - let n := sub(extcodesize(instance), 0x57) - returndatacopy(returndatasize(), returndatasize(), shr(40, n)) - d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n)))) - } - mstore(args, d) // Store the length. - mstore(add(add(args, 0x20), d), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(args, 0x40), d)) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `address(0)` if the implementation address cannot be determined. - function implementationOf(address instance) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - for { extcodecopy(instance, 0x00, 0x00, 0x57) } 1 {} { - if mload(0x2d) { - // ERC1967I and ERC1967IBeaconProxy detection. - if or( - eq(keccak256(0x00, 0x52), ERC1967I_CODE_HASH), - eq(keccak256(0x00, 0x57), ERC1967I_BEACON_PROXY_CODE_HASH) - ) { - pop(staticcall(gas(), instance, 0x00, 0x01, 0x00, 0x20)) - result := mload(0x0c) - break - } - } - // 0age clone detection. - result := mload(0x0b) - codecopy(0x0b, codesize(), 0x14) // Zeroize the 20 bytes for the address. - if iszero(xor(keccak256(0x00, 0x2c), CLONE_CODE_HASH)) { break } - mstore(0x0b, result) // Restore the zeroized memory. - // CWIA detection. - result := mload(0x0a) - codecopy(0x0a, codesize(), 0x14) // Zeroize the 20 bytes for the address. - if iszero(xor(keccak256(0x00, 0x2d), CWIA_CODE_HASH)) { break } - mstore(0x0a, result) // Restore the zeroized memory. - // PUSH0 clone detection. - result := mload(0x09) - codecopy(0x09, codesize(), 0x14) // Zeroize the 20 bytes for the address. - result := shr(xor(keccak256(0x00, 0x2d), PUSH0_CLONE_CODE_HASH), result) - break - } - result := shr(96, result) - mstore(0x37, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Returns the address when a contract with initialization code hash, - /// `hash`, is deployed with `salt`, by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddress(bytes32 hash, bytes32 salt, address deployer) - internal - pure - returns (address predicted) - { - /// @solidity memory-safe-assembly - assembly { - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, hash) - mstore(0x01, shl(96, deployer)) - mstore(0x15, salt) - predicted := keccak256(0x00, 0x55) - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Requires that `salt` starts with either the zero address or `by`. - function checkStartsWith(bytes32 salt, address by) internal pure { - /// @solidity memory-safe-assembly - assembly { - // If the salt does not start with the zero address or `by`. - if iszero(or(iszero(shr(96, salt)), eq(shr(96, shl(96, by)), shr(96, salt)))) { - mstore(0x00, 0x0c4549ef) // `SaltDoesNotStartWith()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns the `bytes32` at `offset` in `args`, without any bounds checks. - /// To load an address, you can use `address(bytes20(argLoad(args, offset)))`. - function argLoad(bytes memory args, uint256 offset) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(args, 0x20), offset)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibMap.sol b/grouperBot/lib/solady/src/utils/LibMap.sol deleted file mode 100644 index edac97a..0000000 --- a/grouperBot/lib/solady/src/utils/LibMap.sol +++ /dev/null @@ -1,309 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for storage of packed unsigned integers. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibMap.sol) -library LibMap { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A uint8 map in storage. - struct Uint8Map { - mapping(uint256 => uint256) map; - } - - /// @dev A uint16 map in storage. - struct Uint16Map { - mapping(uint256 => uint256) map; - } - - /// @dev A uint32 map in storage. - struct Uint32Map { - mapping(uint256 => uint256) map; - } - - /// @dev A uint40 map in storage. Useful for storing timestamps up to 34841 A.D. - struct Uint40Map { - mapping(uint256 => uint256) map; - } - - /// @dev A uint64 map in storage. - struct Uint64Map { - mapping(uint256 => uint256) map; - } - - /// @dev A uint128 map in storage. - struct Uint128Map { - mapping(uint256 => uint256) map; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* GETTERS / SETTERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the uint8 value at `index` in `map`. - function get(Uint8Map storage map, uint256 index) internal view returns (uint8 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(5, index)) - result := byte(and(31, not(index)), sload(keccak256(0x00, 0x40))) - } - } - - /// @dev Updates the uint8 value at `index` in `map`. - function set(Uint8Map storage map, uint256 index, uint8 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(5, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - mstore(0x00, sload(s)) - mstore8(and(31, not(index)), value) - sstore(s, mload(0x00)) - } - } - - /// @dev Returns the uint16 value at `index` in `map`. - function get(Uint16Map storage map, uint256 index) internal view returns (uint16 result) { - result = uint16(map.map[index >> 4] >> ((index & 15) << 4)); - } - - /// @dev Updates the uint16 value at `index` in `map`. - function set(Uint16Map storage map, uint256 index, uint16 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(4, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(4, and(index, 15)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint32 value at `index` in `map`. - function get(Uint32Map storage map, uint256 index) internal view returns (uint32 result) { - result = uint32(map.map[index >> 3] >> ((index & 7) << 5)); - } - - /// @dev Updates the uint32 value at `index` in `map`. - function set(Uint32Map storage map, uint256 index, uint32 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(3, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(5, and(index, 7)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint40 value at `index` in `map`. - function get(Uint40Map storage map, uint256 index) internal view returns (uint40 result) { - unchecked { - result = uint40(map.map[index / 6] >> ((index % 6) * 40)); - } - } - - /// @dev Updates the uint40 value at `index` in `map`. - function set(Uint40Map storage map, uint256 index, uint40 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, div(index, 6)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := mul(40, mod(index, 6)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint64 value at `index` in `map`. - function get(Uint64Map storage map, uint256 index) internal view returns (uint64 result) { - result = uint64(map.map[index >> 2] >> ((index & 3) << 6)); - } - - /// @dev Updates the uint64 value at `index` in `map`. - function set(Uint64Map storage map, uint256 index, uint64 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(2, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(6, and(index, 3)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffffffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint128 value at `index` in `map`. - function get(Uint128Map storage map, uint256 index) internal view returns (uint128 result) { - result = uint128(map.map[index >> 1] >> ((index & 1) << 7)); - } - - /// @dev Updates the uint128 value at `index` in `map`. - function set(Uint128Map storage map, uint256 index, uint128 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(1, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(7, and(index, 1)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffffffffffffffffffffffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the value at `index` in `map`. - function get(mapping(uint256 => uint256) storage map, uint256 index, uint256 bitWidth) - internal - view - returns (uint256 result) - { - unchecked { - uint256 d = _rawDiv(256, bitWidth); // Bucket size. - uint256 m = (1 << bitWidth) - 1; // Value mask. - result = (map[_rawDiv(index, d)] >> (_rawMod(index, d) * bitWidth)) & m; - } - } - - /// @dev Updates the value at `index` in `map`. - function set( - mapping(uint256 => uint256) storage map, - uint256 index, - uint256 value, - uint256 bitWidth - ) internal { - unchecked { - uint256 d = _rawDiv(256, bitWidth); // Bucket size. - uint256 m = (1 << bitWidth) - 1; // Value mask. - uint256 o = _rawMod(index, d) * bitWidth; // Storage slot offset (bits). - map[_rawDiv(index, d)] ^= (((map[_rawDiv(index, d)] >> o) ^ value) & m) << o; - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BINARY SEARCH */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // The following functions search in the range of [`start`, `end`) - // (i.e. `start <= index < end`). - // The range must be sorted in ascending order. - // `index` precedence: equal to > nearest before > nearest after. - // An invalid search range will simply return `(found = false, index = start)`. - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint8Map storage map, uint8 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 8); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint16Map storage map, uint16 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 16); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint32Map storage map, uint32 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 32); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint40Map storage map, uint40 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 40); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint64Map storage map, uint64 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 64); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint128Map storage map, uint128 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 128); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted( - mapping(uint256 => uint256) storage map, - uint256 needle, - uint256 start, - uint256 end, - uint256 bitWidth - ) internal view returns (bool found, uint256 index) { - unchecked { - if (start >= end) end = start; - uint256 t; - uint256 o = start - 1; // Offset to derive the actual index. - uint256 l = 1; // Low. - uint256 d = _rawDiv(256, bitWidth); // Bucket size. - uint256 m = (1 << bitWidth) - 1; // Value mask. - uint256 h = end - start; // High. - while (true) { - index = (l & h) + ((l ^ h) >> 1); - if (l > h) break; - t = (map[_rawDiv(index + o, d)] >> (_rawMod(index + o, d) * bitWidth)) & m; - if (t == needle) break; - if (needle <= t) h = index - 1; - else l = index + 1; - } - /// @solidity memory-safe-assembly - assembly { - m := or(iszero(index), iszero(bitWidth)) - found := iszero(or(xor(t, needle), m)) - index := add(o, xor(index, mul(xor(index, 1), m))) - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `x / y`, returning 0 if `y` is zero. - function _rawDiv(uint256 x, uint256 y) private pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := div(x, y) - } - } - - /// @dev Returns `x % y`, returning 0 if `y` is zero. - function _rawMod(uint256 x, uint256 y) private pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mod(x, y) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibPRNG.sol b/grouperBot/lib/solady/src/utils/LibPRNG.sol deleted file mode 100644 index 4b49a69..0000000 --- a/grouperBot/lib/solady/src/utils/LibPRNG.sol +++ /dev/null @@ -1,500 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for generating pseudorandom numbers. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibPRNG.sol) -/// @author LazyShuffler based on NextShuffler by aschlosberg (divergencearran) -/// (https://github.com/divergencetech/ethier/blob/main/contracts/random/NextShuffler.sol) -library LibPRNG { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The initial length must be greater than zero and less than `2**32 - 1`. - error InvalidInitialLazyShufflerLength(); - - /// @dev The new length must not be less than the current length. - error InvalidNewLazyShufflerLength(); - - /// @dev The lazy shuffler has not been initialized. - error LazyShufflerNotInitialized(); - - /// @dev Cannot double initialize the lazy shuffler. - error LazyShufflerAlreadyInitialized(); - - /// @dev The lazy shuffle has finished. - error LazyShuffleFinished(); - - /// @dev The queried index is out of bounds. - error LazyShufflerGetOutOfBounds(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The scalar of ETH and most ERC20s. - uint256 internal constant WAD = 1e18; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A pseudorandom number state in memory. - struct PRNG { - uint256 state; - } - - /// @dev A lazy Fisher-Yates shuffler for a range `[0..n)` in storage. - struct LazyShuffler { - // Bits Layout: - // - [0..31] `numShuffled` - // - [32..223] `permutationSlot` - // - [224..255] `length` - uint256 _state; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Seeds the `prng` with `state`. - function seed(PRNG memory prng, uint256 state) internal pure { - /// @solidity memory-safe-assembly - assembly { - mstore(prng, state) - } - } - - /// @dev Returns the next pseudorandom uint256. - /// All bits of the returned uint256 pass the NIST Statistical Test Suite. - function next(PRNG memory prng) internal pure returns (uint256 result) { - // We simply use `keccak256` for a great balance between - // runtime gas costs, bytecode size, and statistical properties. - // - // A high-quality LCG with a 32-byte state - // is only about 30% more gas efficient during runtime, - // but requires a 32-byte multiplier, which can cause bytecode bloat - // when this function is inlined. - // - // Using this method is about 2x more efficient than - // `nextRandomness = uint256(keccak256(abi.encode(randomness)))`. - /// @solidity memory-safe-assembly - assembly { - result := keccak256(prng, 0x20) - mstore(prng, result) - } - } - - /// @dev Returns a pseudorandom uint256, uniformly distributed - /// between 0 (inclusive) and `upper` (exclusive). - /// If your modulus is big, this method is recommended - /// for uniform sampling to avoid modulo bias. - /// For uniform sampling across all uint256 values, - /// or for small enough moduli such that the bias is negligible, - /// use {next} instead. - function uniform(PRNG memory prng, uint256 upper) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - result := keccak256(prng, 0x20) - mstore(prng, result) - if iszero(lt(result, mod(sub(0, upper), upper))) { break } - } - result := mod(result, upper) - } - } - - /// @dev Returns a sample from the standard normal distribution denominated in `WAD`. - function standardNormalWad(PRNG memory prng) internal pure returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - // Technically, this is the Irwin-Hall distribution with 20 samples. - // The chance of drawing a sample outside 10 σ from the standard normal distribution - // is ≈ 0.000000000000000000000015, which is insignificant for most practical purposes. - // Passes the Kolmogorov-Smirnov test for 200k samples. Uses about 322 gas. - result := keccak256(prng, 0x20) - mstore(prng, result) - let n := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43 // Prime. - let a := 0x100000000000000000000000000000051 // Prime and a primitive root of `n`. - let m := 0x1fffffffffffffff1fffffffffffffff1fffffffffffffff1fffffffffffffff - let s := 0x1000000000000000100000000000000010000000000000001 - let r1 := mulmod(result, a, n) - let r2 := mulmod(r1, a, n) - let r3 := mulmod(r2, a, n) - // forgefmt: disable-next-item - result := sub(sar(96, mul(26614938895861601847173011183, - add(add(shr(192, mul(s, add(and(m, result), and(m, r1)))), - shr(192, mul(s, add(and(m, r2), and(m, r3))))), - shr(192, mul(s, and(m, mulmod(r3, a, n))))))), 7745966692414833770) - } - } - - /// @dev Returns a sample from the unit exponential distribution denominated in `WAD`. - function exponentialWad(PRNG memory prng) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - // Passes the Kolmogorov-Smirnov test for 200k samples. - // Gas usage varies, starting from about 172+ gas. - let r := keccak256(prng, 0x20) - mstore(prng, r) - let p := shl(129, r) - let w := shl(1, r) - if iszero(gt(w, p)) { - let n := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43 // Prime. - let a := 0x100000000000000000000000000000051 // Prime and a primitive root of `n`. - for {} 1 {} { - r := mulmod(r, a, n) - if iszero(lt(shl(129, r), w)) { - r := mulmod(r, a, n) - result := add(1000000000000000000, result) - w := shl(1, r) - p := shl(129, r) - if iszero(lt(w, p)) { break } - continue - } - w := shl(1, r) - if iszero(lt(w, shl(129, r))) { break } - } - } - result := add(div(p, shl(129, 170141183460469231732)), result) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MEMORY ARRAY SHUFFLING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Shuffles the array in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - let w := not(0) - let mask := shr(128, w) - if n { - for { a := add(a, 0x20) } 1 {} { - // We can just directly use `keccak256`, cuz - // the other approaches don't save much. - let r := keccak256(prng, 0x20) - mstore(prng, r) - - // Note that there will be a very tiny modulo bias - // if the length of the array is not a power of 2. - // For all practical purposes, it is negligible - // and will not be a fairness or security concern. - { - let j := add(a, shl(5, mod(shr(128, r), n))) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let i := add(a, shl(5, n)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - } - - { - let j := add(a, shl(5, mod(and(r, mask), n))) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let i := add(a, shl(5, n)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - } - } - } - } - } - - /// @dev Shuffles the array in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, int256[] memory a) internal pure { - shuffle(prng, _toUints(a)); - } - - /// @dev Shuffles the array in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, address[] memory a) internal pure { - shuffle(prng, _toUints(a)); - } - - /// @dev Partially shuffles the array in-place with Fisher-Yates shuffle. - /// The first `k` elements will be uniformly sampled without replacement. - function shuffle(PRNG memory prng, uint256[] memory a, uint256 k) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - k := xor(k, mul(xor(k, n), lt(n, k))) // `min(n, k)`. - if k { - let mask := shr(128, not(0)) - let b := 0 - for { a := add(a, 0x20) } 1 {} { - // We can just directly use `keccak256`, cuz - // the other approaches don't save much. - let r := keccak256(prng, 0x20) - mstore(prng, r) - - // Note that there will be a very tiny modulo bias - // if the length of the array is not a power of 2. - // For all practical purposes, it is negligible - // and will not be a fairness or security concern. - { - let j := add(a, shl(5, add(b, mod(shr(128, r), sub(n, b))))) - let i := add(a, shl(5, b)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - b := add(b, 1) - if eq(b, k) { break } - } - - { - let j := add(a, shl(5, add(b, mod(and(r, mask), sub(n, b))))) - let i := add(a, shl(5, b)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - b := add(b, 1) - if eq(b, k) { break } - } - } - } - } - } - - /// @dev Partially shuffles the array in-place with Fisher-Yates shuffle. - /// The first `k` elements will be uniformly sampled without replacement. - function shuffle(PRNG memory prng, int256[] memory a, uint256 k) internal pure { - shuffle(prng, _toUints(a), k); - } - - /// @dev Partially shuffles the array in-place with Fisher-Yates shuffle. - /// The first `k` elements will be uniformly sampled without replacement. - function shuffle(PRNG memory prng, address[] memory a, uint256 k) internal pure { - shuffle(prng, _toUints(a), k); - } - - /// @dev Shuffles the bytes in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, bytes memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - let w := not(0) - let mask := shr(128, w) - if n { - let b := add(a, 0x01) - for { a := add(a, 0x20) } 1 {} { - // We can just directly use `keccak256`, cuz - // the other approaches don't save much. - let r := keccak256(prng, 0x20) - mstore(prng, r) - - // Note that there will be a very tiny modulo bias - // if the length of the array is not a power of 2. - // For all practical purposes, it is negligible - // and will not be a fairness or security concern. - { - let o := mod(shr(128, r), n) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let t := mload(add(b, n)) - mstore8(add(a, n), mload(add(b, o))) - mstore8(add(a, o), t) - } - - { - let o := mod(and(r, mask), n) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let t := mload(add(b, n)) - mstore8(add(a, n), mload(add(b, o))) - mstore8(add(a, o), t) - } - } - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE-BASED RANGE LAZY SHUFFLING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Initializes the state for lazy-shuffling the range `[0..n)`. - /// Reverts if `n == 0 || n >= 2**32 - 1`. - /// Reverts if `$` has already been initialized. - /// If you need to reduce the length after initialization, just use a fresh new `$`. - function initialize(LazyShuffler storage $, uint256 n) internal { - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(sub(n, 1), 0xfffffffe)) { - mstore(0x00, 0x83b53941) // `InvalidInitialLazyShufflerLength()`. - revert(0x1c, 0x04) - } - if sload($.slot) { - mstore(0x00, 0x0c9f11f2) // `LazyShufflerAlreadyInitialized()`. - revert(0x1c, 0x04) - } - mstore(0x00, $.slot) - sstore($.slot, or(shl(224, n), shl(32, shr(64, keccak256(0x00, 0x20))))) - } - } - - /// @dev Increases the length of `$`. - /// Reverts if `$` has not been initialized. - function grow(LazyShuffler storage $, uint256 n) internal { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) // The packed value at `$`. - // If the new length is smaller than the old length, revert. - if lt(n, shr(224, state)) { - mstore(0x00, 0xbed37c6e) // `InvalidNewLazyShufflerLength()`. - revert(0x1c, 0x04) - } - if iszero(state) { - mstore(0x00, 0x1ead2566) // `LazyShufflerNotInitialized()`. - revert(0x1c, 0x04) - } - sstore($.slot, or(shl(224, n), shr(32, shl(32, state)))) - } - } - - /// @dev Restarts the shuffler by setting `numShuffled` to zero, - /// such that all elements can be drawn again. - /// Restarting does NOT clear the internal permutation, nor changes the length. - /// Even with the same sequence of randomness, reshuffling can yield different results. - function restart(LazyShuffler storage $) internal { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) - if iszero(state) { - mstore(0x00, 0x1ead2566) // `LazyShufflerNotInitialized()`. - revert(0x1c, 0x04) - } - sstore($.slot, shl(32, shr(32, state))) - } - } - - /// @dev Returns the number of elements that have been shuffled. - function numShuffled(LazyShuffler storage $) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := and(0xffffffff, sload($.slot)) - } - } - - /// @dev Returns the length of `$`. - /// Returns zero if `$` is not initialized, else a non-zero value less than `2**32 - 1`. - function length(LazyShuffler storage $) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(224, sload($.slot)) - } - } - - /// @dev Returns if `$` has been initialized. - function initialized(LazyShuffler storage $) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := iszero(iszero(sload($.slot))) - } - } - - /// @dev Returns if there are any more elements left to shuffle. - /// Reverts if `$` is not initialized. - function finished(LazyShuffler storage $) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) // The packed value at `$`. - if iszero(state) { - mstore(0x00, 0x1ead2566) // `LazyShufflerNotInitialized()`. - revert(0x1c, 0x04) - } - result := eq(shr(224, state), and(0xffffffff, state)) - } - } - - /// @dev Returns the current value stored at `index`, accounting for all historical shuffling. - /// Reverts if `index` is greater than or equal to the `length` of `$`. - function get(LazyShuffler storage $, uint256 index) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) // The packed value at `$`. - let n := shr(224, state) // Length of `$`. - if iszero(lt(index, n)) { - mstore(0x00, 0x61367cc4) // `LazyShufflerGetOutOfBounds()`. - revert(0x1c, 0x04) - } - let u32 := gt(n, 0xfffe) - let s := add(shr(sub(4, u32), index), shr(64, shl(32, state))) // Bucket slot. - let o := shl(add(4, u32), and(index, shr(u32, 15))) // Bucket slot offset (bits). - let m := sub(shl(shl(u32, 16), 1), 1) // Value mask. - result := and(m, shr(o, sload(s))) - result := xor(index, mul(xor(index, sub(result, 1)), iszero(iszero(result)))) - } - } - - /// @dev Does a single Fisher-Yates shuffle step, increments the `numShuffled` in `$`, - /// and returns the next value in the shuffled range. - /// `randomness` can be taken from a good-enough source, or a higher quality source like VRF. - /// Reverts if there are no more values to shuffle, which includes the case if `$` is not initialized. - function next(LazyShuffler storage $, uint256 randomness) internal returns (uint256 chosen) { - /// @solidity memory-safe-assembly - assembly { - function _get(u32_, state_, i_) -> _value { - let s_ := add(shr(sub(4, u32_), i_), shr(64, shl(32, state_))) // Bucket slot. - let o_ := shl(add(4, u32_), and(i_, shr(u32_, 15))) // Bucket slot offset (bits). - let m_ := sub(shl(shl(u32_, 16), 1), 1) // Value mask. - _value := and(m_, shr(o_, sload(s_))) - _value := xor(i_, mul(xor(i_, sub(_value, 1)), iszero(iszero(_value)))) - } - function _set(u32_, state_, i_, value_) { - let s_ := add(shr(sub(4, u32_), i_), shr(64, shl(32, state_))) // Bucket slot. - let o_ := shl(add(4, u32_), and(i_, shr(u32_, 15))) // Bucket slot offset (bits). - let m_ := sub(shl(shl(u32_, 16), 1), 1) // Value mask. - let v_ := sload(s_) // Bucket slot value. - value_ := mul(iszero(eq(i_, value_)), add(value_, 1)) - sstore(s_, xor(v_, shl(o_, and(m_, xor(shr(o_, v_), value_))))) - } - let state := sload($.slot) // The packed value at `$`. - let shuffled := and(0xffffffff, state) // Number of elements shuffled. - let n := shr(224, state) // Length of `$`. - let remainder := sub(n, shuffled) // Number of elements left to shuffle. - if iszero(remainder) { - mstore(0x00, 0x51065f79) // `LazyShuffleFinished()`. - revert(0x1c, 0x04) - } - mstore(0x00, randomness) // (Re)hash the randomness so that we don't - mstore(0x20, shuffled) // need to expect guarantees on its distribution. - let index := add(mod(keccak256(0x00, 0x40), remainder), shuffled) - chosen := _get(gt(n, 0xfffe), state, index) - _set(gt(n, 0xfffe), state, index, _get(gt(n, 0xfffe), state, shuffled)) - _set(gt(n, 0xfffe), state, shuffled, chosen) - sstore($.slot, add(1, state)) // Increment the `numShuffled` by 1, and store it. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(int256[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(address[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - // As any address written to memory will have the upper 96 bits - // of the word zeroized (as per Solidity spec), we can directly - // compare these addresses as if they are whole uint256 words. - casted := a - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibRLP.sol b/grouperBot/lib/solady/src/utils/LibRLP.sol deleted file mode 100644 index 3e9f55e..0000000 --- a/grouperBot/lib/solady/src/utils/LibRLP.sol +++ /dev/null @@ -1,391 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for RLP encoding and CREATE address computation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibRLP.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibRLP.sol) -library LibRLP { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A pointer to a RLP item list in memory. - struct List { - // Do NOT modify the `_data` directly. - uint256 _data; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CREATE ADDRESS PREDICTION */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the address where a contract will be stored if deployed via - /// `deployer` with `nonce` using the `CREATE` opcode. - /// For the specification of the Recursive Length Prefix (RLP) - /// encoding scheme, please refer to p. 19 of the Ethereum Yellow Paper - /// (https://ethereum.github.io/yellowpaper/paper.pdf) - /// and the Ethereum Wiki (https://eth.wiki/fundamentals/rlp). - /// - /// Based on the EIP-161 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md) - /// specification, all contract accounts on the Ethereum mainnet are initiated with - /// `nonce = 1`. Thus, the first contract address created by another contract - /// is calculated with a non-zero nonce. - /// - /// The theoretical allowed limit, based on EIP-2681 - /// (https://eips.ethereum.org/EIPS/eip-2681), for an account nonce is 2**64-2. - /// - /// Caution! This function will NOT check that the nonce is within the theoretical range. - /// This is for performance, as exceeding the range is extremely impractical. - /// It is the user's responsibility to ensure that the nonce is valid - /// (e.g. no dirty bits after packing / unpacking). - /// - /// This is equivalent to: - /// `address(uint160(uint256(keccak256(LibRLP.p(deployer).p(nonce).encode()))))`. - /// - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function computeAddress(address deployer, uint256 nonce) - internal - pure - returns (address deployed) - { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - // The integer zero is treated as an empty byte string, - // and as a result it only has a length prefix, 0x80, - // computed via `0x80 + 0`. - - // A one-byte integer in the [0x00, 0x7f] range uses its - // own value as a length prefix, - // there is no additional `0x80 + length` prefix that precedes it. - if iszero(gt(nonce, 0x7f)) { - mstore(0x00, deployer) - // Using `mstore8` instead of `or` naturally cleans - // any dirty upper bits of `deployer`. - mstore8(0x0b, 0x94) - mstore8(0x0a, 0xd6) - // `shl` 7 is equivalent to multiplying by 0x80. - mstore8(0x20, or(shl(7, iszero(nonce)), nonce)) - deployed := keccak256(0x0a, 0x17) - break - } - let i := 8 - // Just use a loop to generalize all the way with minimal bytecode size. - for {} shr(i, nonce) { i := add(i, 8) } {} - // `shr` 3 is equivalent to dividing by 8. - i := shr(3, i) - // Store in descending slot sequence to overlap the values correctly. - mstore(i, nonce) - mstore(0x00, shl(8, deployer)) - mstore8(0x1f, add(0x80, i)) - mstore8(0x0a, 0x94) - mstore8(0x09, add(0xd6, i)) - deployed := keccak256(0x09, add(0x17, i)) - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RLP ENCODING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: - // - addresses are treated like byte strings of length 20, agnostic of leading zero bytes. - // - uint256s are converted to byte strings, stripped of leading zero bytes, and encoded. - // - bools are converted to uint256s (`b ? 1 : 0`), then encoded with the uint256. - // - For bytes1 to bytes32, you must manually convert them to bytes memory - // with `abi.encodePacked(x)` before encoding. - - /// @dev Returns a new empty list. - function p() internal pure returns (List memory result) {} - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(uint256 x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(address x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(bool x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(bytes memory x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(List memory x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, uint256 x) internal pure returns (List memory result) { - result._data = x << 48; - _updateTail(list, result); - /// @solidity memory-safe-assembly - assembly { - // If `x` is too big, we cannot pack it inline with the node. - // We'll have to allocate a new slot for `x` and store the pointer to it in the node. - if shr(208, x) { - let m := mload(0x40) - mstore(m, x) - mstore(0x40, add(m, 0x20)) - mstore(result, shl(40, or(1, shl(8, m)))) - } - } - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, address x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(40, or(4, shl(8, x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, bool x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(48, iszero(iszero(x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, bytes memory x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(40, or(2, shl(8, x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, List memory x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(40, or(3, shl(8, x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Returns the RLP encoding of `list`. - function encode(List memory list) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function encodeUint(x_, o_) -> _o { - _o := add(o_, 1) - if iszero(gt(x_, 0x7f)) { - mstore8(o_, or(shl(7, iszero(x_)), x_)) // Copy `x_`. - leave - } - let r_ := shl(7, lt(0xffffffffffffffffffffffffffffffff, x_)) - r_ := or(r_, shl(6, lt(0xffffffffffffffff, shr(r_, x_)))) - r_ := or(r_, shl(5, lt(0xffffffff, shr(r_, x_)))) - r_ := or(r_, shl(4, lt(0xffff, shr(r_, x_)))) - r_ := or(shr(3, r_), lt(0xff, shr(r_, x_))) - mstore8(o_, add(r_, 0x81)) // Store the prefix. - mstore(0x00, x_) - mstore(_o, mload(xor(31, r_))) // Copy `x_`. - _o := add(add(1, r_), _o) - } - function encodeAddress(x_, o_) -> _o { - _o := add(o_, 0x15) - mstore(o_, shl(88, x_)) - mstore8(o_, 0x94) - } - function encodeBytes(x_, o_, c_) -> _o { - _o := add(o_, 1) - let n_ := mload(x_) - if iszero(gt(n_, 55)) { - let f_ := mload(add(0x20, x_)) - if iszero(and(eq(1, n_), lt(byte(0, f_), 0x80))) { - mstore8(o_, add(n_, c_)) // Store the prefix. - mstore(add(0x21, o_), mload(add(0x40, x_))) - mstore(_o, f_) - _o := add(n_, _o) - leave - } - mstore(o_, f_) // Copy `x_`. - leave - } - returndatacopy(returndatasize(), returndatasize(), shr(32, n_)) - let r_ := add(1, add(lt(0xff, n_), add(lt(0xffff, n_), lt(0xffffff, n_)))) - mstore(o_, shl(248, add(r_, add(c_, 55)))) // Store the prefix. - // Copy `x`. - let i_ := add(r_, _o) - _o := add(i_, n_) - for { let d_ := sub(add(0x20, x_), i_) } 1 {} { - mstore(i_, mload(add(d_, i_))) - i_ := add(i_, 0x20) - if iszero(lt(i_, _o)) { break } - } - mstore(o_, or(mload(o_), shl(sub(248, shl(3, r_)), n_))) // Store the prefix. - } - function encodeList(l_, o_) -> _o { - if iszero(mload(l_)) { - mstore8(o_, 0xc0) - _o := add(o_, 1) - leave - } - let j_ := add(o_, 0x20) - for { let h_ := l_ } 1 {} { - h_ := and(mload(h_), 0xffffffffff) - if iszero(h_) { break } - let t_ := byte(26, mload(h_)) - if iszero(gt(t_, 1)) { - if iszero(t_) { - j_ := encodeUint(shr(48, mload(h_)), j_) - continue - } - j_ := encodeUint(mload(shr(48, mload(h_))), j_) - continue - } - if eq(t_, 2) { - j_ := encodeBytes(shr(48, mload(h_)), j_, 0x80) - continue - } - if eq(t_, 3) { - j_ := encodeList(shr(48, mload(h_)), j_) - continue - } - j_ := encodeAddress(shr(48, mload(h_)), j_) - } - let n_ := sub(j_, add(o_, 0x20)) - if iszero(gt(n_, 55)) { - mstore8(o_, add(n_, 0xc0)) // Store the prefix. - mstore(add(0x01, o_), mload(add(0x20, o_))) - mstore(add(0x21, o_), mload(add(0x40, o_))) - _o := add(n_, add(0x01, o_)) - leave - } - mstore(o_, n_) - _o := encodeBytes(o_, o_, 0xc0) - } - result := mload(0x40) - let begin := add(result, 0x20) - let end := encodeList(list, begin) - mstore(result, sub(end, begin)) // Store the length of `result`. - mstore(end, 0) // Zeroize the slot after `result`. - mstore(0x40, add(end, 0x20)) // Allocate memory for `result`. - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(uint256 x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - result := mload(0x40) - if iszero(gt(x, 0x7f)) { - mstore(result, 1) // Store the length of `result`. - mstore(add(result, 0x20), shl(248, or(shl(7, iszero(x)), x))) // Copy `x`. - mstore(0x40, add(result, 0x40)) // Allocate memory for `result`. - break - } - let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := add(2, or(shr(3, r), lt(0xff, shr(r, x)))) - mstore(add(r, result), x) // Copy `x`. - mstore(add(result, 1), add(r, 0x7f)) // Store the prefix. - mstore(result, r) // Store the length of `result`. - mstore(add(r, add(result, 0x20)), 0) // Zeroize the slot after `result`. - mstore(0x40, add(result, 0x60)) // Allocate memory for `result`. - break - } - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(address x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 0x15) - let o := add(0x20, result) - mstore(o, shl(88, x)) - mstore8(o, 0x94) - mstore(0x40, add(0x20, o)) - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(bool x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 1) - mstore(add(0x20, result), shl(add(0xf8, mul(7, iszero(x))), 0x01)) - mstore(0x40, add(0x40, result)) - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(bytes memory x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := x - - for {} iszero(and(eq(1, mload(x)), lt(byte(0, mload(add(x, 0x20))), 0x80))) {} { - result := mload(0x40) - let n := mload(x) // Length of `x`. - if iszero(gt(n, 55)) { - mstore(0x40, add(result, 0x60)) - mstore(add(0x41, result), mload(add(0x40, x))) - mstore(add(0x21, result), mload(add(0x20, x))) - mstore(add(1, result), add(n, 0x80)) // Store the prefix. - mstore(result, add(1, n)) // Store the length of `result`. - mstore(add(add(result, 0x21), n), 0) // Zeroize the slot after `result`. - break - } - returndatacopy(returndatasize(), returndatasize(), shr(32, n)) - let r := add(2, add(lt(0xff, n), add(lt(0xffff, n), lt(0xffffff, n)))) - // Copy `x`. - let i := add(r, add(0x20, result)) - let end := add(i, n) - for { let d := sub(add(0x20, x), i) } 1 {} { - mstore(i, mload(add(d, i))) - i := add(i, 0x20) - if iszero(lt(i, end)) { break } - } - mstore(add(r, result), n) // Store the prefix. - mstore(add(1, result), add(r, 0xb6)) // Store the prefix. - mstore(result, add(r, n)) // Store the length of `result`. - mstore(end, 0) // Zeroize the slot after `result`. - mstore(0x40, add(end, 0x20)) // Allocate memory. - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Updates the tail in `list`. - function _updateTail(List memory list, List memory result) private pure { - /// @solidity memory-safe-assembly - assembly { - let v := or(shr(mload(list), result), mload(list)) - let tail := shr(40, v) - mstore(list, xor(shl(40, xor(tail, result)), v)) // Update the tail. - mstore(tail, or(mload(tail), result)) // Make the previous tail point to `result`. - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibSort.sol b/grouperBot/lib/solady/src/utils/LibSort.sol deleted file mode 100644 index 360bf80..0000000 --- a/grouperBot/lib/solady/src/utils/LibSort.sol +++ /dev/null @@ -1,942 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Optimized sorts and operations for sorted arrays. -/// @author Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibSort.sol) -library LibSort { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INSERTION SORT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // - Faster on small arrays (32 or lesser elements). - // - Faster on almost sorted arrays. - // - Smaller bytecode (about 300 bytes smaller than sort, which uses intro-quicksort). - // - May be suitable for view functions intended for off-chain querying. - - /// @dev Sorts the array in-place with insertion sort. - function insertionSort(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) // Length of `a`. - mstore(a, 0) // For insertion sort's inner loop to terminate. - let h := add(a, shl(5, n)) // High slot. - let w := not(0x1f) - for { let i := add(a, 0x20) } 1 {} { - i := add(i, 0x20) - if gt(i, h) { break } - let k := mload(i) // Key. - let j := add(i, w) // The slot before the current slot. - let v := mload(j) // The value of `j`. - if iszero(gt(v, k)) { continue } - for {} 1 {} { - mstore(add(j, 0x20), v) - j := add(j, w) // `sub(j, 0x20)`. - v := mload(j) - if iszero(gt(v, k)) { break } - } - mstore(add(j, 0x20), k) - } - mstore(a, n) // Restore the length of `a`. - } - } - - /// @dev Sorts the array in-place with insertion sort. - function insertionSort(int256[] memory a) internal pure { - _flipSign(a); - insertionSort(_toUints(a)); - _flipSign(a); - } - - /// @dev Sorts the array in-place with insertion sort. - function insertionSort(address[] memory a) internal pure { - insertionSort(_toUints(a)); - } - - /// @dev Sorts the array in-place with insertion sort. - function insertionSort(bytes32[] memory a) internal pure { - insertionSort(_toUints(a)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTRO-QUICKSORT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // - Faster on larger arrays (more than 32 elements). - // - Robust performance. - // - Larger bytecode. - - /// @dev Sorts the array in-place with intro-quicksort. - function sort(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - function swap(a_, b_) -> _a, _b { - _b := a_ - _a := b_ - } - function mswap(i_, j_) { - let t_ := mload(i_) - mstore(i_, mload(j_)) - mstore(j_, t_) - } - function sortInner(w_, l_, h_) { - // Do insertion sort if `h_ - l_ <= 0x20 * 12`. - // Threshold is fine-tuned via trial and error. - if iszero(gt(sub(h_, l_), 0x180)) { - // Hardcode sort the first 2 elements. - let i_ := add(l_, 0x20) - if iszero(lt(mload(l_), mload(i_))) { mswap(i_, l_) } - for {} 1 {} { - i_ := add(i_, 0x20) - if gt(i_, h_) { break } - let k_ := mload(i_) // Key. - let j_ := add(i_, w_) // The slot before the current slot. - let v_ := mload(j_) // The value of `j_`. - if iszero(gt(v_, k_)) { continue } - for {} 1 {} { - mstore(add(j_, 0x20), v_) - j_ := add(j_, w_) - v_ := mload(j_) - if iszero(gt(v_, k_)) { break } - } - mstore(add(j_, 0x20), k_) - } - leave - } - // Pivot slot is the average of `l_` and `h_`. - let p_ := add(shl(5, shr(6, add(l_, h_))), and(31, l_)) - // Median of 3 with sorting. - { - let e0_ := mload(l_) - let e1_ := mload(p_) - if iszero(lt(e0_, e1_)) { e0_, e1_ := swap(e0_, e1_) } - let e2_ := mload(h_) - if iszero(lt(e1_, e2_)) { - e1_, e2_ := swap(e1_, e2_) - if iszero(lt(e0_, e1_)) { e0_, e1_ := swap(e0_, e1_) } - } - mstore(h_, e2_) - mstore(p_, e1_) - mstore(l_, e0_) - } - // Hoare's partition. - { - // The value of the pivot slot. - let x_ := mload(p_) - p_ := h_ - for { let i_ := l_ } 1 {} { - for {} 1 {} { - i_ := add(0x20, i_) - if iszero(gt(x_, mload(i_))) { break } - } - let j_ := p_ - for {} 1 {} { - j_ := add(w_, j_) - if iszero(lt(x_, mload(j_))) { break } - } - p_ := j_ - if iszero(lt(i_, p_)) { break } - mswap(i_, p_) - } - } - if iszero(eq(add(p_, 0x20), h_)) { sortInner(w_, add(p_, 0x20), h_) } - if iszero(eq(p_, l_)) { sortInner(w_, l_, p_) } - } - - for { let n := mload(a) } iszero(lt(n, 2)) {} { - let w := not(0x1f) // `-0x20`. - let l := add(a, 0x20) // Low slot. - let h := add(a, shl(5, n)) // High slot. - let j := h - // While `mload(j - 0x20) <= mload(j): j -= 0x20`. - for {} iszero(gt(mload(add(w, j)), mload(j))) {} { j := add(w, j) } - // If the array is already sorted, break. - if iszero(gt(j, l)) { break } - // While `mload(j - 0x20) >= mload(j): j -= 0x20`. - for { j := h } iszero(lt(mload(add(w, j)), mload(j))) {} { j := add(w, j) } - // If the array is reversed sorted. - if iszero(gt(j, l)) { - for {} 1 {} { - let t := mload(l) - mstore(l, mload(h)) - mstore(h, t) - h := add(w, h) - l := add(l, 0x20) - if iszero(lt(l, h)) { break } - } - break - } - mstore(a, 0) // For insertion sort's inner loop to terminate. - sortInner(w, l, h) - mstore(a, n) // Restore the length of `a`. - break - } - } - } - - /// @dev Sorts the array in-place with intro-quicksort. - function sort(int256[] memory a) internal pure { - _flipSign(a); - sort(_toUints(a)); - _flipSign(a); - } - - /// @dev Sorts the array in-place with intro-quicksort. - function sort(address[] memory a) internal pure { - sort(_toUints(a)); - } - - /// @dev Sorts the array in-place with intro-quicksort. - function sort(bytes32[] memory a) internal pure { - sort(_toUints(a)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER USEFUL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // For performance, the `uniquifySorted` methods will not revert if the - // array is not sorted -- it will simply remove consecutive duplicate elements. - - /// @dev Removes duplicate elements from a ascendingly sorted memory array. - function uniquifySorted(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - // If the length of `a` is greater than 1. - if iszero(lt(mload(a), 2)) { - let x := add(a, 0x20) - let y := add(a, 0x40) - let end := add(a, shl(5, add(mload(a), 1))) - for {} 1 {} { - if iszero(eq(mload(x), mload(y))) { - x := add(x, 0x20) - mstore(x, mload(y)) - } - y := add(y, 0x20) - if eq(y, end) { break } - } - mstore(a, shr(5, sub(x, a))) - } - } - } - - /// @dev Removes duplicate elements from a ascendingly sorted memory array. - function uniquifySorted(int256[] memory a) internal pure { - uniquifySorted(_toUints(a)); - } - - /// @dev Removes duplicate elements from a ascendingly sorted memory array. - function uniquifySorted(address[] memory a) internal pure { - uniquifySorted(_toUints(a)); - } - - /// @dev Removes duplicate elements from a ascendingly sorted memory array. - function uniquifySorted(bytes32[] memory a) internal pure { - uniquifySorted(_toUints(a)); - } - - /// @dev Returns whether `a` contains `needle`, and the index of `needle`. - /// `index` precedence: equal to > nearest before > nearest after. - function searchSorted(uint256[] memory a, uint256 needle) - internal - pure - returns (bool found, uint256 index) - { - (found, index) = _searchSorted(a, needle, 0); - } - - /// @dev Returns whether `a` contains `needle`, and the index of `needle`. - /// `index` precedence: equal to > nearest before > nearest after. - function searchSorted(int256[] memory a, int256 needle) - internal - pure - returns (bool found, uint256 index) - { - (found, index) = _searchSorted(_toUints(a), uint256(needle), 1 << 255); - } - - /// @dev Returns whether `a` contains `needle`, and the index of `needle`. - /// `index` precedence: equal to > nearest before > nearest after. - function searchSorted(address[] memory a, address needle) - internal - pure - returns (bool found, uint256 index) - { - (found, index) = _searchSorted(_toUints(a), uint160(needle), 0); - } - - /// @dev Returns whether `a` contains `needle`, and the index of `needle`. - /// `index` precedence: equal to > nearest before > nearest after. - function searchSorted(bytes32[] memory a, bytes32 needle) - internal - pure - returns (bool found, uint256 index) - { - (found, index) = _searchSorted(_toUints(a), uint256(needle), 0); - } - - /// @dev Returns whether `a` contains `needle`. - function inSorted(uint256[] memory a, uint256 needle) internal pure returns (bool found) { - (found,) = searchSorted(a, needle); - } - - /// @dev Returns whether `a` contains `needle`. - function inSorted(int256[] memory a, int256 needle) internal pure returns (bool found) { - (found,) = searchSorted(a, needle); - } - - /// @dev Returns whether `a` contains `needle`. - function inSorted(address[] memory a, address needle) internal pure returns (bool found) { - (found,) = searchSorted(a, needle); - } - - /// @dev Returns whether `a` contains `needle`. - function inSorted(bytes32[] memory a, bytes32 needle) internal pure returns (bool found) { - (found,) = searchSorted(a, needle); - } - - /// @dev Reverses the array in-place. - function reverse(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(mload(a), 2)) { - let s := 0x20 - let w := not(0x1f) - let h := add(a, shl(5, mload(a))) - for { a := add(a, s) } 1 {} { - let t := mload(a) - mstore(a, mload(h)) - mstore(h, t) - h := add(h, w) - a := add(a, s) - if iszero(lt(a, h)) { break } - } - } - } - } - - /// @dev Reverses the array in-place. - function reverse(int256[] memory a) internal pure { - reverse(_toUints(a)); - } - - /// @dev Reverses the array in-place. - function reverse(address[] memory a) internal pure { - reverse(_toUints(a)); - } - - /// @dev Reverses the array in-place. - function reverse(bytes32[] memory a) internal pure { - reverse(_toUints(a)); - } - - /// @dev Returns a copy of the array. - function copy(uint256[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let end := add(add(result, 0x20), shl(5, mload(a))) - let o := result - for { let d := sub(a, result) } 1 {} { - mstore(o, mload(add(o, d))) - o := add(0x20, o) - if eq(o, end) { break } - } - mstore(0x40, o) - } - } - - /// @dev Returns a copy of the array. - function copy(int256[] memory a) internal pure returns (int256[] memory result) { - result = _toInts(copy(_toUints(a))); - } - - /// @dev Returns a copy of the array. - function copy(address[] memory a) internal pure returns (address[] memory result) { - result = _toAddresses(copy(_toUints(a))); - } - - /// @dev Returns a copy of the array. - function copy(bytes32[] memory a) internal pure returns (bytes32[] memory result) { - result = _toBytes32s(copy(_toUints(a))); - } - - /// @dev Returns whether the array is sorted in ascending order. - function isSorted(uint256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 {} { - let p := mload(a) - a := add(a, 0x20) - result := iszero(gt(p, mload(a))) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is sorted in ascending order. - function isSorted(int256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 {} { - let p := mload(a) - a := add(a, 0x20) - result := iszero(sgt(p, mload(a))) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is sorted in ascending order. - function isSorted(address[] memory a) internal pure returns (bool result) { - result = isSorted(_toUints(a)); - } - - /// @dev Returns whether the array is sorted in ascending order. - function isSorted(bytes32[] memory a) internal pure returns (bool result) { - result = isSorted(_toUints(a)); - } - - /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(uint256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 {} { - let p := mload(a) - a := add(a, 0x20) - result := lt(p, mload(a)) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(int256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if iszero(lt(mload(a), 2)) { - let end := add(a, shl(5, mload(a))) - for { a := add(a, 0x20) } 1 {} { - let p := mload(a) - a := add(a, 0x20) - result := slt(p, mload(a)) - if iszero(mul(result, xor(a, end))) { break } - } - } - } - } - - /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(address[] memory a) internal pure returns (bool result) { - result = isSortedAndUniquified(_toUints(a)); - } - - /// @dev Returns whether the array is strictly ascending (sorted and uniquified). - function isSortedAndUniquified(bytes32[] memory a) internal pure returns (bool result) { - result = isSortedAndUniquified(_toUints(a)); - } - - /// @dev Returns the sorted set difference of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(uint256[] memory a, uint256[] memory b) - internal - pure - returns (uint256[] memory c) - { - c = _difference(a, b, 0); - } - - /// @dev Returns the sorted set difference between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(int256[] memory a, int256[] memory b) - internal - pure - returns (int256[] memory c) - { - c = _toInts(_difference(_toUints(a), _toUints(b), 1 << 255)); - } - - /// @dev Returns the sorted set difference between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(address[] memory a, address[] memory b) - internal - pure - returns (address[] memory c) - { - c = _toAddresses(_difference(_toUints(a), _toUints(b), 0)); - } - - /// @dev Returns the sorted set difference between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function difference(bytes32[] memory a, bytes32[] memory b) - internal - pure - returns (bytes32[] memory c) - { - c = _toBytes32s(_difference(_toUints(a), _toUints(b), 0)); - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(uint256[] memory a, uint256[] memory b) - internal - pure - returns (uint256[] memory c) - { - c = _intersection(a, b, 0); - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(int256[] memory a, int256[] memory b) - internal - pure - returns (int256[] memory c) - { - c = _toInts(_intersection(_toUints(a), _toUints(b), 1 << 255)); - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(address[] memory a, address[] memory b) - internal - pure - returns (address[] memory c) - { - c = _toAddresses(_intersection(_toUints(a), _toUints(b), 0)); - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function intersection(bytes32[] memory a, bytes32[] memory b) - internal - pure - returns (bytes32[] memory c) - { - c = _toBytes32s(_intersection(_toUints(a), _toUints(b), 0)); - } - - /// @dev Returns the sorted set union of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(uint256[] memory a, uint256[] memory b) - internal - pure - returns (uint256[] memory c) - { - c = _union(a, b, 0); - } - - /// @dev Returns the sorted set union of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(int256[] memory a, int256[] memory b) - internal - pure - returns (int256[] memory c) - { - c = _toInts(_union(_toUints(a), _toUints(b), 1 << 255)); - } - - /// @dev Returns the sorted set union between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(address[] memory a, address[] memory b) - internal - pure - returns (address[] memory c) - { - c = _toAddresses(_union(_toUints(a), _toUints(b), 0)); - } - - /// @dev Returns the sorted set union between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function union(bytes32[] memory a, bytes32[] memory b) - internal - pure - returns (bytes32[] memory c) - { - c = _toBytes32s(_union(_toUints(a), _toUints(b), 0)); - } - - /// @dev Cleans the upper 96 bits of the addresses. - /// In case `a` is produced via assembly and might have dirty upper bits. - function clean(address[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let addressMask := shr(96, not(0)) - for { let end := add(a, shl(5, mload(a))) } iszero(eq(a, end)) {} { - a := add(a, 0x20) - mstore(a, and(mload(a), addressMask)) - } - } - } - - /// @dev Sorts and uniquifies `keys`. Updates `values` with the grouped sums by key. - function groupSum(uint256[] memory keys, uint256[] memory values) internal pure { - /// @solidity memory-safe-assembly - assembly { - function mswap(i_, j_) { - let t_ := mload(i_) - mstore(i_, mload(j_)) - mstore(j_, t_) - } - function sortInner(l_, h_, d_) { - let p_ := mload(l_) - let j_ := l_ - for { let i_ := add(l_, 0x20) } 1 {} { - if lt(mload(i_), p_) { - j_ := add(j_, 0x20) - mswap(i_, j_) - mswap(add(i_, d_), add(j_, d_)) - } - i_ := add(0x20, i_) - if iszero(lt(i_, h_)) { break } - } - mswap(l_, j_) - mswap(add(l_, d_), add(j_, d_)) - if iszero(gt(add(0x40, l_), j_)) { sortInner(l_, j_, d_) } - if iszero(gt(add(0x60, j_), h_)) { sortInner(add(j_, 0x20), h_, d_) } - } - let n := mload(values) - if iszero(eq(mload(keys), n)) { - mstore(0x00, 0x4e487b71) - mstore(0x20, 0x32) // Array out of bounds panic if the arrays lengths differ. - revert(0x1c, 0x24) - } - if iszero(lt(n, 2)) { - let d := sub(values, keys) - let x := add(keys, 0x20) - let end := add(x, shl(5, n)) - sortInner(x, end, d) - let s := mload(add(x, d)) - for { let y := add(keys, 0x40) } 1 {} { - if iszero(eq(mload(x), mload(y))) { - mstore(add(x, d), s) // Write sum. - s := 0 - x := add(x, 0x20) - mstore(x, mload(y)) - } - s := add(s, mload(add(y, d))) - if lt(s, mload(add(y, d))) { - mstore(0x00, 0x4e487b71) - mstore(0x20, 0x11) // Overflow panic if the addition overflows. - revert(0x1c, 0x24) - } - y := add(y, 0x20) - if eq(y, end) { break } - } - mstore(add(x, d), s) // Write sum. - mstore(keys, shr(5, sub(x, keys))) // Truncate. - mstore(values, mload(keys)) // Truncate. - } - } - } - - /// @dev Sorts and uniquifies `keys`. Updates `values` with the grouped sums by key. - function groupSum(address[] memory keys, uint256[] memory values) internal pure { - groupSum(_toUints(keys), values); - } - - /// @dev Sorts and uniquifies `keys`. Updates `values` with the grouped sums by key. - function groupSum(bytes32[] memory keys, uint256[] memory values) internal pure { - groupSum(_toUints(keys), values); - } - - /// @dev Sorts and uniquifies `keys`. Updates `values` with the grouped sums by key. - function groupSum(int256[] memory keys, uint256[] memory values) internal pure { - groupSum(_toUints(keys), values); - } - - /// @dev Returns if `a` has any duplicate. Does NOT mutate `a`. `O(n)`. - function hasDuplicate(uint256[] memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - function p(i_, x_) -> _y { - _y := or(shr(i_, x_), x_) - } - let n := mload(a) - if iszero(lt(n, 2)) { - let m := mload(0x40) // Use free memory temporarily for hashmap. - let w := not(0x1f) // `-0x20`. - let c := and(w, p(16, p(8, p(4, p(2, p(1, mul(0x30, n))))))) - calldatacopy(m, calldatasize(), add(0x20, c)) // Zeroize hashmap. - for { let i := add(a, shl(5, n)) } 1 {} { - // See LibPRNG for explanation of this formula. - let r := mulmod(mload(i), 0x100000000000000000000000000000051, not(0xbc)) - // Linear probing. - for {} 1 { r := add(0x20, r) } { - let o := add(m, and(r, c)) // Non-zero pointer into hashmap. - if iszero(mload(o)) { - mstore(o, i) // Store non-zero pointer into hashmap. - break - } - if eq(mload(mload(o)), mload(i)) { - result := 1 - i := a // To break the outer loop. - break - } - } - i := add(i, w) // Iterate `a` backwards. - if iszero(lt(a, i)) { break } - } - if shr(31, n) { invalid() } // Just in case. - } - } - } - - /// @dev Returns if `a` has any duplicate. Does NOT mutate `a`. `O(n)`. - function hasDuplicate(address[] memory a) internal pure returns (bool) { - return hasDuplicate(_toUints(a)); - } - - /// @dev Returns if `a` has any duplicate. Does NOT mutate `a`. `O(n)`. - function hasDuplicate(bytes32[] memory a) internal pure returns (bool) { - return hasDuplicate(_toUints(a)); - } - - /// @dev Returns if `a` has any duplicate. Does NOT mutate `a`. `O(n)`. - function hasDuplicate(int256[] memory a) internal pure returns (bool) { - return hasDuplicate(_toUints(a)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(int256[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(address[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - // As any address written to memory will have the upper 96 bits - // of the word zeroized (as per Solidity spec), we can directly - // compare these addresses as if they are whole uint256 words. - casted := a - } - } - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(bytes32[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an int array. - function _toInts(uint256[] memory a) private pure returns (int256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an address array. - function _toAddresses(uint256[] memory a) private pure returns (address[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an bytes32 array. - function _toBytes32s(uint256[] memory a) private pure returns (bytes32[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Converts an array of signed integers to unsigned - /// integers suitable for sorting or vice versa. - function _flipSign(int256[] memory a) private pure { - /// @solidity memory-safe-assembly - assembly { - let q := shl(255, 1) - for { let i := add(a, shl(5, mload(a))) } iszero(eq(a, i)) {} { - mstore(i, add(mload(i), q)) - i := sub(i, 0x20) - } - } - } - - /// @dev Returns whether `a` contains `needle`, and the index of `needle`. - /// `index` precedence: equal to > nearest before > nearest after. - function _searchSorted(uint256[] memory a, uint256 needle, uint256 signed) - private - pure - returns (bool found, uint256 index) - { - /// @solidity memory-safe-assembly - assembly { - let w := not(0) - let l := 1 - let h := mload(a) - let t := 0 - for { needle := add(signed, needle) } 1 {} { - index := shr(1, add(l, h)) - t := add(signed, mload(add(a, shl(5, index)))) - if or(gt(l, h), eq(t, needle)) { break } - // Decide whether to search the left or right half. - if iszero(gt(needle, t)) { - h := add(index, w) - continue - } - l := add(index, 1) - } - // `index` will be zero in the case of an empty array, - // or when the value is less than the smallest value in the array. - found := eq(t, needle) - t := iszero(iszero(index)) - index := mul(add(index, w), t) - found := and(found, t) - } - } - - /// @dev Returns the sorted set difference of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _difference(uint256[] memory a, uint256[] memory b, uint256 signed) - private - pure - returns (uint256[] memory c) - { - /// @solidity memory-safe-assembly - assembly { - let s := 0x20 - let aEnd := add(a, shl(5, mload(a))) - let bEnd := add(b, shl(5, mload(b))) - c := mload(0x40) // Set `c` to the free memory pointer. - a := add(a, s) - b := add(b, s) - let k := c - for {} iszero(or(gt(a, aEnd), gt(b, bEnd))) {} { - let u := mload(a) - let v := mload(b) - if iszero(xor(u, v)) { - a := add(a, s) - b := add(b, s) - continue - } - if iszero(lt(add(u, signed), add(v, signed))) { - b := add(b, s) - continue - } - k := add(k, s) - mstore(k, u) - a := add(a, s) - } - for {} iszero(gt(a, aEnd)) {} { - k := add(k, s) - mstore(k, mload(a)) - a := add(a, s) - } - mstore(c, shr(5, sub(k, c))) // Store the length of `c`. - mstore(0x40, add(k, s)) // Allocate the memory for `c`. - } - } - - /// @dev Returns the sorted set intersection between `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _intersection(uint256[] memory a, uint256[] memory b, uint256 signed) - private - pure - returns (uint256[] memory c) - { - /// @solidity memory-safe-assembly - assembly { - let s := 0x20 - let aEnd := add(a, shl(5, mload(a))) - let bEnd := add(b, shl(5, mload(b))) - c := mload(0x40) // Set `c` to the free memory pointer. - a := add(a, s) - b := add(b, s) - let k := c - for {} iszero(or(gt(a, aEnd), gt(b, bEnd))) {} { - let u := mload(a) - let v := mload(b) - if iszero(xor(u, v)) { - k := add(k, s) - mstore(k, u) - a := add(a, s) - b := add(b, s) - continue - } - if iszero(lt(add(u, signed), add(v, signed))) { - b := add(b, s) - continue - } - a := add(a, s) - } - mstore(c, shr(5, sub(k, c))) // Store the length of `c`. - mstore(0x40, add(k, s)) // Allocate the memory for `c`. - } - } - - /// @dev Returns the sorted set union of `a` and `b`. - /// Note: Behaviour is undefined if inputs are not sorted and uniquified. - function _union(uint256[] memory a, uint256[] memory b, uint256 signed) - private - pure - returns (uint256[] memory c) - { - /// @solidity memory-safe-assembly - assembly { - let s := 0x20 - let aEnd := add(a, shl(5, mload(a))) - let bEnd := add(b, shl(5, mload(b))) - c := mload(0x40) // Set `c` to the free memory pointer. - a := add(a, s) - b := add(b, s) - let k := c - for {} iszero(or(gt(a, aEnd), gt(b, bEnd))) {} { - let u := mload(a) - let v := mload(b) - if iszero(xor(u, v)) { - k := add(k, s) - mstore(k, u) - a := add(a, s) - b := add(b, s) - continue - } - if iszero(lt(add(u, signed), add(v, signed))) { - k := add(k, s) - mstore(k, v) - b := add(b, s) - continue - } - k := add(k, s) - mstore(k, u) - a := add(a, s) - } - for {} iszero(gt(a, aEnd)) {} { - k := add(k, s) - mstore(k, mload(a)) - a := add(a, s) - } - for {} iszero(gt(b, bEnd)) {} { - k := add(k, s) - mstore(k, mload(b)) - b := add(b, s) - } - mstore(c, shr(5, sub(k, c))) // Store the length of `c`. - mstore(0x40, add(k, s)) // Allocate the memory for `c`. - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibStorage.sol b/grouperBot/lib/solady/src/utils/LibStorage.sol deleted file mode 100644 index d3eabbb..0000000 --- a/grouperBot/lib/solady/src/utils/LibStorage.sol +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for basic storage operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibStorage.sol) -library LibStorage { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage slot seed for calculating a bumped storage slot. - /// `bytes4(keccak256("_BUMPED_STORAGE_REF_SLOT_SEED"))`. - uint256 private constant _BUMPED_STORAGE_REF_SLOT_SEED = 0xd4203f8b; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Generates a storage slot that can be invalidated. - struct Bump { - uint256 _current; - } - - /// @dev Pointer struct to a `uint256` in storage. - /// We have opted for a `uint256` as the inner type, - /// as it requires less casting to get / set specific bits. - struct Ref { - uint256 value; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the current storage slot pointed by the bump. - /// Use inline-assembly to cast the result to a desired custom data type storage pointer. - function slot(Bump storage b) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1f, sload(b.slot)) - mstore(0x04, _BUMPED_STORAGE_REF_SLOT_SEED) - mstore(0x00, b.slot) - result := keccak256(0x00, 0x3f) - } - } - - /// @dev Makes the bump point to a whole new storage slot. - function invalidate(Bump storage b) internal { - unchecked { - ++b._current; - } - } - - /// @dev Returns a bump at the storage slot. - function bump(bytes32 sSlot) internal pure returns (Bump storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } - - /// @dev Returns a bump at the storage slot. - function bump(uint256 sSlot) internal pure returns (Bump storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } - - /// @dev Returns a pointer to a `uint256` in storage. - function ref(bytes32 sSlot) internal pure returns (Ref storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } - - /// @dev Returns a pointer to a `uint256` in storage. - function ref(uint256 sSlot) internal pure returns (Ref storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibString.sol b/grouperBot/lib/solady/src/utils/LibString.sol deleted file mode 100644 index 3d40155..0000000 --- a/grouperBot/lib/solady/src/utils/LibString.sol +++ /dev/null @@ -1,977 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {LibBytes} from "./LibBytes.sol"; - -/// @notice Library for converting numbers into strings and other string operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) -/// -/// @dev Note: -/// For performance and bytecode compactness, most of the string operations are restricted to -/// byte strings (7-bit ASCII), except where otherwise specified. -/// Usage of byte string operations on charsets with runes spanning two or more bytes -/// can lead to undefined behavior. -library LibString { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Goated string storage struct that totally MOGs, no cap, fr. - /// Uses less gas and bytecode than Solidity's native string storage. It's meta af. - /// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight. - struct StringStorage { - bytes32 _spacer; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The length of the output is too small to contain all the hex digits. - error HexLengthInsufficient(); - - /// @dev The length of the string is more than 32 bytes. - error TooBigForSmallString(); - - /// @dev The input string must be a 7-bit ASCII. - error StringNot7BitASCII(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when the `search` is not found in the string. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'. - uint128 internal constant ALPHANUMERIC_7_BIT_ASCII = 0x7fffffe07fffffe03ff000000000000; - - /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'. - uint128 internal constant LETTERS_7_BIT_ASCII = 0x7fffffe07fffffe0000000000000000; - - /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyz'. - uint128 internal constant LOWERCASE_7_BIT_ASCII = 0x7fffffe000000000000000000000000; - - /// @dev Lookup for 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. - uint128 internal constant UPPERCASE_7_BIT_ASCII = 0x7fffffe0000000000000000; - - /// @dev Lookup for '0123456789'. - uint128 internal constant DIGITS_7_BIT_ASCII = 0x3ff000000000000; - - /// @dev Lookup for '0123456789abcdefABCDEF'. - uint128 internal constant HEXDIGITS_7_BIT_ASCII = 0x7e0000007e03ff000000000000; - - /// @dev Lookup for '01234567'. - uint128 internal constant OCTDIGITS_7_BIT_ASCII = 0xff000000000000; - - /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'. - uint128 internal constant PRINTABLE_7_BIT_ASCII = 0x7fffffffffffffffffffffff00003e00; - - /// @dev Lookup for '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'. - uint128 internal constant PUNCTUATION_7_BIT_ASCII = 0x78000001f8000001fc00fffe00000000; - - /// @dev Lookup for ' \t\n\r\x0b\x0c'. - uint128 internal constant WHITESPACE_7_BIT_ASCII = 0x100003e00; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRING STORAGE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the value of the string storage `$` to `s`. - function set(StringStorage storage $, string memory s) internal { - LibBytes.set(bytesStorage($), bytes(s)); - } - - /// @dev Sets the value of the string storage `$` to `s`. - function setCalldata(StringStorage storage $, string calldata s) internal { - LibBytes.setCalldata(bytesStorage($), bytes(s)); - } - - /// @dev Sets the value of the string storage `$` to the empty string. - function clear(StringStorage storage $) internal { - delete $._spacer; - } - - /// @dev Returns whether the value stored is `$` is the empty string "". - function isEmpty(StringStorage storage $) internal view returns (bool) { - return uint256($._spacer) & 0xff == uint256(0); - } - - /// @dev Returns the length of the value stored in `$`. - function length(StringStorage storage $) internal view returns (uint256) { - return LibBytes.length(bytesStorage($)); - } - - /// @dev Returns the value stored in `$`. - function get(StringStorage storage $) internal view returns (string memory) { - return string(LibBytes.get(bytesStorage($))); - } - - /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0. - function uint8At(StringStorage storage $, uint256 i) internal view returns (uint8) { - return LibBytes.uint8At(bytesStorage($), i); - } - - /// @dev Helper to cast `$` to a `BytesStorage`. - function bytesStorage(StringStorage storage $) - internal - pure - returns (LibBytes.BytesStorage storage casted) - { - /// @solidity memory-safe-assembly - assembly { - casted.slot := $.slot - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DECIMAL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the base 10 decimal representation of `value`. - function toString(uint256 value) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - // The maximum value of a uint256 contains 78 digits (1 byte per digit), but - // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. - // We will need 1 word for the trailing zeros padding, 1 word for the length, - // and 3 words for a maximum of 78 digits. - result := add(mload(0x40), 0x80) - mstore(0x40, add(result, 0x20)) // Allocate memory. - mstore(result, 0) // Zeroize the slot after the string. - - let end := result // Cache the end of the memory to calculate the length later. - let w := not(0) // Tsk. - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for { let temp := value } 1 {} { - result := add(result, w) // `sub(result, 1)`. - // Store the character to the pointer. - // The ASCII index of the '0' character is 48. - mstore8(result, add(48, mod(temp, 10))) - temp := div(temp, 10) // Keep dividing `temp` until zero. - if iszero(temp) { break } - } - let n := sub(end, result) - result := sub(result, 0x20) // Move the pointer 32 bytes back to make room for the length. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the base 10 decimal representation of `value`. - function toString(int256 value) internal pure returns (string memory result) { - if (value >= 0) return toString(uint256(value)); - unchecked { - result = toString(~uint256(value) + 1); - } - /// @solidity memory-safe-assembly - assembly { - // We still have some spare memory space on the left, - // as we have allocated 3 words (96 bytes) for up to 78 digits. - let n := mload(result) // Load the string length. - mstore(result, 0x2d) // Store the '-' character. - result := sub(result, 1) // Move back the string pointer by a byte. - mstore(result, add(n, 1)) // Update the string length. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HEXADECIMAL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the hexadecimal representation of `value`, - /// left-padded to an input length of `byteCount` bytes. - /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, - /// giving a total length of `byteCount * 2 + 2` bytes. - /// Reverts if `byteCount` is too small for the output to contain all the digits. - function toHexString(uint256 value, uint256 byteCount) - internal - pure - returns (string memory result) - { - result = toHexStringNoPrefix(value, byteCount); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`, - /// left-padded to an input length of `byteCount` bytes. - /// The output is not prefixed with "0x" and is encoded using 2 hexadecimal digits per byte, - /// giving a total length of `byteCount * 2` bytes. - /// Reverts if `byteCount` is too small for the output to contain all the digits. - function toHexStringNoPrefix(uint256 value, uint256 byteCount) - internal - pure - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - // We need 0x20 bytes for the trailing zeros padding, `byteCount * 2` bytes - // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length. - // We add 0x20 to the total and round down to a multiple of 0x20. - // (0x20 + 0x20 + 0x02 + 0x20) = 0x62. - result := add(mload(0x40), and(add(shl(1, byteCount), 0x42), not(0x1f))) - mstore(0x40, add(result, 0x20)) // Allocate memory. - mstore(result, 0) // Zeroize the slot after the string. - - let end := result // Cache the end to calculate the length later. - // Store "0123456789abcdef" in scratch space. - mstore(0x0f, 0x30313233343536373839616263646566) - - let start := sub(result, add(byteCount, byteCount)) - let w := not(1) // Tsk. - let temp := value - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for {} 1 {} { - result := add(result, w) // `sub(result, 2)`. - mstore8(add(result, 1), mload(and(temp, 15))) - mstore8(result, mload(and(shr(4, temp), 15))) - temp := shr(8, temp) - if iszero(xor(result, start)) { break } - } - if temp { - mstore(0x00, 0x2194895a) // `HexLengthInsufficient()`. - revert(0x1c, 0x04) - } - let n := sub(end, result) - result := sub(result, 0x20) - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. - /// As address are 20 bytes long, the output will left-padded to have - /// a length of `20 * 2 + 2` bytes. - function toHexString(uint256 value) internal pure returns (string memory result) { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x". - /// The output excludes leading "0" from the `toHexString` output. - /// `0x00: "0x0", 0x01: "0x1", 0x12: "0x12", 0x123: "0x123"`. - function toMinimalHexString(uint256 value) internal pure returns (string memory result) { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present. - let n := add(mload(result), 2) // Compute the length. - mstore(add(result, o), 0x3078) // Store the "0x" prefix, accounting for leading zero. - result := sub(add(result, o), 2) // Move the pointer, accounting for leading zero. - mstore(result, sub(n, o)) // Store the length, accounting for leading zero. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output excludes leading "0" from the `toHexStringNoPrefix` output. - /// `0x00: "0", 0x01: "1", 0x12: "12", 0x123: "123"`. - function toMinimalHexStringNoPrefix(uint256 value) - internal - pure - returns (string memory result) - { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present. - let n := mload(result) // Get the length. - result := add(result, o) // Move the pointer, accounting for leading zero. - mstore(result, sub(n, o)) // Store the length, accounting for leading zero. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is encoded using 2 hexadecimal digits per byte. - /// As address are 20 bytes long, the output will left-padded to have - /// a length of `20 * 2` bytes. - function toHexStringNoPrefix(uint256 value) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, - // 0x02 bytes for the prefix, and 0x40 bytes for the digits. - // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0. - result := add(mload(0x40), 0x80) - mstore(0x40, add(result, 0x20)) // Allocate memory. - mstore(result, 0) // Zeroize the slot after the string. - - let end := result // Cache the end to calculate the length later. - mstore(0x0f, 0x30313233343536373839616263646566) // Store the "0123456789abcdef" lookup. - - let w := not(1) // Tsk. - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for { let temp := value } 1 {} { - result := add(result, w) // `sub(result, 2)`. - mstore8(add(result, 1), mload(and(temp, 15))) - mstore8(result, mload(and(shr(4, temp), 15))) - temp := shr(8, temp) - if iszero(temp) { break } - } - let n := sub(end, result) - result := sub(result, 0x20) - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte, - /// and the alphabets are capitalized conditionally according to - /// https://eips.ethereum.org/EIPS/eip-55 - function toHexStringChecksummed(address value) internal pure returns (string memory result) { - result = toHexString(value); - /// @solidity memory-safe-assembly - assembly { - let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...` - let o := add(result, 0x22) - let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... ` - let t := shl(240, 136) // `0b10001000 << 240` - for { let i := 0 } 1 {} { - mstore(add(i, i), mul(t, byte(i, hashed))) - i := add(i, 1) - if eq(i, 20) { break } - } - mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask))))) - o := add(o, 0x20) - mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask))))) - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. - function toHexString(address value) internal pure returns (string memory result) { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is encoded using 2 hexadecimal digits per byte. - function toHexStringNoPrefix(address value) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - // Allocate memory. - // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, - // 0x02 bytes for the prefix, and 0x28 bytes for the digits. - // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80. - mstore(0x40, add(result, 0x80)) - mstore(0x0f, 0x30313233343536373839616263646566) // Store the "0123456789abcdef" lookup. - - result := add(result, 2) - mstore(result, 40) // Store the length. - let o := add(result, 0x20) - mstore(add(o, 40), 0) // Zeroize the slot after the string. - value := shl(96, value) - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for { let i := 0 } 1 {} { - let p := add(o, add(i, i)) - let temp := byte(i, value) - mstore8(add(p, 1), mload(and(temp, 15))) - mstore8(p, mload(shr(4, temp))) - i := add(i, 1) - if eq(i, 20) { break } - } - } - } - - /// @dev Returns the hex encoded string from the raw bytes. - /// The output is encoded using 2 hexadecimal digits per byte. - function toHexString(bytes memory raw) internal pure returns (string memory result) { - result = toHexStringNoPrefix(raw); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hex encoded string from the raw bytes. - /// The output is encoded using 2 hexadecimal digits per byte. - function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(raw) - result := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix. - mstore(result, add(n, n)) // Store the length of the output. - - mstore(0x0f, 0x30313233343536373839616263646566) // Store the "0123456789abcdef" lookup. - let o := add(result, 0x20) - let end := add(raw, n) - for {} iszero(eq(raw, end)) {} { - raw := add(raw, 1) - mstore8(add(o, 1), mload(and(mload(raw), 15))) - mstore8(o, mload(and(shr(4, mload(raw)), 15))) - o := add(o, 2) - } - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RUNE STRING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of UTF characters in the string. - function runeCount(string memory s) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - if mload(s) { - mstore(0x00, div(not(0), 255)) - mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506) - let o := add(s, 0x20) - let end := add(o, mload(s)) - for { result := 1 } 1 { result := add(result, 1) } { - o := add(o, byte(0, mload(shr(250, mload(o))))) - if iszero(lt(o, end)) { break } - } - } - } - } - - /// @dev Returns if this string is a 7-bit ASCII string. - /// (i.e. all characters codes are in [0..127]) - function is7BitASCII(string memory s) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - let mask := shl(7, div(not(0), 255)) - let n := mload(s) - if n { - let o := add(s, 0x20) - let end := add(o, n) - let last := mload(end) - mstore(end, 0) - for {} 1 {} { - if and(mask, mload(o)) { - result := 0 - break - } - o := add(o, 0x20) - if iszero(lt(o, end)) { break } - } - mstore(end, last) - } - } - } - - /// @dev Returns if this string is a 7-bit ASCII string, - /// AND all characters are in the `allowed` lookup. - /// Note: If `s` is empty, returns true regardless of `allowed`. - function is7BitASCII(string memory s, uint128 allowed) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if mload(s) { - let allowed_ := shr(128, shl(128, allowed)) - let o := add(s, 0x20) - for { let end := add(o, mload(s)) } 1 {} { - result := and(result, shr(byte(0, mload(o)), allowed_)) - o := add(o, 1) - if iszero(and(result, lt(o, end))) { break } - } - } - } - } - - /// @dev Converts the bytes in the 7-bit ASCII string `s` to - /// an allowed lookup for use in `is7BitASCII(s, allowed)`. - /// To save runtime gas, you can cache the result in an immutable variable. - function to7BitASCIIAllowedLookup(string memory s) internal pure returns (uint128 result) { - /// @solidity memory-safe-assembly - assembly { - if mload(s) { - let o := add(s, 0x20) - for { let end := add(o, mload(s)) } 1 {} { - result := or(result, shl(byte(0, mload(o)), 1)) - o := add(o, 1) - if iszero(lt(o, end)) { break } - } - if shr(128, result) { - mstore(0x00, 0xc9807e0d) // `StringNot7BitASCII()`. - revert(0x1c, 0x04) - } - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTE STRING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // For performance and bytecode compactness, byte string operations are restricted - // to 7-bit ASCII strings. All offsets are byte offsets, not UTF character offsets. - // Usage of byte string operations on charsets with runes spanning two or more bytes - // can lead to undefined behavior. - - /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`. - function replace(string memory subject, string memory needle, string memory replacement) - internal - pure - returns (string memory) - { - return string(LibBytes.replace(bytes(subject), bytes(needle), bytes(replacement))); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(string memory subject, string memory needle, uint256 from) - internal - pure - returns (uint256) - { - return LibBytes.indexOf(bytes(subject), bytes(needle), from); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(string memory subject, string memory needle) internal pure returns (uint256) { - return LibBytes.indexOf(bytes(subject), bytes(needle), 0); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(string memory subject, string memory needle, uint256 from) - internal - pure - returns (uint256) - { - return LibBytes.lastIndexOf(bytes(subject), bytes(needle), from); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(string memory subject, string memory needle) - internal - pure - returns (uint256) - { - return LibBytes.lastIndexOf(bytes(subject), bytes(needle), type(uint256).max); - } - - /// @dev Returns true if `needle` is found in `subject`, false otherwise. - function contains(string memory subject, string memory needle) internal pure returns (bool) { - return LibBytes.contains(bytes(subject), bytes(needle)); - } - - /// @dev Returns whether `subject` starts with `needle`. - function startsWith(string memory subject, string memory needle) internal pure returns (bool) { - return LibBytes.startsWith(bytes(subject), bytes(needle)); - } - - /// @dev Returns whether `subject` ends with `needle`. - function endsWith(string memory subject, string memory needle) internal pure returns (bool) { - return LibBytes.endsWith(bytes(subject), bytes(needle)); - } - - /// @dev Returns `subject` repeated `times`. - function repeat(string memory subject, uint256 times) internal pure returns (string memory) { - return string(LibBytes.repeat(bytes(subject), times)); - } - - /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function slice(string memory subject, uint256 start, uint256 end) - internal - pure - returns (string memory) - { - return string(LibBytes.slice(bytes(subject), start, end)); - } - - /// @dev Returns a copy of `subject` sliced from `start` to the end of the string. - /// `start` is a byte offset. - function slice(string memory subject, uint256 start) internal pure returns (string memory) { - return string(LibBytes.slice(bytes(subject), start, type(uint256).max)); - } - - /// @dev Returns all the indices of `needle` in `subject`. - /// The indices are byte offsets. - function indicesOf(string memory subject, string memory needle) - internal - pure - returns (uint256[] memory) - { - return LibBytes.indicesOf(bytes(subject), bytes(needle)); - } - - /// @dev Returns an arrays of strings based on the `delimiter` inside of the `subject` string. - function split(string memory subject, string memory delimiter) - internal - pure - returns (string[] memory result) - { - bytes[] memory a = LibBytes.split(bytes(subject), bytes(delimiter)); - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Returns a concatenated string of `a` and `b`. - /// Cheaper than `string.concat()` and does not de-align the free memory pointer. - function concat(string memory a, string memory b) internal pure returns (string memory) { - return string(LibBytes.concat(bytes(a), bytes(b))); - } - - /// @dev Returns a copy of the string in either lowercase or UPPERCASE. - /// WARNING! This function is only compatible with 7-bit ASCII strings. - function toCase(string memory subject, bool toUpper) - internal - pure - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(subject) - if n { - result := mload(0x40) - let o := add(result, 0x20) - let d := sub(subject, result) - let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff) - for { let end := add(o, n) } 1 {} { - let b := byte(0, mload(add(d, o))) - mstore8(o, xor(and(shr(b, flags), 0x20), b)) - o := add(o, 1) - if eq(o, end) { break } - } - mstore(result, n) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - } - - /// @dev Returns a string from a small bytes32 string. - /// `s` must be null-terminated, or behavior will be undefined. - function fromSmallString(bytes32 s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let n := 0 - for {} byte(n, s) { n := add(n, 1) } {} // Scan for '\0'. - mstore(result, n) // Store the length. - let o := add(result, 0x20) - mstore(o, s) // Store the bytes of the string. - mstore(add(o, n), 0) // Zeroize the slot after the string. - mstore(0x40, add(result, 0x40)) // Allocate memory. - } - } - - /// @dev Returns the small string, with all bytes after the first null byte zeroized. - function normalizeSmallString(bytes32 s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - for {} byte(result, s) { result := add(result, 1) } {} // Scan for '\0'. - mstore(0x00, s) - mstore(result, 0x00) - result := mload(0x00) - } - } - - /// @dev Returns the string as a normalized null-terminated small string. - function toSmallString(string memory s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(s) - if iszero(lt(result, 33)) { - mstore(0x00, 0xec92f9a3) // `TooBigForSmallString()`. - revert(0x1c, 0x04) - } - result := shl(shl(3, sub(32, result)), mload(add(s, result))) - } - } - - /// @dev Returns a lowercased copy of the string. - /// WARNING! This function is only compatible with 7-bit ASCII strings. - function lower(string memory subject) internal pure returns (string memory result) { - result = toCase(subject, false); - } - - /// @dev Returns an UPPERCASED copy of the string. - /// WARNING! This function is only compatible with 7-bit ASCII strings. - function upper(string memory subject) internal pure returns (string memory result) { - result = toCase(subject, true); - } - - /// @dev Escapes the string to be used within HTML tags. - function escapeHTML(string memory s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let end := add(s, mload(s)) - let o := add(result, 0x20) - // Store the bytes of the packed offsets and strides into the scratch space. - // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6. - mstore(0x1f, 0x900094) - mstore(0x08, 0xc0000000a6ab) - // Store ""&'<>" into the scratch space. - mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b)) - for {} iszero(eq(s, end)) {} { - s := add(s, 1) - let c := and(mload(s), 0xff) - // Not in `["\"","'","&","<",">"]`. - if iszero(and(shl(c, 1), 0x500000c400000000)) { - mstore8(o, c) - o := add(o, 1) - continue - } - let t := shr(248, mload(c)) - mstore(o, mload(and(t, 0x1f))) - o := add(o, shr(5, t)) - } - mstore(o, 0) // Zeroize the slot after the string. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /// @dev Escapes the string to be used within double-quotes in a JSON. - /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes. - function escapeJSON(string memory s, bool addDoubleQuotes) - internal - pure - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let o := add(result, 0x20) - if addDoubleQuotes { - mstore8(o, 34) - o := add(1, o) - } - // Store "\\u0000" in scratch space. - // Store "0123456789abcdef" in scratch space. - // Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`. - // into the scratch space. - mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672) - // Bitmask for detecting `["\"","\\"]`. - let e := or(shl(0x22, 1), shl(0x5c, 1)) - for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} { - s := add(s, 1) - let c := and(mload(s), 0xff) - if iszero(lt(c, 0x20)) { - if iszero(and(shl(c, 1), e)) { - // Not in `["\"","\\"]`. - mstore8(o, c) - o := add(o, 1) - continue - } - mstore8(o, 0x5c) // "\\". - mstore8(add(o, 1), c) - o := add(o, 2) - continue - } - if iszero(and(shl(c, 1), 0x3700)) { - // Not in `["\b","\t","\n","\f","\d"]`. - mstore8(0x1d, mload(shr(4, c))) // Hex value. - mstore8(0x1e, mload(and(c, 15))) // Hex value. - mstore(o, mload(0x19)) // "\\u00XX". - o := add(o, 6) - continue - } - mstore8(o, 0x5c) // "\\". - mstore8(add(o, 1), mload(add(c, 8))) - o := add(o, 2) - } - if addDoubleQuotes { - mstore8(o, 34) - o := add(1, o) - } - mstore(o, 0) // Zeroize the slot after the string. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /// @dev Escapes the string to be used within double-quotes in a JSON. - function escapeJSON(string memory s) internal pure returns (string memory result) { - result = escapeJSON(s, false); - } - - /// @dev Encodes `s` so that it can be safely used in a URI, - /// just like `encodeURIComponent` in JavaScript. - /// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent - /// See: https://datatracker.ietf.org/doc/html/rfc2396 - /// See: https://datatracker.ietf.org/doc/html/rfc3986 - function encodeURIComponent(string memory s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - // Store "0123456789ABCDEF" in scratch space. - // Uppercased to be consistent with JavaScript's implementation. - mstore(0x0f, 0x30313233343536373839414243444546) - let o := add(result, 0x20) - for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} { - s := add(s, 1) - let c := and(mload(s), 0xff) - // If not in `[0-9A-Z-a-z-_.!~*'()]`. - if iszero(and(1, shr(c, 0x47fffffe87fffffe03ff678200000000))) { - mstore8(o, 0x25) // '%'. - mstore8(add(o, 1), mload(and(shr(4, c), 15))) - mstore8(add(o, 2), mload(and(c, 15))) - o := add(o, 3) - continue - } - mstore8(o, c) - o := add(o, 1) - } - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /// @dev Returns whether `a` equals `b`. - function eq(string memory a, string memory b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b))) - } - } - - /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small string. - function eqs(string memory a, bytes32 b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - // These should be evaluated on compile time, as far as possible. - let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`. - let x := not(or(m, or(b, add(m, and(b, m))))) - let r := shl(7, iszero(iszero(shr(128, x)))) - r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x)))))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // forgefmt: disable-next-item - result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))), - xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20))))) - } - } - - /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`. - /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1. - function cmp(string memory a, string memory b) internal pure returns (int256) { - return LibBytes.cmp(bytes(a), bytes(b)); - } - - /// @dev Packs a single string with its length into a single word. - /// Returns `bytes32(0)` if the length is zero or greater than 31. - function packOne(string memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - // We don't need to zero right pad the string, - // since this is our own custom non-standard packing scheme. - result := - mul( - // Load the length and the bytes. - mload(add(a, 0x1f)), - // `length != 0 && length < 32`. Abuses underflow. - // Assumes that the length is valid and within the block gas limit. - lt(sub(mload(a), 1), 0x1f) - ) - } - } - - /// @dev Unpacks a string packed using {packOne}. - /// Returns the empty string if `packed` is `bytes32(0)`. - /// If `packed` is not an output of {packOne}, the output behavior is undefined. - function unpackOne(bytes32 packed) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) // Grab the free memory pointer. - mstore(0x40, add(result, 0x40)) // Allocate 2 words (1 for the length, 1 for the bytes). - mstore(result, 0) // Zeroize the length slot. - mstore(add(result, 0x1f), packed) // Store the length and bytes. - mstore(add(add(result, 0x20), mload(result)), 0) // Right pad with zeroes. - } - } - - /// @dev Packs two strings with their lengths into a single word. - /// Returns `bytes32(0)` if combined length is zero or greater than 30. - function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let aLen := mload(a) - // We don't need to zero right pad the strings, - // since this is our own custom non-standard packing scheme. - result := - mul( - or( // Load the length and the bytes of `a` and `b`. - shl(shl(3, sub(0x1f, aLen)), mload(add(a, aLen))), mload(sub(add(b, 0x1e), aLen))), - // `totalLen != 0 && totalLen < 31`. Abuses underflow. - // Assumes that the lengths are valid and within the block gas limit. - lt(sub(add(aLen, mload(b)), 1), 0x1e) - ) - } - } - - /// @dev Unpacks strings packed using {packTwo}. - /// Returns the empty strings if `packed` is `bytes32(0)`. - /// If `packed` is not an output of {packTwo}, the output behavior is undefined. - function unpackTwo(bytes32 packed) - internal - pure - returns (string memory resultA, string memory resultB) - { - /// @solidity memory-safe-assembly - assembly { - resultA := mload(0x40) // Grab the free memory pointer. - resultB := add(resultA, 0x40) - // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words. - mstore(0x40, add(resultB, 0x40)) - // Zeroize the length slots. - mstore(resultA, 0) - mstore(resultB, 0) - // Store the lengths and bytes. - mstore(add(resultA, 0x1f), packed) - mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA)))) - // Right pad with zeroes. - mstore(add(add(resultA, 0x20), mload(resultA)), 0) - mstore(add(add(resultB, 0x20), mload(resultB)), 0) - } - } - - /// @dev Directly returns `a` without copying. - function directReturn(string memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - // Assumes that the string does not start from the scratch space. - let retStart := sub(a, 0x20) - let retUnpaddedSize := add(mload(a), 0x40) - // Right pad with zeroes. Just in case the string is produced - // by a method that doesn't zero right pad. - mstore(add(retStart, retUnpaddedSize), 0) - mstore(retStart, 0x20) // Store the return offset. - // End the transaction, returning the string. - return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize))) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibTransient.sol b/grouperBot/lib/solady/src/utils/LibTransient.sol deleted file mode 100644 index b7151a4..0000000 --- a/grouperBot/lib/solady/src/utils/LibTransient.sol +++ /dev/null @@ -1,963 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for transient storage operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibTransient.sol) -/// @author Modified from Transient Goodies by Philogy (https://github.com/Philogy/transient-goodies/blob/main/src/TransientBytesLib.sol) -/// -/// @dev Note: The functions postfixed with `Compat` will only use transient storage on L1. -/// L2s are super cheap anyway. -/// For best safety, always clear the storage after use. -library LibTransient { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Pointer struct to a `uint256` in transient storage. - struct TUint256 { - uint256 _spacer; - } - - /// @dev Pointer struct to a `int256` in transient storage. - struct TInt256 { - uint256 _spacer; - } - - /// @dev Pointer struct to a `bytes32` in transient storage. - struct TBytes32 { - uint256 _spacer; - } - - /// @dev Pointer struct to a `address` in transient storage. - struct TAddress { - uint256 _spacer; - } - - /// @dev Pointer struct to a `bool` in transient storage. - struct TBool { - uint256 _spacer; - } - - /// @dev Pointer struct to a `bytes` in transient storage. - struct TBytes { - uint256 _spacer; - } - - /// @dev Pointer struct to a stack pointer generator in transient storage. - /// This stack does not directly take in values. Instead, it generates pointers - /// that can be casted to any of the other transient storage pointer struct. - struct TStack { - uint256 _spacer; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The transient stack is empty. - error StackIsEmpty(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage slot seed for converting a transient slot to a storage slot. - /// `bytes4(keccak256("_LIB_TRANSIENT_COMPAT_SLOT_SEED"))`. - uint256 private constant _LIB_TRANSIENT_COMPAT_SLOT_SEED = 0x5a0b45f2; - - /// @dev Multiplier to stack base slot, so that in the case where two stacks - /// share consecutive base slots, their pointers will likely not overlap. A prime. - uint256 private constant _STACK_BASE_SALT = 0x9e076501211e1371b; - - /// @dev The canonical address of the transient registry. - /// See: https://gist.github.com/Vectorized/4ab665d7a234ef5aaaff2e5091ec261f - address internal constant REGISTRY = 0x000000000000297f64C7F8d9595e43257908F170; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UINT256 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `uint256` in transient storage. - function tUint256(bytes32 tSlot) internal pure returns (TUint256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `uint256` in transient storage. - function tUint256(uint256 tSlot) internal pure returns (TUint256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TUint256 storage ptr) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TUint256 storage ptr) internal view returns (uint256 result) { - result = block.chainid == 1 ? get(ptr) : _compat(ptr)._spacer; - } - - /// @dev Sets the value at transient `ptr`. - function set(TUint256 storage ptr, uint256 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, value) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TUint256 storage ptr, uint256 value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = value; - } - - /// @dev Clears the value at transient `ptr`. - function clear(TUint256 storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TUint256 storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /// @dev Increments the value at transient `ptr` by 1. - function inc(TUint256 storage ptr) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by 1. - function incCompat(TUint256 storage ptr) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function inc(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) + delta); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incCompat(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + delta); - } - - /// @dev Decrements the value at transient `ptr` by 1. - function dec(TUint256 storage ptr) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decCompat(TUint256 storage ptr) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function dec(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) - delta); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decCompat(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - delta); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incSigned(TUint256 storage ptr, int256 delta) internal returns (uint256 newValue) { - /// @solidity memory-safe-assembly - assembly { - let currentValue := tload(ptr.slot) - newValue := add(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), slt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - tstore(ptr.slot, newValue) - } - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incSignedCompat(TUint256 storage ptr, int256 delta) - internal - returns (uint256 newValue) - { - if (block.chainid == 1) return incSigned(ptr, delta); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - let currentValue := sload(ptr.slot) - newValue := add(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), slt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - sstore(ptr.slot, newValue) - } - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decSigned(TUint256 storage ptr, int256 delta) internal returns (uint256 newValue) { - /// @solidity memory-safe-assembly - assembly { - let currentValue := tload(ptr.slot) - newValue := sub(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), sgt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - tstore(ptr.slot, newValue) - } - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decSignedCompat(TUint256 storage ptr, int256 delta) - internal - returns (uint256 newValue) - { - if (block.chainid == 1) return decSigned(ptr, delta); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - let currentValue := sload(ptr.slot) - newValue := sub(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), sgt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - sstore(ptr.slot, newValue) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INT256 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `int256` in transient storage. - function tInt256(bytes32 tSlot) internal pure returns (TInt256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `int256` in transient storage. - function tInt256(uint256 tSlot) internal pure returns (TInt256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TInt256 storage ptr) internal view returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TInt256 storage ptr) internal view returns (int256 result) { - result = block.chainid == 1 ? get(ptr) : int256(_compat(ptr)._spacer); - } - - /// @dev Sets the value at transient `ptr`. - function set(TInt256 storage ptr, int256 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, value) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TInt256 storage ptr, int256 value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = uint256(value); - } - - /// @dev Clears the value at transient `ptr`. - function clear(TInt256 storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TInt256 storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /// @dev Increments the value at transient `ptr` by 1. - function inc(TInt256 storage ptr) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by 1. - function incCompat(TInt256 storage ptr) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function inc(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) + delta); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incCompat(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + delta); - } - - /// @dev Decrements the value at transient `ptr` by 1. - function dec(TInt256 storage ptr) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by 1. - function decCompat(TInt256 storage ptr) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function dec(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) - delta); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decCompat(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - delta); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTES32 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `bytes32` in transient storage. - function tBytes32(bytes32 tSlot) internal pure returns (TBytes32 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `bytes32` in transient storage. - function tBytes32(uint256 tSlot) internal pure returns (TBytes32 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TBytes32 storage ptr) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TBytes32 storage ptr) internal view returns (bytes32 result) { - result = block.chainid == 1 ? get(ptr) : bytes32(_compat(ptr)._spacer); - } - - /// @dev Sets the value at transient `ptr`. - function set(TBytes32 storage ptr, bytes32 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, value) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TBytes32 storage ptr, bytes32 value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = uint256(value); - } - - /// @dev Clears the value at transient `ptr`. - function clear(TBytes32 storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TBytes32 storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ADDRESS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `address` in transient storage. - function tAddress(bytes32 tSlot) internal pure returns (TAddress storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `address` in transient storage. - function tAddress(uint256 tSlot) internal pure returns (TAddress storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TAddress storage ptr) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TAddress storage ptr) internal view returns (address result) { - result = block.chainid == 1 ? get(ptr) : address(uint160(_compat(ptr)._spacer)); - } - - /// @dev Sets the value at transient `ptr`. - function set(TAddress storage ptr, address value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, shr(96, shl(96, value))) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TAddress storage ptr, address value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = uint160(value); - } - - /// @dev Clears the value at transient `ptr`. - function clear(TAddress storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TAddress storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BOOL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `bool` in transient storage. - function tBool(bytes32 tSlot) internal pure returns (TBool storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `bool` in transient storage. - function tBool(uint256 tSlot) internal pure returns (TBool storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TBool storage ptr) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TBool storage ptr) internal view returns (bool result) { - result = block.chainid == 1 ? get(ptr) : _compat(ptr)._spacer != 0; - } - - /// @dev Sets the value at transient `ptr`. - function set(TBool storage ptr, bool value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, iszero(iszero(value))) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TBool storage ptr, bool value) internal { - if (block.chainid == 1) return set(ptr, value); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - sstore(ptr.slot, iszero(iszero(value))) - } - } - - /// @dev Clears the value at transient `ptr`. - function clear(TBool storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TBool storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTES OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `bytes` in transient storage. - function tBytes(bytes32 tSlot) internal pure returns (TBytes storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `bytes` in transient storage. - function tBytes(uint256 tSlot) internal pure returns (TBytes storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the length of the bytes stored at transient `ptr`. - function length(TBytes storage ptr) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(224, tload(ptr.slot)) - } - } - - /// @dev Returns the length of the bytes stored at transient `ptr`. - function lengthCompat(TBytes storage ptr) internal view returns (uint256 result) { - if (block.chainid == 1) return length(ptr); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - result := shr(224, sload(ptr.slot)) - } - } - - /// @dev Returns the bytes stored at transient `ptr`. - function get(TBytes storage ptr) internal view returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 0x00) - mstore(add(result, 0x1c), tload(ptr.slot)) // Length and first `0x1c` bytes. - let n := mload(result) - let e := add(add(result, 0x20), n) - if iszero(lt(n, 0x1d)) { - mstore(0x00, ptr.slot) - let d := sub(keccak256(0x00, 0x20), result) - for { let o := add(result, 0x3c) } 1 {} { - mstore(o, tload(add(o, d))) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - mstore(e, 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, e)) // Allocate memory. - } - } - - /// @dev Returns the bytes stored at transient `ptr`. - function getCompat(TBytes storage ptr) internal view returns (bytes memory result) { - if (block.chainid == 1) return get(ptr); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 0x00) - mstore(add(result, 0x1c), sload(ptr.slot)) // Length and first `0x1c` bytes. - let n := mload(result) - let e := add(add(result, 0x20), n) - if iszero(lt(n, 0x1d)) { - mstore(0x00, ptr.slot) - let d := sub(keccak256(0x00, 0x20), result) - for { let o := add(result, 0x3c) } 1 {} { - mstore(o, sload(add(o, d))) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - mstore(e, 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, e)) // Allocate memory. - } - } - - /// @dev Sets the value at transient `ptr`. - function set(TBytes storage ptr, bytes memory value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, mload(add(value, 0x1c))) - if iszero(lt(mload(value), 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(add(value, 0x20), mload(value)) - let d := sub(keccak256(0x00, or(0x20, sub(0, shr(32, mload(value))))), value) - for { let o := add(value, 0x3c) } 1 {} { - tstore(add(o, d), mload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TBytes storage ptr, bytes memory value) internal { - if (block.chainid == 1) return set(ptr, value); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - sstore(ptr.slot, mload(add(value, 0x1c))) - if iszero(lt(mload(value), 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(add(value, 0x20), mload(value)) - let d := sub(keccak256(0x00, or(0x20, sub(0, shr(32, mload(value))))), value) - for { let o := add(value, 0x3c) } 1 {} { - sstore(add(o, d), mload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Sets the value at transient `ptr`. - function setCalldata(TBytes storage ptr, bytes calldata value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, or(shl(224, value.length), shr(32, calldataload(value.offset)))) - if iszero(lt(value.length, 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(value.offset, value.length) - // forgefmt: disable-next-item - let d := add(sub(keccak256(0x00, or(0x20, sub(0, shr(32, value.length)))), - value.offset), 0x20) - for { let o := add(value.offset, 0x1c) } 1 {} { - tstore(add(o, d), calldataload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Sets the value at transient `ptr`. - function setCalldataCompat(TBytes storage ptr, bytes calldata value) internal { - if (block.chainid == 1) return setCalldata(ptr, value); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - sstore(ptr.slot, or(shl(224, value.length), shr(32, calldataload(value.offset)))) - if iszero(lt(value.length, 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(value.offset, value.length) - // forgefmt: disable-next-item - let d := add(sub(keccak256(0x00, or(0x20, sub(0, shr(32, value.length)))), - value.offset), 0x20) - for { let o := add(value.offset, 0x1c) } 1 {} { - sstore(add(o, d), calldataload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Clears the value at transient `ptr`. - function clear(TBytes storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TBytes storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STACK OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a stack in transient storage. - function tStack(bytes32 tSlot) internal pure returns (TStack storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a stack in transient storage. - function tStack(uint256 tSlot) internal pure returns (TStack storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the number of elements in the stack. - function length(TStack storage ptr) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(160, shl(128, tload(ptr.slot))) // Removes the base offset and stride. - } - } - - /// @dev Clears the stack at `ptr`. - /// Note: Future usage of the stack will point to a fresh transient storage region. - function clear(TStack storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - // Clears the length and increments the base pointer by `1 << 128`. - tstore(ptr.slot, shl(128, add(1, shr(128, tload(ptr.slot))))) - } - } - - /// @dev Increments the stack length by 1, and returns a pointer to the top element. - /// We don't want to call this `push` as it does not take in an element value. - /// Note: The value pointed to might not be cleared from previous usage. - function place(TStack storage ptr) internal returns (bytes32 topPtr) { - /// @solidity memory-safe-assembly - assembly { - topPtr := add(0x100000000, tload(ptr.slot)) // Increments by a stride. - tstore(ptr.slot, topPtr) - topPtr := add(mul(_STACK_BASE_SALT, ptr.slot), topPtr) - } - } - - /// @dev Returns a pointer to the top element. Returns the zero pointer if the stack is empty. - /// This method can help avoid an additional `TLOAD`, but you MUST check if the - /// returned pointer is zero. And if it is, please DO NOT read / write to it. - function peek(TStack storage ptr) internal view returns (bytes32 topPtr) { - /// @solidity memory-safe-assembly - assembly { - let t := tload(ptr.slot) - topPtr := mul(iszero(iszero(shl(128, t))), add(mul(_STACK_BASE_SALT, ptr.slot), t)) - } - } - - /// @dev Returns a pointer to the top element. Reverts if the stack is empty. - function top(TStack storage ptr) internal view returns (bytes32 topPtr) { - /// @solidity memory-safe-assembly - assembly { - topPtr := tload(ptr.slot) - if iszero(topPtr) { - mstore(0x00, 0xbb704e21) // `StackIsEmpty()`. - revert(0x1c, 0x04) - } - topPtr := add(mul(_STACK_BASE_SALT, ptr.slot), topPtr) - } - } - - /// @dev Decrements the stack length by 1, returns a pointer to the top element - /// before the popping. Reverts if the stack is empty. - /// Note: Popping from the stack does NOT auto-clear the top value. - function pop(TStack storage ptr) internal returns (bytes32 lastTopPtr) { - /// @solidity memory-safe-assembly - assembly { - lastTopPtr := tload(ptr.slot) - if iszero(lastTopPtr) { - mstore(0x00, 0xbb704e21) // `StackIsEmpty()`. - revert(0x1c, 0x04) - } - tstore(ptr.slot, sub(lastTopPtr, 0x100000000)) // Decrements by a stride. - lastTopPtr := add(mul(_STACK_BASE_SALT, ptr.slot), lastTopPtr) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* TRANSIENT REGISTRY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the value for the key. - /// If the key does not exist, its admin will be set to the caller. - /// If the key already exist, its value will be overwritten, - /// and the caller must be the current admin for the key. - /// Reverts with empty data if the registry has not been deployed. - function registrySet(bytes32 key, bytes memory value) internal { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, 0xaac438c0) // `set(bytes32,bytes)`. - mstore(add(m, 0x20), key) - mstore(add(m, 0x40), 0x40) - let n := mload(value) - mstore(add(m, 0x60), n) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(m, 0x80), i), mload(add(add(value, 0x20), i))) - } - if iszero( - mul( - returndatasize(), - call(gas(), REGISTRY, 0, add(m, 0x1c), add(n, 0x64), 0x00, 0x20) - ) - ) { revert(0x00, returndatasize()) } - } - } - - /// @dev Returns the value for the key. - /// Reverts if the key does not exist. - /// Reverts with empty data if the registry has not been deployed. - function registryGet(bytes32 key) internal view returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x00, 0x8eaa6ac0) // `get(bytes32)`. - mstore(0x20, key) - if iszero(mul(returndatasize(), staticcall(gas(), REGISTRY, 0x1c, 0x24, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - // We can safely assume that the bytes will be containing the 0x20 offset. - returndatacopy(result, 0x20, sub(returndatasize(), 0x20)) - mstore(0x40, add(result, returndatasize())) // Allocate memory. - } - } - - /// @dev Clears the admin and the value for the key. - /// The caller must be the current admin of the key. - /// Reverts with empty data if the registry has not been deployed. - function registryClear(bytes32 key) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x97040a45) // `clear(bytes32)`. - mstore(0x20, key) - if iszero(mul(returndatasize(), call(gas(), REGISTRY, 0, 0x1c, 0x24, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - } - } - - /// @dev Returns the admin of the key. - /// Returns `address(0)` if the key does not exist. - /// Reverts with empty data if the registry has not been deployed. - function registryAdminOf(bytes32 key) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xc5344411) // `adminOf(bytes32)`. - mstore(0x20, key) - if iszero(mul(returndatasize(), staticcall(gas(), REGISTRY, 0x1c, 0x24, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - result := mload(0x00) - } - } - - /// @dev Changes the admin of the key. - /// The caller must be the current admin of the key. - /// The new admin must not be `address(0)`. - /// Reverts with empty data if the registry has not been deployed. - function registryChangeAdmin(bytes32 key, address newAdmin) internal { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, 0x053b1ca3) // `changeAdmin(bytes32,address)`. - mstore(0x20, key) - mstore(0x40, shr(96, shl(96, newAdmin))) - if iszero(mul(returndatasize(), call(gas(), REGISTRY, 0, 0x1c, 0x44, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TUint256 storage ptr) private pure returns (TUint256 storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TInt256 storage ptr) private pure returns (TInt256 storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TBytes32 storage ptr) private pure returns (TBytes32 storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TAddress storage ptr) private pure returns (TAddress storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TBool storage ptr) private pure returns (TBool storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TBytes storage ptr) private pure returns (TBytes storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/LibZip.sol b/grouperBot/lib/solady/src/utils/LibZip.sol deleted file mode 100644 index e7ce354..0000000 --- a/grouperBot/lib/solady/src/utils/LibZip.sol +++ /dev/null @@ -1,327 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for compressing and decompressing bytes. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibZip.sol) -/// @author Calldata compression by clabby (https://github.com/clabby/op-kompressor) -/// @author FastLZ by ariya (https://github.com/ariya/FastLZ) -/// -/// @dev Note: -/// The accompanying solady.js library includes implementations of -/// FastLZ and calldata operations for convenience. -library LibZip { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* FAST LZ OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // LZ77 implementation based on FastLZ. - // Equivalent to level 1 compression and decompression at the following commit: - // https://github.com/ariya/FastLZ/commit/344eb4025f9ae866ebf7a2ec48850f7113a97a42 - // Decompression is backwards compatible. - - /// @dev Returns the compressed `data`. - function flzCompress(bytes memory data) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function ms8(d_, v_) -> _d { - mstore8(d_, v_) - _d := add(d_, 1) - } - function u24(p_) -> _u { - _u := mload(p_) - _u := or(shl(16, byte(2, _u)), or(shl(8, byte(1, _u)), byte(0, _u))) - } - function cmp(p_, q_, e_) -> _l { - for { e_ := sub(e_, q_) } lt(_l, e_) { _l := add(_l, 1) } { - e_ := mul(iszero(byte(0, xor(mload(add(p_, _l)), mload(add(q_, _l))))), e_) - } - } - function literals(runs_, src_, dest_) -> _o { - for { _o := dest_ } iszero(lt(runs_, 0x20)) { runs_ := sub(runs_, 0x20) } { - mstore(ms8(_o, 31), mload(src_)) - _o := add(_o, 0x21) - src_ := add(src_, 0x20) - } - if iszero(runs_) { leave } - mstore(ms8(_o, sub(runs_, 1)), mload(src_)) - _o := add(1, add(_o, runs_)) - } - function mt(l_, d_, o_) -> _o { - for { d_ := sub(d_, 1) } iszero(lt(l_, 263)) { l_ := sub(l_, 262) } { - o_ := ms8(ms8(ms8(o_, add(224, shr(8, d_))), 253), and(0xff, d_)) - } - if iszero(lt(l_, 7)) { - _o := ms8(ms8(ms8(o_, add(224, shr(8, d_))), sub(l_, 7)), and(0xff, d_)) - leave - } - _o := ms8(ms8(o_, add(shl(5, l_), shr(8, d_))), and(0xff, d_)) - } - function setHash(i_, v_) { - let p_ := add(mload(0x40), shl(2, i_)) - mstore(p_, xor(mload(p_), shl(224, xor(shr(224, mload(p_)), v_)))) - } - function getHash(i_) -> _h { - _h := shr(224, mload(add(mload(0x40), shl(2, i_)))) - } - function hash(v_) -> _r { - _r := and(shr(19, mul(2654435769, v_)), 0x1fff) - } - function setNextHash(ip_, ipStart_) -> _ip { - setHash(hash(u24(ip_)), sub(ip_, ipStart_)) - _ip := add(ip_, 1) - } - result := mload(0x40) - calldatacopy(result, calldatasize(), 0x8000) // Zeroize the hashmap. - let op := add(result, 0x8000) - let a := add(data, 0x20) - let ipStart := a - let ipLimit := sub(add(ipStart, mload(data)), 13) - for { let ip := add(2, a) } lt(ip, ipLimit) {} { - let r := 0 - let d := 0 - for {} 1 {} { - let s := u24(ip) - let h := hash(s) - r := add(ipStart, getHash(h)) - setHash(h, sub(ip, ipStart)) - d := sub(ip, r) - if iszero(lt(ip, ipLimit)) { break } - ip := add(ip, 1) - if iszero(gt(d, 0x1fff)) { if eq(s, u24(r)) { break } } - } - if iszero(lt(ip, ipLimit)) { break } - ip := sub(ip, 1) - if gt(ip, a) { op := literals(sub(ip, a), a, op) } - let l := cmp(add(r, 3), add(ip, 3), add(ipLimit, 9)) - op := mt(l, d, op) - ip := setNextHash(setNextHash(add(ip, l), ipStart), ipStart) - a := ip - } - // Copy the result to compact the memory, overwriting the hashmap. - let end := sub(literals(sub(add(ipStart, mload(data)), a), a, op), 0x7fe0) - let o := add(result, 0x20) - mstore(result, sub(end, o)) // Store the length. - for {} iszero(gt(o, end)) { o := add(o, 0x20) } { mstore(o, mload(add(o, 0x7fe0))) } - mstore(end, 0) // Zeroize the slot after the string. - mstore(0x40, add(end, 0x20)) // Allocate the memory. - } - } - - /// @dev Returns the decompressed `data`. - function flzDecompress(bytes memory data) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let op := add(result, 0x20) - let end := add(add(data, 0x20), mload(data)) - for { data := add(data, 0x20) } lt(data, end) {} { - let w := mload(data) - let c := byte(0, w) - let t := shr(5, c) - if iszero(t) { - mstore(op, mload(add(data, 1))) - data := add(data, add(2, c)) - op := add(op, add(1, c)) - continue - } - for { - let g := eq(t, 7) - let l := add(2, xor(t, mul(g, xor(t, add(7, byte(1, w)))))) // M - let s := add(add(shl(8, and(0x1f, c)), byte(add(1, g), w)), 1) // R - let r := sub(op, s) - let f := xor(s, mul(gt(s, 0x20), xor(s, 0x20))) - let j := 0 - } 1 {} { - mstore(add(op, j), mload(add(r, j))) - j := add(j, f) - if lt(j, l) { continue } - data := add(data, add(2, g)) - op := add(op, l) - break - } - } - mstore(result, sub(op, add(result, 0x20))) // Store the length. - mstore(op, 0) // Zeroize the slot after the string. - mstore(0x40, add(op, 0x20)) // Allocate the memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CALLDATA OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Calldata compression and decompression using selective run length encoding: - // - Sequences of 0x00 (up to 128 consecutive). - // - Sequences of 0xff (up to 32 consecutive). - // - // A run length encoded block consists of two bytes: - // (0) 0x00 - // (1) A control byte with the following bit layout: - // - [7] `0: 0x00, 1: 0xff`. - // - [0..6] `runLength - 1`. - // - // The first 4 bytes are bitwise negated so that the compressed calldata - // can be dispatched into the `fallback` and `receive` functions. - - /// @dev Returns the compressed `data`. - function cdCompress(bytes memory data) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function countLeadingZeroBytes(x_) -> _r { - _r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x_)) - _r := or(_r, shl(6, lt(0xffffffffffffffff, shr(_r, x_)))) - _r := or(_r, shl(5, lt(0xffffffff, shr(_r, x_)))) - _r := or(_r, shl(4, lt(0xffff, shr(_r, x_)))) - _r := xor(31, or(shr(3, _r), lt(0xff, shr(_r, x_)))) - } - function min(x_, y_) -> _z { - _z := xor(x_, mul(xor(x_, y_), lt(y_, x_))) - } - result := mload(0x40) - let end := add(data, mload(data)) - let m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f - let o := add(result, 0x20) - for { let i := data } iszero(eq(i, end)) {} { - i := add(i, 1) - let c := byte(31, mload(i)) - if iszero(c) { - for {} 1 {} { - let x := mload(add(i, 0x20)) - if iszero(x) { - let r := min(sub(end, i), 0x20) - r := min(sub(0x7f, c), r) - i := add(i, r) - c := add(c, r) - if iszero(gt(r, 0x1f)) { break } - continue - } - let r := countLeadingZeroBytes(x) - r := min(sub(end, i), r) - i := add(i, r) - c := add(c, r) - break - } - mstore(o, shl(240, c)) - o := add(o, 2) - continue - } - if eq(c, 0xff) { - let r := 0x20 - let x := not(mload(add(i, r))) - if x { r := countLeadingZeroBytes(x) } - r := min(min(sub(end, i), r), 0x1f) - i := add(i, r) - mstore(o, shl(240, or(r, 0x80))) - o := add(o, 2) - continue - } - mstore8(o, c) - o := add(o, 1) - c := mload(add(i, 0x20)) - mstore(o, c) - // `.each(b => b == 0x00 || b == 0xff ? 0x80 : 0x00)`. - c := not(or(and(or(add(and(c, m), m), c), or(add(and(not(c), m), m), not(c))), m)) - let r := shl(7, lt(0x8421084210842108cc6318c6db6d54be, c)) // Save bytecode. - r := or(shl(6, lt(0xffffffffffffffff, shr(r, c))), r) - // forgefmt: disable-next-item - r := add(iszero(c), shr(3, xor(byte(and(0x1f, shr(byte(24, - mul(0x02040810204081, shr(r, c))), 0x8421084210842108cc6318c6db6d54be)), - 0xc0c8c8d0c8e8d0d8c8e8e0e8d0d8e0f0c8d0e8d0e0e0d8f0d0d0e0d8f8f8f8f8), r))) - r := min(sub(end, i), r) - o := add(o, r) - i := add(i, r) - } - // Bitwise negate the first 4 bytes. - mstore(add(result, 4), not(mload(add(result, 4)))) - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate the memory. - } - } - - /// @dev Returns the decompressed `data`. - function cdDecompress(bytes memory data) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - if mload(data) { - result := mload(0x40) - let s := add(data, 4) - let v := mload(s) - let end := add(add(0x20, data), mload(data)) - let m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f - let o := add(result, 0x20) - mstore(s, not(v)) // Bitwise negate the first 4 bytes. - for { let i := add(0x20, data) } 1 {} { - let c := mload(i) - if iszero(byte(0, c)) { - c := add(1, byte(1, c)) - if iszero(gt(c, 0x80)) { - i := add(i, 2) - calldatacopy(o, calldatasize(), c) // Fill with 0x00. - o := add(o, c) - if iszero(lt(i, end)) { break } - continue - } - i := add(i, 2) - mstore(o, not(0)) // Fill with 0xff. - o := add(o, sub(c, 0x80)) - if iszero(lt(i, end)) { break } - continue - } - mstore(o, c) - c := not(or(or(add(and(c, m), m), c), m)) // `.each(b => b == 0x00 ? 0x80 : 0x00)`. - let r := shl(7, lt(0x8421084210842108cc6318c6db6d54be, c)) // Save bytecode. - r := or(shl(6, lt(0xffffffffffffffff, shr(r, c))), r) - // forgefmt: disable-next-item - c := add(iszero(c), shr(3, xor(byte(and(0x1f, shr(byte(24, - mul(0x02040810204081, shr(r, c))), 0x8421084210842108cc6318c6db6d54be)), - 0xc0c8c8d0c8e8d0d8c8e8e0e8d0d8e0f0c8d0e8d0e0e0d8f0d0d0e0d8f8f8f8f8), r))) - o := add(o, c) - i := add(i, c) - if lt(i, end) { continue } - if gt(i, end) { o := sub(o, sub(i, end)) } - break - } - mstore(s, v) // Restore the first 4 bytes. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate the memory. - } - } - } - - /// @dev To be called in the `fallback` function. - /// ``` - /// fallback() external payable { LibZip.cdFallback(); } - /// receive() external payable {} // Silence compiler warning to add a `receive` function. - /// ``` - /// For efficiency, this function will directly return the results, terminating the context. - /// If called internally, it must be called at the end of the function. - function cdFallback() internal { - /// @solidity memory-safe-assembly - assembly { - if iszero(calldatasize()) { return(calldatasize(), calldatasize()) } - let o := 0 - let f := not(3) // For negating the first 4 bytes. - for { let i := 0 } lt(i, calldatasize()) {} { - let c := byte(0, xor(add(i, f), calldataload(i))) - i := add(i, 1) - if iszero(c) { - let d := byte(0, xor(add(i, f), calldataload(i))) - i := add(i, 1) - // Fill with either 0xff or 0x00. - mstore(o, not(0)) - if iszero(gt(d, 0x7f)) { calldatacopy(o, calldatasize(), add(d, 1)) } - o := add(o, add(and(d, 0x7f), 1)) - continue - } - mstore8(o, c) - o := add(o, 1) - } - let success := delegatecall(gas(), address(), 0x00, o, codesize(), 0x00) - returndatacopy(0x00, 0x00, returndatasize()) - if iszero(success) { revert(0x00, returndatasize()) } - return(0x00, returndatasize()) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/Lifebuoy.sol b/grouperBot/lib/solady/src/utils/Lifebuoy.sol deleted file mode 100644 index f4831a8..0000000 --- a/grouperBot/lib/solady/src/utils/Lifebuoy.sol +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Class that allows for rescue of ETH, ERC20, ERC721 tokens. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Lifebuoy.sol) -/// -/// @dev This contract is created to mitigate the following disasters: -/// - Careless user sends tokens to the wrong chain or wrong contract. -/// - Careless dev deploys a contract without a withdraw function in attempt to rescue -/// careless user's tokens, due to deployment nonce mismatch caused by -/// script misfire / misconfiguration. -/// - Careless dev forgets to add a withdraw function to a NFT sale contract. -/// -/// Note: if you are deploying via a untrusted `tx.origin`, -/// you MUST override `_lifebuoyDefaultDeployer` to return a trusted address. -/// -/// For best safety: -/// - For non-escrow contracts, inherit Lifebuoy as much as possible, -/// and leave it unlocked. -/// - For escrow contracts, lock access as tight as possible, -/// as soon as possible. Or simply don't inherit Lifebuoy. -/// Escrow: Your contract is designed to hold ETH, ERC20s, ERC721s -/// (e.g. liquidity pools). -/// -/// All rescue and rescue authorization functions require either: -/// - Caller is the deployer -/// AND the contract is not a proxy -/// AND `rescueLocked() & _LIFEBUOY_DEPLOYER_ACCESS_LOCK == 0`. -/// - Caller is `owner()` -/// AND `rescueLocked() & _LIFEBUOY_OWNER_ACCESS_LOCK == 0`. -/// -/// The choice of using bit flags to represent locked statuses is for -/// efficiency, flexibility, convenience. -/// -/// This contract is optimized with a priority on minimal bytecode size, -/// as the methods are not intended to be called often. -contract Lifebuoy { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The caller is not authorized to rescue or lock the rescue function. - error RescueUnauthorizedOrLocked(); - - /// @dev The rescue operation has failed due to a failed transfer. - error RescueTransferFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* LOCK FLAGS CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // These flags are kept internal to avoid bloating up the function dispatch. - // You can just copy paste this into your own code. - - /// @dev Flag to denote that the deployer's access is locked. (1) - uint256 internal constant _LIFEBUOY_DEPLOYER_ACCESS_LOCK = 1 << 0; - - /// @dev Flag to denote that the `owner()`'s access is locked. (2) - uint256 internal constant _LIFEBUOY_OWNER_ACCESS_LOCK = 1 << 1; - - /// @dev Flag to denote that the `lockRescue` function is locked. (4) - uint256 internal constant _LIFEBUOY_LOCK_RESCUE_LOCK = 1 << 2; - - /// @dev Flag to denote that the `rescueETH` function is locked. (8) - uint256 internal constant _LIFEBUOY_RESCUE_ETH_LOCK = 1 << 3; - - /// @dev Flag to denote that the `rescueERC20` function is locked. (16) - uint256 internal constant _LIFEBUOY_RESCUE_ERC20_LOCK = 1 << 4; - - /// @dev Flag to denote that the `rescueERC721` function is locked. (32) - uint256 internal constant _LIFEBUOY_RESCUE_ERC721_LOCK = 1 << 5; - - /// @dev Flag to denote that the `rescueERC1155` function is locked. (64) - uint256 internal constant _LIFEBUOY_RESCUE_ERC1155_LOCK = 1 << 6; - - /// @dev Flag to denote that the `rescueERC6909` function is locked. (128) - uint256 internal constant _LIFEBUOY_RESCUE_ERC6909_LOCK = 1 << 7; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* IMMUTABLES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For checking that the caller is the deployer and - /// that the context is not a delegatecall - /// (so that the implementation deployer cannot drain proxies). - bytes32 internal immutable _lifebuoyDeployerHash; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The rescue locked flags slot is given by: - /// `bytes32(~uint256(uint32(bytes4(keccak256("_RESCUE_LOCKED_FLAGS_SLOT_NOT")))))`. - /// It is intentionally chosen to be a high value - /// to avoid collision with lower slots. - /// The choice of manual storage layout is to enable compatibility - /// with both regular and upgradeable contracts. - bytes32 internal constant _RESCUE_LOCKED_FLAGS_SLOT = - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffb8e2915b; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor() payable { - bytes32 hash; - uint256 deployer = uint160(_lifebuoyDefaultDeployer()); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, address()) - mstore(0x20, deployer) - hash := keccak256(0x00, 0x40) - } - _lifebuoyDeployerHash = hash; - } - - /// @dev Returns `tx.origin` by default. Override to return another address if needed. - /// - /// Note: If you are deploying via a untrusted `tx.origin` (e.g. ERC4337 bundler) - /// you MUST override this function to return a trusted address. - function _lifebuoyDefaultDeployer() internal view virtual returns (address) { - // I know about EIP7645, and I will stop it if it gets traction. - // Worse case, I will add an `ecrecover` method. But not today. - return tx.origin; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RESCUE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sends `amount` (in wei) ETH from the current contract to `to`. - /// Reverts upon failure. - function rescueETH(address to, uint256 amount) - public - payable - virtual - onlyRescuer(_LIFEBUOY_RESCUE_ETH_LOCK) - { - /// @solidity memory-safe-assembly - assembly { - if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0x7ec62e76) // `RescueTransferFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. - /// Does not check for existence of token or return data. Reverts upon failure. - function rescueERC20(address token, address to, uint256 amount) - public - payable - virtual - onlyRescuer(_LIFEBUOY_RESCUE_ERC20_LOCK) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - // `RescueTransferFailed()` and `transfer(address,uint256)`. - mstore(0x00, shl(96, 0x7ec62e76a9059cbb)) - if iszero(call(gas(), token, callvalue(), 0x10, 0x44, codesize(), 0x00)) { - revert(0x0c, 0x04) - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @dev Sends `id` of ERC721 `token` from the current contract to `to`. - /// Does not check for existence of token or return data. Reverts upon failure. - function rescueERC721(address token, address to, uint256 id) - public - payable - virtual - onlyRescuer(_LIFEBUOY_RESCUE_ERC721_LOCK) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, id) // Store the `id` argument. - mstore(0x40, shr(96, shl(96, to))) // Store the `to` argument. - mstore(0x20, address()) // Store the `from` argument. - // `RescueTransferFailed()` and `transferFrom(address,address,uint256)`. - mstore(0x00, 0x7ec62e7623b872dd) - if iszero(call(gas(), token, callvalue(), 0x1c, 0x64, codesize(), 0x00)) { - revert(0x18, 0x04) - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Sends `amount` of `id` of ERC1155 `token` from the current contract to `to`. - /// Does not check for existence of token or return data. Reverts upon failure. - function rescueERC1155( - address token, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) public payable virtual onlyRescuer(_LIFEBUOY_RESCUE_ERC1155_LOCK) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - // `RescueTransferFailed()` and `safeTransferFrom(address,address,uint256,uint256,bytes)`. - mstore(m, 0x7ec62e76f242432a) - mstore(add(0x20, m), address()) // Store the `from` argument. - mstore(add(0x40, m), shr(96, shl(96, to))) // Store the `to` argument. - mstore(add(0x60, m), id) // Store the `id` argument. - mstore(add(0x80, m), amount) // Store the `amount` argument. - mstore(add(0xa0, m), 0xa0) // Store the offset to `data`. - mstore(add(0xc0, m), data.length) - calldatacopy(add(m, 0xe0), data.offset, data.length) - // forgefmt: disable-next-item - if iszero( - call(gas(), token, callvalue(), add(m, 0x1c), add(0xc4, data.length), codesize(), 0x00) - ) { revert(add(m, 0x18), 0x04) } - } - } - - /// @dev Sends `amount` of `id` of ERC6909 `token` from the current contract to `to`. - /// Does not check for existence of token or return data. Reverts upon failure. - function rescueERC6909(address token, address to, uint256 id, uint256 amount) - public - payable - virtual - onlyRescuer(_LIFEBUOY_RESCUE_ERC6909_LOCK) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, id) // Store the `id` argument. - mstore(0x54, amount) // Store the `amount` argument. - // `RescueTransferFailed()` and `transfer(address,uint256,uint256)`. - mstore(0x00, shl(96, 0x7ec62e76095bcdb6)) - if iszero(call(gas(), token, callvalue(), 0x10, 0x64, codesize(), 0x00)) { - revert(0x0c, 0x04) - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RESCUE AUTHORIZATION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the flags denoting whether access to rescue functions - /// (including `lockRescue`) is locked. - function rescueLocked() public view virtual returns (uint256 locks) { - /// @solidity memory-safe-assembly - assembly { - locks := sload(_RESCUE_LOCKED_FLAGS_SLOT) - } - } - - /// @dev Locks (i.e. permanently removes) access to rescue functions (including `lockRescue`). - function lockRescue(uint256 locksToSet) - public - payable - virtual - onlyRescuer(_LIFEBUOY_LOCK_RESCUE_LOCK) - { - _lockRescue(locksToSet); - } - - /// @dev Internal function to set the lock flags without going through access control. - function _lockRescue(uint256 locksToSet) internal virtual { - /// @solidity memory-safe-assembly - assembly { - let s := _RESCUE_LOCKED_FLAGS_SLOT - sstore(s, or(sload(s), locksToSet)) - } - } - - /// @dev Requires that the rescue function being guarded is: - /// 1. Not locked, AND - /// 2. Called by either: - /// (a) The `owner()`, OR - /// (b) The deployer (if not via a delegate call and deployer is an EOA). - function _checkRescuer(uint256 modeLock) internal view virtual { - uint256 locks = rescueLocked(); - bytes32 h = _lifebuoyDeployerHash; - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - // If the `modeLock` flag is true, set all bits in `locks` to true. - locks := or(sub(0, iszero(iszero(and(modeLock, locks)))), locks) - // Caller is the deployer - // AND the contract is not a proxy - // AND `locks & _LIFEBUOY_DEPLOYER_ACCESS_LOCK` is false. - mstore(0x20, caller()) - mstore(and(locks, _LIFEBUOY_DEPLOYER_ACCESS_LOCK), address()) - if eq(keccak256(0x00, 0x40), h) { break } - // If the caller is `owner()` - // AND `locks & _LIFEBUOY_OWNER_ACCESS_LOCK` is false. - mstore(0x08, 0x8da5cb5b0a0362e0) // `owner()` and `RescueUnauthorizedOrLocked()`. - if and( // The arguments of `and` are evaluated from right to left. - lt( - and(locks, _LIFEBUOY_OWNER_ACCESS_LOCK), - and(gt(returndatasize(), 0x1f), eq(mload(0x00), caller())) - ), - staticcall(gas(), address(), 0x20, 0x04, 0x00, 0x20) - ) { break } - revert(0x24, 0x04) - } - } - } - - /// @dev Modifier that calls `_checkRescuer()` at the start of the function. - modifier onlyRescuer(uint256 modeLock) virtual { - _checkRescuer(modeLock); - _; - } -} diff --git a/grouperBot/lib/solady/src/utils/MerkleProofLib.sol b/grouperBot/lib/solady/src/utils/MerkleProofLib.sol deleted file mode 100644 index 967eb98..0000000 --- a/grouperBot/lib/solady/src/utils/MerkleProofLib.sol +++ /dev/null @@ -1,309 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol) -library MerkleProofLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MERKLE PROOF VERIFICATION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. - function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) - internal - pure - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - if mload(proof) { - // Initialize `offset` to the offset of `proof` elements in memory. - let offset := add(proof, 0x20) - // Left shift by 5 is equivalent to multiplying by 0x20. - let end := add(offset, shl(5, mload(proof))) - // Iterate over proof elements to compute root hash. - for {} 1 {} { - // Slot of `leaf` in scratch space. - // If the condition is true: 0x20, otherwise: 0x00. - let scratch := shl(5, gt(leaf, mload(offset))) - // Store elements to hash contiguously in scratch space. - // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes. - mstore(scratch, leaf) - mstore(xor(scratch, 0x20), mload(offset)) - // Reuse `leaf` to store the hash to reduce stack operations. - leaf := keccak256(0x00, 0x40) - offset := add(offset, 0x20) - if iszero(lt(offset, end)) { break } - } - } - isValid := eq(leaf, root) - } - } - - /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`. - function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) - internal - pure - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - if proof.length { - // Left shift by 5 is equivalent to multiplying by 0x20. - let end := add(proof.offset, shl(5, proof.length)) - // Initialize `offset` to the offset of `proof` in the calldata. - let offset := proof.offset - // Iterate over proof elements to compute root hash. - for {} 1 {} { - // Slot of `leaf` in scratch space. - // If the condition is true: 0x20, otherwise: 0x00. - let scratch := shl(5, gt(leaf, calldataload(offset))) - // Store elements to hash contiguously in scratch space. - // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes. - mstore(scratch, leaf) - mstore(xor(scratch, 0x20), calldataload(offset)) - // Reuse `leaf` to store the hash to reduce stack operations. - leaf := keccak256(0x00, 0x40) - offset := add(offset, 0x20) - if iszero(lt(offset, end)) { break } - } - } - isValid := eq(leaf, root) - } - } - - /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`, - /// given `proof` and `flags`. - /// - /// Note: - /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length` - /// will always return false. - /// - The sum of the lengths of `proof` and `leaves` must never overflow. - /// - Any non-zero word in the `flags` array is treated as true. - /// - The memory offset of `proof` must be non-zero - /// (i.e. `proof` is not pointing to the scratch space). - function verifyMultiProof( - bytes32[] memory proof, - bytes32 root, - bytes32[] memory leaves, - bool[] memory flags - ) internal pure returns (bool isValid) { - // Rebuilds the root by consuming and producing values on a queue. - // The queue starts with the `leaves` array, and goes into a `hashes` array. - // After the process, the last element on the queue is verified - // to be equal to the `root`. - // - // The `flags` array denotes whether the sibling - // should be popped from the queue (`flag == true`), or - // should be popped from the `proof` (`flag == false`). - /// @solidity memory-safe-assembly - assembly { - // Cache the lengths of the arrays. - let leavesLength := mload(leaves) - let proofLength := mload(proof) - let flagsLength := mload(flags) - - // Advance the pointers of the arrays to point to the data. - leaves := add(0x20, leaves) - proof := add(0x20, proof) - flags := add(0x20, flags) - - // If the number of flags is correct. - for {} eq(add(leavesLength, proofLength), add(flagsLength, 1)) {} { - // For the case where `proof.length + leaves.length == 1`. - if iszero(flagsLength) { - // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`. - isValid := eq(mload(xor(leaves, mul(xor(proof, leaves), proofLength))), root) - break - } - - // The required final proof offset if `flagsLength` is not zero, otherwise zero. - let proofEnd := add(proof, shl(5, proofLength)) - // We can use the free memory space for the queue. - // We don't need to allocate, since the queue is temporary. - let hashesFront := mload(0x40) - // Copy the leaves into the hashes. - // Sometimes, a little memory expansion costs less than branching. - // Should cost less, even with a high free memory offset of 0x7d00. - leavesLength := shl(5, leavesLength) - for { let i := 0 } iszero(eq(i, leavesLength)) { i := add(i, 0x20) } { - mstore(add(hashesFront, i), mload(add(leaves, i))) - } - // Compute the back of the hashes. - let hashesBack := add(hashesFront, leavesLength) - // This is the end of the memory for the queue. - // We recycle `flagsLength` to save on stack variables (sometimes save gas). - flagsLength := add(hashesBack, shl(5, flagsLength)) - - for {} 1 {} { - // Pop from `hashes`. - let a := mload(hashesFront) - // Pop from `hashes`. - let b := mload(add(hashesFront, 0x20)) - hashesFront := add(hashesFront, 0x40) - - // If the flag is false, load the next proof, - // else, pops from the queue. - if iszero(mload(flags)) { - // Loads the next proof. - b := mload(proof) - proof := add(proof, 0x20) - // Unpop from `hashes`. - hashesFront := sub(hashesFront, 0x20) - } - - // Advance to the next flag. - flags := add(flags, 0x20) - - // Slot of `a` in scratch space. - // If the condition is true: 0x20, otherwise: 0x00. - let scratch := shl(5, gt(a, b)) - // Hash the scratch space and push the result onto the queue. - mstore(scratch, a) - mstore(xor(scratch, 0x20), b) - mstore(hashesBack, keccak256(0x00, 0x40)) - hashesBack := add(hashesBack, 0x20) - if iszero(lt(hashesBack, flagsLength)) { break } - } - isValid := - and( - // Checks if the last value in the queue is same as the root. - eq(mload(sub(hashesBack, 0x20)), root), - // And whether all the proofs are used, if required. - eq(proofEnd, proof) - ) - break - } - } - } - - /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`, - /// given `proof` and `flags`. - /// - /// Note: - /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length` - /// will always return false. - /// - Any non-zero word in the `flags` array is treated as true. - /// - The calldata offset of `proof` must be non-zero - /// (i.e. `proof` is from a regular Solidity function with a 4-byte selector). - function verifyMultiProofCalldata( - bytes32[] calldata proof, - bytes32 root, - bytes32[] calldata leaves, - bool[] calldata flags - ) internal pure returns (bool isValid) { - // Rebuilds the root by consuming and producing values on a queue. - // The queue starts with the `leaves` array, and goes into a `hashes` array. - // After the process, the last element on the queue is verified - // to be equal to the `root`. - // - // The `flags` array denotes whether the sibling - // should be popped from the queue (`flag == true`), or - // should be popped from the `proof` (`flag == false`). - /// @solidity memory-safe-assembly - assembly { - // If the number of flags is correct. - for {} eq(add(leaves.length, proof.length), add(flags.length, 1)) {} { - // For the case where `proof.length + leaves.length == 1`. - if iszero(flags.length) { - // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`. - // forgefmt: disable-next-item - isValid := eq( - calldataload( - xor(leaves.offset, mul(xor(proof.offset, leaves.offset), proof.length)) - ), - root - ) - break - } - - // The required final proof offset if `flagsLength` is not zero, otherwise zero. - let proofEnd := add(proof.offset, shl(5, proof.length)) - // We can use the free memory space for the queue. - // We don't need to allocate, since the queue is temporary. - let hashesFront := mload(0x40) - // Copy the leaves into the hashes. - // Sometimes, a little memory expansion costs less than branching. - // Should cost less, even with a high free memory offset of 0x7d00. - calldatacopy(hashesFront, leaves.offset, shl(5, leaves.length)) - // Compute the back of the hashes. - let hashesBack := add(hashesFront, shl(5, leaves.length)) - // This is the end of the memory for the queue. - // We recycle `flagsLength` to save on stack variables (sometimes save gas). - flags.length := add(hashesBack, shl(5, flags.length)) - - // We don't need to make a copy of `proof.offset` or `flags.offset`, - // as they are pass-by-value (this trick may not always save gas). - - for {} 1 {} { - // Pop from `hashes`. - let a := mload(hashesFront) - // Pop from `hashes`. - let b := mload(add(hashesFront, 0x20)) - hashesFront := add(hashesFront, 0x40) - - // If the flag is false, load the next proof, - // else, pops from the queue. - if iszero(calldataload(flags.offset)) { - // Loads the next proof. - b := calldataload(proof.offset) - proof.offset := add(proof.offset, 0x20) - // Unpop from `hashes`. - hashesFront := sub(hashesFront, 0x20) - } - - // Advance to the next flag offset. - flags.offset := add(flags.offset, 0x20) - - // Slot of `a` in scratch space. - // If the condition is true: 0x20, otherwise: 0x00. - let scratch := shl(5, gt(a, b)) - // Hash the scratch space and push the result onto the queue. - mstore(scratch, a) - mstore(xor(scratch, 0x20), b) - mstore(hashesBack, keccak256(0x00, 0x40)) - hashesBack := add(hashesBack, 0x20) - if iszero(lt(hashesBack, flags.length)) { break } - } - isValid := - and( - // Checks if the last value in the queue is same as the root. - eq(mload(sub(hashesBack, 0x20)), root), - // And whether all the proofs are used, if required. - eq(proofEnd, proof.offset) - ) - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EMPTY CALLDATA HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns an empty calldata bytes32 array. - function emptyProof() internal pure returns (bytes32[] calldata proof) { - /// @solidity memory-safe-assembly - assembly { - proof.length := 0 - } - } - - /// @dev Returns an empty calldata bytes32 array. - function emptyLeaves() internal pure returns (bytes32[] calldata leaves) { - /// @solidity memory-safe-assembly - assembly { - leaves.length := 0 - } - } - - /// @dev Returns an empty calldata bool array. - function emptyFlags() internal pure returns (bool[] calldata flags) { - /// @solidity memory-safe-assembly - assembly { - flags.length := 0 - } - } -} diff --git a/grouperBot/lib/solady/src/utils/MerkleTreeLib.sol b/grouperBot/lib/solady/src/utils/MerkleTreeLib.sol deleted file mode 100644 index 260fac5..0000000 --- a/grouperBot/lib/solady/src/utils/MerkleTreeLib.sol +++ /dev/null @@ -1,289 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for generating Merkle trees. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MerkleTreeLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/merkle-tree/blob/master/src/core.ts) -/// @dev Note: -/// - Leaves are NOT auto hashed. Note that some libraries hash the leaves by default. -/// We leave it up to you to decide if this is needed. -/// If your leaves are 64 bytes long, do hash them first for safety. -/// See: https://www.rareskills.io/post/merkle-tree-second-preimage-attack -/// - Leaves are NOT auto globally sorted. Note that some libraries sort the leaves by default. -/// - The pair hash is pair-sorted-keccak256, which works out-of-the-box with `MerkleProofLib`. -/// - This library is NOT equivalent to OpenZeppelin or Murky. -/// Equivalence is NOT required if you are just using this for pure Solidity testing. -/// May be relevant for differential testing between Solidity vs external libraries. -library MerkleTreeLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev At least 1 leaf is required to build the tree. - error MerkleTreeLeavesEmpty(); - - /// @dev Attempt to access a node with an out-of-bounds index. - /// Check if the tree has been built and has sufficient leaves and nodes. - error MerkleTreeOutOfBoundsAccess(); - - /// @dev Leaf indices for multi proof must be strictly ascending and not empty. - error MerkleTreeInvalidLeafIndices(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MERKLE TREE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Builds and return a complete Merkle tree. - /// To make it a full Merkle tree, use `build(pad(leaves))`. - function build(bytes32[] memory leaves) internal pure returns (bytes32[] memory tree) { - /// @solidity memory-safe-assembly - assembly { - tree := mload(0x40) // `nodes`. - let l := mload(leaves) - if iszero(l) { - mstore(0x00, 0xe7171dc4) // `MerkleTreeLeavesEmpty()`. - revert(0x1c, 0x04) - } - let n := sub(add(l, l), 1) - mstore(tree, n) // `.length`. - let nodes := add(tree, 0x20) - let f := add(nodes, shl(5, n)) - mstore(0x40, f) // Allocate memory. - let e := add(0x20, shl(5, l)) - for { let i := 0x20 } 1 {} { - mstore(sub(f, i), mload(add(leaves, i))) - i := add(i, 0x20) - if eq(i, e) { break } - } - if iszero(lt(l, 2)) { - for { let i := shl(5, sub(l, 2)) } 1 {} { - let left := mload(add(nodes, add(add(i, i), 0x20))) - let right := mload(add(nodes, add(add(i, i), 0x40))) - let c := shl(5, lt(left, right)) - mstore(c, right) - mstore(xor(c, 0x20), left) - mstore(add(nodes, i), keccak256(0x00, 0x40)) - if iszero(i) { break } - i := sub(i, 0x20) - } - } - } - } - - /// @dev Returns the root. - function root(bytes32[] memory tree) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(0x20, tree)) - if iszero(mload(tree)) { - mstore(0x00, 0x7a856a38) // `MerkleTreeOutOfBoundsAccess()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Returns the number of leaves. - function numLeaves(bytes32[] memory tree) internal pure returns (uint256) { - unchecked { - return tree.length - (tree.length >> 1); - } - } - - /// @dev Returns the number of internal nodes. - function numInternalNodes(bytes32[] memory tree) internal pure returns (uint256) { - return tree.length >> 1; - } - - /// @dev Returns the leaf at `leafIndex`. - function leaf(bytes32[] memory tree, uint256 leafIndex) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(tree) - if iszero(lt(leafIndex, sub(n, shr(1, n)))) { - mstore(0x00, 0x7a856a38) // `MerkleTreeOutOfBoundsAccess()`. - revert(0x1c, 0x04) - } - result := mload(add(tree, shl(5, sub(n, leafIndex)))) - } - } - - /// @dev Returns the leaves at `leafIndices`. - function gatherLeaves(bytes32[] memory tree, uint256[] memory leafIndices) - internal - pure - returns (bytes32[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let l := mload(leafIndices) - mstore(result, l) // `.length`. - let d := sub(leafIndices, result) - let n := mload(tree) - let o := add(result, 0x20) - for { let i := 0 } iszero(eq(i, l)) { i := add(i, 1) } { - let j := add(o, shl(5, i)) - let leafIndex := mload(add(j, d)) - if iszero(lt(leafIndex, sub(n, shr(1, n)))) { - mstore(0x00, 0x7a856a38) // `MerkleTreeOutOfBoundsAccess()`. - revert(0x1c, 0x04) - } - mstore(j, mload(add(tree, shl(5, sub(n, leafIndex))))) - } - mstore(0x40, add(o, shl(5, l))) // Allocate memory. - } - } - - /// @dev Returns the proof for the leaf at `leafIndex`. - function leafProof(bytes32[] memory tree, uint256 leafIndex) - internal - pure - returns (bytes32[] memory result) - { - uint256 nodeIndex; - /// @solidity memory-safe-assembly - assembly { - let n := mload(tree) - nodeIndex := sub(n, add(1, leafIndex)) - if iszero(lt(leafIndex, sub(n, shr(1, n)))) { nodeIndex := not(0) } - } - result = nodeProof(tree, nodeIndex); - } - - /// @dev Returns the proof for the node at `nodeIndex`. - /// This function can be used to prove the existence of internal nodes. - function nodeProof(bytes32[] memory tree, uint256 nodeIndex) - internal - pure - returns (bytes32[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - if iszero(lt(nodeIndex, mload(tree))) { - mstore(0x00, 0x7a856a38) // `MerkleTreeOutOfBoundsAccess()`. - revert(0x1c, 0x04) - } - let o := add(result, 0x20) - for { let i := nodeIndex } i { i := shr(1, sub(i, 1)) } { - mstore(o, mload(add(tree, shl(5, add(i, shl(1, and(1, i))))))) - o := add(o, 0x20) - } - mstore(0x40, o) // Allocate memory. - mstore(result, shr(5, sub(o, add(result, 0x20)))) // Store length. - } - } - - /// @dev Returns proof and corresponding flags for multiple leaves. - /// The `leafIndices` must be non-empty and sorted in strictly ascending order. - function multiProofForLeaves(bytes32[] memory tree, uint256[] memory leafIndices) - internal - pure - returns (bytes32[] memory proof, bool[] memory flags) - { - /// @solidity memory-safe-assembly - assembly { - function gen(leafIndices_, t_, proof_, flags_) -> _flagsLen, _proofLen { - let q_ := mload(0x40) // Circular buffer. - let c_ := mload(leafIndices_) // Capacity of circular buffer. - let e_ := c_ // End index of circular buffer. - let b_ := 0 // Start index of circular buffer. - for { - let n_ := mload(t_) // Num nodes. - let l_ := sub(n_, shr(1, n_)) // Num leaves. - let p_ := not(0) - let i_ := 0 - } 1 {} { - let j_ := mload(add(add(leafIndices_, 0x20), shl(5, i_))) // Leaf index. - if flags_ { - if iszero(lt(j_, l_)) { - mstore(0x00, 0x7a856a38) // `MerkleTreeOutOfBoundsAccess()`. - revert(0x1c, 0x04) - } - if iszero(sgt(j_, p_)) { - mstore(0x00, 0xe9729976) // `MerkleTreeInvalidLeafIndices()`. - revert(0x1c, 0x04) - } - p_ := j_ - } - mstore(add(q_, shl(5, i_)), sub(n_, add(1, j_))) - i_ := add(i_, 1) - if eq(i_, e_) { break } - } - for {} 1 {} { - if iszero(lt(b_, e_)) { break } - let j_ := mload(add(q_, shl(5, mod(b_, c_)))) // Current. - if iszero(j_) { break } - b_ := add(b_, 1) - let s_ := add(j_, shl(1, and(j_, 1))) // Sibling (+1). - _flagsLen := add(_flagsLen, 0x20) - let f_ := and(eq(s_, add(1, mload(add(q_, shl(5, mod(b_, c_)))))), lt(b_, e_)) - b_ := add(b_, f_) - _proofLen := add(_proofLen, shl(5, iszero(f_))) - if flags_ { - mstore(add(flags_, _flagsLen), f_) - mstore(mul(iszero(f_), add(proof_, _proofLen)), mload(add(t_, shl(5, s_)))) - } - mstore(add(q_, shl(5, mod(e_, c_))), shr(1, sub(j_, 1))) - e_ := add(e_, 1) - } - _proofLen := shr(5, _proofLen) - _flagsLen := shr(5, _flagsLen) - } - if iszero(mload(leafIndices)) { - mstore(0x00, 0xe9729976) // `MerkleTreeInvalidLeafIndices()`. - revert(0x1c, 0x04) - } - let flagsLen, proofLen := gen(leafIndices, tree, 0x00, 0x00) - proof := mload(0x40) - mstore(proof, proofLen) - flags := add(add(proof, 0x20), shl(5, proofLen)) - mstore(flags, flagsLen) - mstore(0x40, add(add(flags, 0x20), shl(5, flagsLen))) // Allocate memory. - flagsLen, proofLen := gen(leafIndices, tree, proof, flags) - } - } - - /// @dev Returns a copy of leaves, with the length padded to a power of 2. - function pad(bytes32[] memory leaves, bytes32 defaultFill) - internal - pure - returns (bytes32[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let l := mload(leaves) - let p := sub(l, 1) - if iszero(lt(p, 0xffffffff)) { - mstore(0x00, 0xe7171dc4) // `MerkleTreeLeavesEmpty()`. - revert(0x1c, mul(iszero(l), 0x04)) // If `p > 2**32 - 1`, revert with empty. - } - p := or(shr(1, p), p) - p := or(shr(2, p), p) - p := or(shr(4, p), p) - p := or(shr(8, p), p) - p := add(1, or(shr(16, p), p)) // Supports up to `2**32 - 1`. - mstore(result, p) // Store length. - mstore(0x40, add(result, add(0x20, shl(5, p)))) // Allocate memory. - let d := sub(result, leaves) - let copyEnd := add(add(leaves, 0x20), shl(5, l)) - let end := add(add(leaves, 0x20), shl(5, p)) - mstore(0x00, defaultFill) - for { let i := add(leaves, 0x20) } 1 {} { - mstore(add(i, d), mload(mul(i, lt(i, copyEnd)))) - i := add(i, 0x20) - if eq(i, end) { break } - } - } - } - - /// @dev Equivalent to `pad(leaves, bytes32(0))`. - function pad(bytes32[] memory leaves) internal pure returns (bytes32[] memory result) { - result = pad(leaves, bytes32(0)); - } -} diff --git a/grouperBot/lib/solady/src/utils/MetadataReaderLib.sol b/grouperBot/lib/solady/src/utils/MetadataReaderLib.sol deleted file mode 100644 index b4b83dc..0000000 --- a/grouperBot/lib/solady/src/utils/MetadataReaderLib.sol +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for reading contract metadata robustly. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MetadataReaderLib.sol) -library MetadataReaderLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Default gas stipend for contract reads. High enough for most practical use cases - /// (able to SLOAD about 1000 bytes of data), but low enough to prevent griefing. - uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000; - - /// @dev Default string byte length limit. - uint256 internal constant STRING_LIMIT_DEFAULT = 1000; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* METADATA READING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Best-effort string reading operations. - // Should NOT revert as long as sufficient gas is provided. - // - // Performs the following in order: - // 1. Returns the empty string for the following cases: - // - Reverts. - // - No returndata (e.g. function returns nothing, EOA). - // - Returns empty string. - // 2. Attempts to `abi.decode` the returndata into a string. - // 3. With any remaining gas, scans the returndata from start to end for the - // null byte '\0', to interpret the returndata as a null-terminated string. - - /// @dev Equivalent to `readString(abi.encodeWithSignature("name()"))`. - function readName(address target) internal view returns (string memory) { - return _string(target, _ptr(0x06fdde03), STRING_LIMIT_DEFAULT, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Equivalent to `readString(abi.encodeWithSignature("name()"), limit)`. - function readName(address target, uint256 limit) internal view returns (string memory) { - return _string(target, _ptr(0x06fdde03), limit, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Equivalent to `readString(abi.encodeWithSignature("name()"), limit, gasStipend)`. - function readName(address target, uint256 limit, uint256 gasStipend) - internal - view - returns (string memory) - { - return _string(target, _ptr(0x06fdde03), limit, gasStipend); - } - - /// @dev Equivalent to `readString(abi.encodeWithSignature("symbol()"))`. - function readSymbol(address target) internal view returns (string memory) { - return _string(target, _ptr(0x95d89b41), STRING_LIMIT_DEFAULT, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Equivalent to `readString(abi.encodeWithSignature("symbol()"), limit)`. - function readSymbol(address target, uint256 limit) internal view returns (string memory) { - return _string(target, _ptr(0x95d89b41), limit, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Equivalent to `readString(abi.encodeWithSignature("symbol()"), limit, gasStipend)`. - function readSymbol(address target, uint256 limit, uint256 gasStipend) - internal - view - returns (string memory) - { - return _string(target, _ptr(0x95d89b41), limit, gasStipend); - } - - /// @dev Performs a best-effort string query on `target` with `data` as the calldata. - /// The string will be truncated to `STRING_LIMIT_DEFAULT` (1000) bytes. - function readString(address target, bytes memory data) internal view returns (string memory) { - return _string(target, _ptr(data), STRING_LIMIT_DEFAULT, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Performs a best-effort string query on `target` with `data` as the calldata. - /// The string will be truncated to `limit` bytes. - function readString(address target, bytes memory data, uint256 limit) - internal - view - returns (string memory) - { - return _string(target, _ptr(data), limit, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Performs a best-effort string query on `target` with `data` as the calldata. - /// The string will be truncated to `limit` bytes. - function readString(address target, bytes memory data, uint256 limit, uint256 gasStipend) - internal - view - returns (string memory) - { - return _string(target, _ptr(data), limit, gasStipend); - } - - // Best-effort unsigned integer reading operations. - // Should NOT revert as long as sufficient gas is provided. - // - // Performs the following in order: - // 1. Attempts to `abi.decode` the result into a uint256 - // (equivalent across all Solidity uint types, downcast as needed). - // 2. Returns zero for the following cases: - // - Reverts. - // - No returndata (e.g. function returns nothing, EOA). - // - Returns zero. - // - `abi.decode` failure. - - /// @dev Equivalent to `uint8(readUint(abi.encodeWithSignature("decimals()")))`. - function readDecimals(address target) internal view returns (uint8) { - return uint8(_uint(target, _ptr(0x313ce567), GAS_STIPEND_NO_GRIEF)); - } - - /// @dev Equivalent to `uint8(readUint(abi.encodeWithSignature("decimals()"), gasStipend))`. - function readDecimals(address target, uint256 gasStipend) internal view returns (uint8) { - return uint8(_uint(target, _ptr(0x313ce567), gasStipend)); - } - - /// @dev Performs a best-effort uint query on `target` with `data` as the calldata. - function readUint(address target, bytes memory data) internal view returns (uint256) { - return _uint(target, _ptr(data), GAS_STIPEND_NO_GRIEF); - } - - /// @dev Performs a best-effort uint query on `target` with `data` as the calldata. - function readUint(address target, bytes memory data, uint256 gasStipend) - internal - view - returns (uint256) - { - return _uint(target, _ptr(data), gasStipend); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Attempts to read and return a string at `target`. - function _string(address target, bytes32 ptr, uint256 limit, uint256 gasStipend) - private - view - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - function min(x_, y_) -> _z { - _z := xor(x_, mul(xor(x_, y_), lt(y_, x_))) - } - for {} staticcall(gasStipend, target, add(ptr, 0x20), mload(ptr), 0x00, 0x20) {} { - let m := mload(0x40) // Grab the free memory pointer. - let s := add(0x20, m) // Start of the string's bytes in memory. - // Attempt to `abi.decode` if the returndatasize is greater or equal to 64. - if iszero(lt(returndatasize(), 0x40)) { - let o := mload(0x00) // Load the string's offset in the returndata. - // If the string's offset is within bounds. - if iszero(gt(o, sub(returndatasize(), 0x20))) { - returndatacopy(m, o, 0x20) // Copy the string's length. - // If the full string's end is within bounds. - // Note: If the full string doesn't fit, the `abi.decode` must be aborted - // for compliance purposes, regardless if the truncated string can fit. - if iszero(gt(mload(m), sub(returndatasize(), add(o, 0x20)))) { - let n := min(mload(m), limit) // Truncate if needed. - mstore(m, n) // Overwrite the length. - returndatacopy(s, add(o, 0x20), n) // Copy the string's bytes. - mstore(add(s, n), 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, add(s, n))) // Allocate memory for the string. - result := m - break - } - } - } - // Try interpreting as a null-terminated string. - let n := min(returndatasize(), limit) // Truncate if needed. - returndatacopy(s, 0, n) // Copy the string's bytes. - mstore8(add(s, n), 0) // Place a '\0' at the end. - let i := s // Pointer to the next byte to scan. - for {} byte(0, mload(i)) { i := add(i, 1) } {} // Scan for '\0'. - mstore(m, sub(i, s)) // Store the string's length. - mstore(i, 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, i)) // Allocate memory for the string. - result := m - break - } - } - } - - /// @dev Attempts to read and return a uint at `target`. - function _uint(address target, bytes32 ptr, uint256 gasStipend) - private - view - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := - mul( - mload(0x20), - and( // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x1f), // At least 32 bytes returned. - staticcall(gasStipend, target, add(ptr, 0x20), mload(ptr), 0x20, 0x20) - ) - ) - } - } - - /// @dev Casts the function selector `s` into a pointer. - function _ptr(uint256 s) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - // Layout the calldata in the scratch space for temporary usage. - mstore(0x04, s) // Store the function selector. - mstore(result, 4) // Store the length. - } - } - - /// @dev Casts the `data` into a pointer. - function _ptr(bytes memory data) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := data - } - } -} diff --git a/grouperBot/lib/solady/src/utils/MinHeapLib.sol b/grouperBot/lib/solady/src/utils/MinHeapLib.sol deleted file mode 100644 index 404156f..0000000 --- a/grouperBot/lib/solady/src/utils/MinHeapLib.sol +++ /dev/null @@ -1,576 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for managing a min-heap in storage or memory. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MinHeapLib.sol) -library MinHeapLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The heap is empty. - error HeapIsEmpty(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A heap in storage. - struct Heap { - uint256[] data; - } - - /// @dev A heap in memory. - struct MemHeap { - uint256[] data; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Tips: - // - To use as a max-heap, bitwise negate the input and output values (e.g. `heap.push(~x)`). - // - To use on tuples, pack the tuple values into a single integer. - // - To use on signed integers, convert the signed integers into - // their ordered unsigned counterparts via `uint256(x) + (1 << 255)`. - - /// @dev Returns the minimum value of the heap. - /// Reverts if the heap is empty. - function root(Heap storage heap) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - if iszero(sload(heap.slot)) { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } - mstore(0x00, heap.slot) - result := sload(keccak256(0x00, 0x20)) - } - } - - /// @dev Returns the minimum value of the heap. - /// Reverts if the heap is empty. - function root(MemHeap memory heap) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(heap) - if iszero(mload(result)) { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } - result := mload(add(0x20, result)) - } - } - - /// @dev Reserves at least `minimum` slots of memory for the heap. - /// Helps avoid reallocation if you already know the max size of the heap. - function reserve(MemHeap memory heap, uint256 minimum) internal pure { - /// @solidity memory-safe-assembly - assembly { - let w := not(0x1f) - let prime := 204053801631428327883786711931463459222251954273621 - let cap := not(mload(add(mload(heap), w))) - if gt(minimum, mul(iszero(mod(cap, prime)), div(cap, prime))) { - let data := mload(heap) - let n := mload(data) - let newCap := and(add(minimum, 0x1f), w) // Round up to multiple of 32. - mstore(mload(0x40), not(mul(newCap, prime))) - let m := add(mload(0x40), 0x20) - mstore(m, n) // Store the length. - mstore(0x40, add(add(m, 0x20), shl(5, newCap))) // Allocate `heap.data` memory. - mstore(heap, m) // Update `heap.data`. - if n { - for { let i := shl(5, n) } 1 {} { - mstore(add(m, i), mload(add(data, i))) - i := add(i, w) - if iszero(i) { break } - } - } - } - } - } - - /// @dev Returns an array of the `k` smallest items in the heap, - /// sorted in ascending order, without modifying the heap. - /// If the heap has less than `k` items, all items in the heap will be returned. - function smallest(Heap storage heap, uint256 k) internal view returns (uint256[] memory a) { - /// @solidity memory-safe-assembly - assembly { - function pIndex(h_, p_) -> _i { - _i := mload(add(0x20, add(h_, shl(6, p_)))) - } - function pValue(h_, p_) -> _v { - _v := mload(add(h_, shl(6, p_))) - } - function pSet(h_, p_, i_, v_) { - mstore(add(h_, shl(6, p_)), v_) - mstore(add(0x20, add(h_, shl(6, p_))), i_) - } - function pSiftdown(h_, p_, i_, v_) { - for {} 1 {} { - let u_ := shr(1, sub(p_, 1)) - if iszero(mul(p_, lt(v_, pValue(h_, u_)))) { break } - pSet(h_, p_, pIndex(h_, u_), pValue(h_, u_)) - p_ := u_ - } - pSet(h_, p_, i_, v_) - } - function pSiftup(h_, e_, i_, v_) { - let p_ := 0 - for { let c_ := 1 } lt(c_, e_) { c_ := add(1, shl(1, p_)) } { - c_ := add(c_, gt(pValue(h_, c_), pValue(h_, add(c_, lt(add(c_, 1), e_))))) - pSet(h_, p_, pIndex(h_, c_), pValue(h_, c_)) - p_ := c_ - } - pSiftdown(h_, p_, i_, v_) - } - a := mload(0x40) - mstore(0x00, heap.slot) - let sOffset := keccak256(0x00, 0x20) - let o := add(a, 0x20) // Offset into `a`. - let n := sload(heap.slot) // The number of items in the heap. - let m := xor(n, mul(xor(n, k), lt(k, n))) // `min(k, n)`. - let h := add(o, shl(5, m)) // Priority queue. - pSet(h, 0, 0, sload(sOffset)) // Store the root into the priority queue. - for { let e := iszero(eq(o, h)) } e {} { - mstore(o, pValue(h, 0)) - o := add(0x20, o) - if eq(o, h) { break } - let childPos := add(shl(1, pIndex(h, 0)), 1) - if iszero(lt(childPos, n)) { - e := sub(e, 1) - pSiftup(h, e, pIndex(h, e), pValue(h, e)) - continue - } - pSiftup(h, e, childPos, sload(add(sOffset, childPos))) - childPos := add(1, childPos) - if iszero(eq(childPos, n)) { - pSiftdown(h, e, childPos, sload(add(sOffset, childPos))) - e := add(e, 1) - } - } - mstore(a, shr(5, sub(o, add(a, 0x20)))) // Store the length. - mstore(0x40, o) // Allocate memory. - } - } - - /// @dev Returns an array of the `k` smallest items in the heap, - /// sorted in ascending order, without modifying the heap. - /// If the heap has less than `k` items, all items in the heap will be returned. - function smallest(MemHeap memory heap, uint256 k) internal pure returns (uint256[] memory a) { - /// @solidity memory-safe-assembly - assembly { - function pIndex(h_, p_) -> _i { - _i := mload(add(0x20, add(h_, shl(6, p_)))) - } - function pValue(h_, p_) -> _v { - _v := mload(add(h_, shl(6, p_))) - } - function pSet(h_, p_, i_, v_) { - mstore(add(h_, shl(6, p_)), v_) - mstore(add(0x20, add(h_, shl(6, p_))), i_) - } - function pSiftdown(h_, p_, i_, v_) { - for {} 1 {} { - let u_ := shr(1, sub(p_, 1)) - if iszero(mul(p_, lt(v_, pValue(h_, u_)))) { break } - pSet(h_, p_, pIndex(h_, u_), pValue(h_, u_)) - p_ := u_ - } - pSet(h_, p_, i_, v_) - } - function pSiftup(h_, e_, i_, v_) { - let p_ := 0 - for { let c_ := 1 } lt(c_, e_) { c_ := add(1, shl(1, p_)) } { - c_ := add(c_, gt(pValue(h_, c_), pValue(h_, add(c_, lt(add(c_, 1), e_))))) - pSet(h_, p_, pIndex(h_, c_), pValue(h_, c_)) - p_ := c_ - } - pSiftdown(h_, p_, i_, v_) - } - a := mload(0x40) - let sOffset := add(mload(heap), 0x20) - let o := add(a, 0x20) // Offset into `a`. - let n := mload(mload(heap)) // The number of items in the heap. - let m := xor(n, mul(xor(n, k), lt(k, n))) // `min(k, n)`. - let h := add(o, shl(5, m)) // Priority queue. - pSet(h, 0, 0, mload(sOffset)) // Store the root into the priority queue. - for { let e := iszero(eq(o, h)) } e {} { - mstore(o, pValue(h, 0)) - o := add(0x20, o) - if eq(o, h) { break } - let childPos := add(shl(1, pIndex(h, 0)), 1) - if iszero(lt(childPos, n)) { - e := sub(e, 1) - pSiftup(h, e, pIndex(h, e), pValue(h, e)) - continue - } - pSiftup(h, e, childPos, mload(add(sOffset, shl(5, childPos)))) - childPos := add(1, childPos) - if iszero(eq(childPos, n)) { - pSiftdown(h, e, childPos, mload(add(sOffset, shl(5, childPos)))) - e := add(e, 1) - } - } - mstore(a, shr(5, sub(o, add(a, 0x20)))) // Store the length. - mstore(0x40, o) // Allocate memory. - } - } - - /// @dev Returns the number of items in the heap. - function length(Heap storage heap) internal view returns (uint256) { - return heap.data.length; - } - - /// @dev Returns the number of items in the heap. - function length(MemHeap memory heap) internal pure returns (uint256) { - return heap.data.length; - } - - /// @dev Pushes the `value` onto the min-heap. - function push(Heap storage heap, uint256 value) internal { - _set(heap, value, 0, 3); - } - - /// @dev Pushes the `value` onto the min-heap. - function push(MemHeap memory heap, uint256 value) internal pure { - _set(heap, value, 0, 3); - } - - /// @dev Pops the minimum value from the min-heap. - /// Reverts if the heap is empty. - function pop(Heap storage heap) internal returns (uint256 popped) { - (, popped) = _set(heap, 0, 0, 2); - } - - /// @dev Pops the minimum value from the min-heap. - /// Reverts if the heap is empty. - function pop(MemHeap memory heap) internal pure returns (uint256 popped) { - (, popped) = _set(heap, 0, 0, 2); - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value. - function pushPop(Heap storage heap, uint256 value) internal returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 4); - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value. - function pushPop(MemHeap memory heap, uint256 value) internal pure returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 4); - } - - /// @dev Pops the minimum value, and pushes the new `value` onto the min-heap. - /// Reverts if the heap is empty. - function replace(Heap storage heap, uint256 value) internal returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 1); - } - - /// @dev Pops the minimum value, and pushes the new `value` onto the min-heap. - /// Reverts if the heap is empty. - function replace(MemHeap memory heap, uint256 value) internal pure returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 1); - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value - /// if the length of the heap exceeds `maxLength`. - /// - /// Reverts if `maxLength` is zero. - /// - /// - If the queue is not full: - /// (`success` = true, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is not greater than the minimum value: - /// (`success` = false, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is greater than the minimum value: - /// (`success` = true, `hasPopped` = true, `popped` = ) - /// - /// Useful for implementing a bounded priority queue. - /// - /// It is technically possible for the heap size to exceed `maxLength` - /// if `enqueue` has been previously called with a larger `maxLength`. - /// In such a case, the heap will be treated exactly as if it is full, - /// conditionally popping the minimum value if `value` is greater than it. - /// - /// Under normal usage, which keeps `maxLength` constant throughout - /// the lifetime of a heap, this out-of-spec edge case will not be triggered. - function enqueue(Heap storage heap, uint256 value, uint256 maxLength) - internal - returns (bool success, bool hasPopped, uint256 popped) - { - (value, popped) = _set(heap, value, maxLength, 0); - /// @solidity memory-safe-assembly - assembly { - hasPopped := eq(3, value) - success := value - } - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value - /// if the length of the heap exceeds `maxLength`. - /// - /// Reverts if `maxLength` is zero. - /// - /// - If the queue is not full: - /// (`success` = true, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is not greater than the minimum value: - /// (`success` = false, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is greater than the minimum value: - /// (`success` = true, `hasPopped` = true, `popped` = ) - /// - /// Useful for implementing a bounded priority queue. - function enqueue(MemHeap memory heap, uint256 value, uint256 maxLength) - internal - pure - returns (bool success, bool hasPopped, uint256 popped) - { - (value, popped) = _set(heap, value, maxLength, 0); - /// @solidity memory-safe-assembly - assembly { - hasPopped := eq(3, value) - success := value - } - } - - /// @dev Increments the free memory pointer by a word and fills the word with 0. - /// This is if you want to take extra precaution that the memory word slot before - /// the `data` array in `MemHeap` doesn't contain a non-zero multiple of prime - /// to masquerade as a prime-checksummed capacity. - /// If you are not directly assigning some array to `data`, - /// you don't have to worry about it. - function bumpFreeMemoryPointer() internal pure { - uint256 zero; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, zero) - mstore(0x40, add(m, 0x20)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper function for heap operations. - /// Designed for code conciseness, bytecode compactness, and decent performance. - function _set(Heap storage heap, uint256 value, uint256 maxLength, uint256 mode) - private - returns (uint256 status, uint256 popped) - { - /// @solidity memory-safe-assembly - assembly { - let n := sload(heap.slot) - mstore(0x00, heap.slot) - let sOffset := keccak256(0x00, 0x20) // Array storage slot offset. - let pos := 0 - let childPos := not(0) - // Operations are ordered from most likely usage to least likely usage. - for {} 1 { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } { - // Mode: `enqueue`. - if iszero(mode) { - if iszero(maxLength) { continue } - // If queue is full. - if iszero(lt(n, maxLength)) { - let r := sload(sOffset) - if iszero(lt(r, value)) { break } - status := 3 - childPos := 1 - popped := r - break - } - status := 1 - pos := n - // Increment and update the length. - sstore(heap.slot, add(pos, 1)) - childPos := sOffset - break - } - if iszero(gt(mode, 2)) { - if iszero(n) { continue } - // Mode: `pop`. - if eq(mode, 2) { - // Decrement and update the length. - n := sub(n, 1) - sstore(heap.slot, n) - // Set the `value` to the last item. - value := sload(add(sOffset, n)) - popped := value - if iszero(n) { break } - } - // Mode: `replace`. - popped := sload(sOffset) - childPos := 1 - break - } - // Mode: `push`. - if eq(mode, 3) { - // Increment and update the length. - pos := n - sstore(heap.slot, add(pos, 1)) - // `sOffset` is used as a value that is `>= n` and `< not(0)`. - childPos := sOffset - break - } - // Mode: `pushPop`. - popped := value - if iszero(n) { break } - let r := sload(sOffset) - if iszero(lt(r, value)) { break } - popped := r - childPos := 1 - break - } - // Siftup. - for {} lt(childPos, n) {} { - let child := sload(add(sOffset, childPos)) - let rightPos := add(childPos, 1) - let right := sload(add(sOffset, rightPos)) - if iszero(gt(lt(rightPos, n), lt(child, right))) { - right := child - rightPos := childPos - } - sstore(add(sOffset, pos), right) - pos := rightPos - childPos := add(shl(1, pos), 1) - } - // Siftdown. - for {} pos {} { - let parentPos := shr(1, sub(pos, 1)) - let parent := sload(add(sOffset, parentPos)) - if iszero(lt(value, parent)) { break } - sstore(add(sOffset, pos), parent) - pos := parentPos - } - // If `childPos` has been changed from `not(0)`. - if add(childPos, 1) { sstore(add(sOffset, pos), value) } - } - } - - /// @dev Helper function for heap operations. - /// Designed for code conciseness, bytecode compactness, and decent performance. - function _set(MemHeap memory heap, uint256 value, uint256 maxLength, uint256 mode) - private - pure - returns (uint256 status, uint256 popped) - { - /// @solidity memory-safe-assembly - assembly { - let data := mload(heap) - let n := mload(data) - // Allocation / reallocation. - for { - let cap := not(mload(sub(data, 0x20))) - let prime := 204053801631428327883786711931463459222251954273621 - cap := mul(iszero(mod(cap, prime)), div(cap, prime)) - } iszero(lt(n, cap)) {} { - let newCap := add(add(cap, cap), shl(5, iszero(cap))) - if iszero(or(cap, iszero(n))) { - for { cap := n } iszero(gt(newCap, n)) {} { newCap := add(newCap, newCap) } - } - mstore(mload(0x40), not(mul(newCap, prime))) // Update `heap.capacity`. - let m := add(mload(0x40), 0x20) - mstore(m, n) // Store the length. - mstore(0x40, add(add(m, 0x20), shl(5, newCap))) // Allocate `heap.data` memory. - if cap { - let w := not(0x1f) - for { let i := shl(5, cap) } 1 {} { - mstore(add(m, i), mload(add(data, i))) - i := add(i, w) - if iszero(i) { break } - } - } - mstore(heap, m) // Update `heap.data`. - data := m - break - } - let sOffset := add(data, 0x20) // Array memory offset. - let pos := 0 - let childPos := not(0) - // Operations are ordered from most likely usage to least likely usage. - for {} 1 { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } { - // Mode: `enqueue`. - if iszero(mode) { - if iszero(maxLength) { continue } - // If the queue is full. - if iszero(lt(n, maxLength)) { - if iszero(lt(mload(sOffset), value)) { break } - status := 3 - childPos := 1 - popped := mload(sOffset) - break - } - status := 1 - pos := n - // Increment and update the length. - mstore(data, add(pos, 1)) - childPos := 0xff0000000000000000 - break - } - if iszero(gt(mode, 2)) { - if iszero(n) { continue } - // Mode: `pop`. - if eq(mode, 2) { - // Decrement and update the length. - n := sub(n, 1) - mstore(data, n) - // Set the `value` to the last item. - value := mload(add(sOffset, shl(5, n))) - popped := value - if iszero(n) { break } - } - // Mode: `replace`. - popped := mload(sOffset) - childPos := 1 - break - } - // Mode: `push`. - if eq(mode, 3) { - // Increment and update the length. - pos := n - mstore(data, add(pos, 1)) - childPos := 0xff0000000000000000 - break - } - // Mode: `pushPop`. - if iszero(mul(n, lt(mload(sOffset), value))) { - popped := value - break - } - popped := mload(sOffset) - childPos := 1 - break - } - // Siftup. - for {} lt(childPos, n) {} { - let child := mload(add(sOffset, shl(5, childPos))) - let rightPos := add(childPos, 1) - let right := mload(add(sOffset, shl(5, rightPos))) - if iszero(gt(lt(rightPos, n), lt(child, right))) { - mstore(add(sOffset, shl(5, pos)), child) - pos := childPos - childPos := add(shl(1, pos), 1) - continue - } - mstore(add(sOffset, shl(5, pos)), right) - pos := rightPos - childPos := add(shl(1, pos), 1) - } - // Siftdown. - for {} pos {} { - let parentPos := shr(1, sub(pos, 1)) - let parent := mload(add(sOffset, shl(5, parentPos))) - if iszero(lt(value, parent)) { break } - mstore(add(sOffset, shl(5, pos)), parent) - pos := parentPos - } - // If `childPos` has been changed from `not(0)`. - if iszero(shr(128, childPos)) { mstore(add(sOffset, shl(5, pos)), value) } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/Multicallable.sol b/grouperBot/lib/solady/src/utils/Multicallable.sol deleted file mode 100644 index 06af372..0000000 --- a/grouperBot/lib/solady/src/utils/Multicallable.sol +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Contract that enables a single call to call multiple methods on itself. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Multicallable.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Multicallable.sol) -/// -/// WARNING: -/// This implementation is NOT to be used with ERC2771 out-of-the-box. -/// https://blog.openzeppelin.com/arbitrary-address-spoofing-vulnerability-erc2771context-multicall-public-disclosure -/// This also applies to potentially other ERCs / patterns appending to the back of calldata. -/// -/// We do NOT have a check for ERC2771, as we do not inherit from OpenZeppelin's context. -/// Moreover, it is infeasible and inefficient for us to add checks and mitigations -/// for all possible ERC / patterns appending to the back of calldata. -/// -/// We would highly recommend using an alternative pattern such as -/// https://github.com/Vectorized/multicaller -/// which is more flexible, futureproof, and safer by default. -abstract contract Multicallable { - /// @dev Apply `delegatecall` with the current contract to each calldata in `data`, - /// and store the `abi.encode` formatted results of each `delegatecall` into `results`. - /// If any of the `delegatecall`s reverts, the entire context is reverted, - /// and the error is bubbled up. - /// - /// By default, this function directly returns the results and terminates the call context. - /// If you need to add before and after actions to the multicall, please override this function. - function multicall(bytes[] calldata data) public payable virtual returns (bytes[] memory) { - // Revert if `msg.value` is non-zero by default to guard against double-spending. - // (See: https://www.paradigm.xyz/2021/08/two-rights-might-make-a-wrong) - // - // If you really need to pass in a `msg.value`, then you will have to - // override this function and add in any relevant before and after checks. - if (msg.value != 0) revert(); - // `_multicallDirectReturn` returns the results directly and terminates the call context. - _multicallDirectReturn(_multicall(data)); - } - - /// @dev The inner logic of `multicall`. - /// This function is included so that you can override `multicall` - /// to add before and after actions, and use the `_multicallDirectReturn` function. - function _multicall(bytes[] calldata data) internal virtual returns (bytes32 results) { - /// @solidity memory-safe-assembly - assembly { - results := mload(0x40) - mstore(results, 0x20) - mstore(add(0x20, results), data.length) - let c := add(0x40, results) - let s := c - let end := shl(5, data.length) - calldatacopy(c, data.offset, end) - end := add(c, end) - let m := end - if data.length { - for {} 1 {} { - let o := add(data.offset, mload(c)) - calldatacopy(m, add(o, 0x20), calldataload(o)) - // forgefmt: disable-next-item - if iszero(delegatecall(gas(), address(), m, calldataload(o), codesize(), 0x00)) { - // Bubble up the revert if the delegatecall reverts. - returndatacopy(results, 0x00, returndatasize()) - revert(results, returndatasize()) - } - mstore(c, sub(m, s)) - c := add(0x20, c) - // Append the `returndatasize()`, and the return data. - mstore(m, returndatasize()) - let b := add(m, 0x20) - returndatacopy(b, 0x00, returndatasize()) - // Advance `m` by `returndatasize() + 0x20`, - // rounded up to the next multiple of 32. - m := and(add(add(b, returndatasize()), 0x1f), 0xffffffffffffffe0) - mstore(add(b, returndatasize()), 0) // Zeroize the slot after the returndata. - if iszero(lt(c, end)) { break } - } - } - mstore(0x40, m) // Allocate memory. - results := or(shl(64, sub(m, results)), results) // Pack the bytes length into `results`. - } - } - - /// @dev Decodes the `results` into an array of bytes. - /// This can be useful if you need to access the results or re-encode it. - function _multicallResultsToBytesArray(bytes32 results) - internal - pure - virtual - returns (bytes[] memory decoded) - { - /// @solidity memory-safe-assembly - assembly { - decoded := mload(0x40) - let c := and(0xffffffffffffffff, results) // Extract the offset. - mstore(decoded, mload(add(c, 0x20))) // Store the length. - let o := add(decoded, 0x20) // Start of elements in `decoded`. - let end := add(o, shl(5, mload(decoded))) - mstore(0x40, end) // Allocate memory. - let s := add(c, 0x40) // Start of elements in `results`. - let d := sub(s, o) // Difference between input and output pointers. - for {} iszero(eq(o, end)) { o := add(o, 0x20) } { mstore(o, add(mload(add(d, o)), s)) } - } - } - - /// @dev Directly returns the `results` and terminates the current call context. - /// `results` must be from `_multicall`, else behavior is undefined. - function _multicallDirectReturn(bytes32 results) internal pure virtual { - /// @solidity memory-safe-assembly - assembly { - return(and(0xffffffffffffffff, results), shr(64, results)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/P256.sol b/grouperBot/lib/solady/src/utils/P256.sol deleted file mode 100644 index 57419e1..0000000 --- a/grouperBot/lib/solady/src/utils/P256.sol +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Gas optimized P256 wrapper. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/P256.sol) -/// @author Modified from Daimo P256 Verifier (https://github.com/daimo-eth/p256-verifier/blob/master/src/P256.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/P256.sol) -library P256 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Address of the Solidity P256 verifier. - /// Please make sure the contract is deployed onto the chain you are working on. - /// See: https://gist.github.com/Vectorized/599b0d8a94d21bc74700eb1354e2f55c - /// Unlike RIP-7212, this verifier returns `uint256(0)` on failure, to - /// facilitate easier existence check. This verifier will also never revert. - address internal constant VERIFIER = 0x000000000000D01eA45F9eFD5c54f037Fa57Ea1a; - - /// @dev The existence of this contract, as determined by non-empty bytecode, - /// implies the existence of the RIP-7212 precompile. - /// See: https://gist.github.com/Vectorized/3c69dcf4604b9e1216525cabcd06ee34 - /// This is to enable the optimization to skip the `VERIFIER` entirely - /// when the `RIP_PRECOMPILE` returns empty returndata for an invalid signature. - address internal constant CANARY = 0x0000000000001Ab2e8006Fd8B71907bf06a5BDEE; - - /// @dev Address of the RIP-7212 P256 verifier precompile. - /// Currently, we don't support EIP-7212's precompile at 0x0b as it has not been finalized. - /// See: https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md - address internal constant RIP_PRECOMPILE = 0x0000000000000000000000000000000000000100; - - /// @dev The order of the secp256r1 elliptic curve. - uint256 internal constant N = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551; - - /// @dev `N/2`. Used for checking the malleability of the signature. - uint256 private constant _HALF_N = - 0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* P256 VERIFICATION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns if the signature (`r`, `s`) is valid for `hash` and public key (`x`, `y`). - /// Does NOT include the malleability check. - function verifySignatureAllowMalleability( - bytes32 hash, - bytes32 r, - bytes32 s, - bytes32 x, - bytes32 y - ) internal view returns (bool isValid) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, hash) - mstore(add(m, 0x20), r) - mstore(add(m, 0x40), s) - mstore(add(m, 0x60), x) - mstore(add(m, 0x80), y) - mstore(0x00, 0) // Zeroize the return slot before the staticcalls. - pop(staticcall(gas(), RIP_PRECOMPILE, m, 0xa0, 0x00, 0x20)) - // RIP-7212 dictates that success returns `uint256(1)`. - // But failure returns zero returndata, which is ambiguous. - if iszero(returndatasize()) { - if iszero(extcodesize(CANARY)) { - // The verifier will never revert when given sufficient gas. - // The `invalid` upon `staticcall` failure is solely for gas estimation. - if iszero(staticcall(gas(), VERIFIER, m, 0xa0, 0x00, 0x20)) { invalid() } - } - // Unlike RIP-7212, the verifier returns `uint256(0)` on failure. - // We shall not revert even if the verifier does not exist, - // to allow for workflows where reverting can cause trouble. - } - isValid := eq(1, mload(0x00)) - } - } - - /// @dev Returns if the signature (`r`, `s`) is valid for `hash` and public key (`x`, `y`). - /// Includes the malleability check. - function verifySignature(bytes32 hash, bytes32 r, bytes32 s, bytes32 x, bytes32 y) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, hash) - mstore(add(m, 0x20), r) - mstore(add(m, 0x40), s) - mstore(add(m, 0x60), x) - mstore(add(m, 0x80), y) - mstore(0x00, 0) // Zeroize the return slot before the staticcalls. - pop(staticcall(gas(), RIP_PRECOMPILE, m, 0xa0, 0x00, 0x20)) - // RIP-7212 dictates that success returns `uint256(1)`. - // But failure returns zero returndata, which is ambiguous. - if iszero(returndatasize()) { - if iszero(extcodesize(CANARY)) { - // The verifier will never revert when given sufficient gas. - // The `invalid` upon `staticcall` failure is solely for gas estimation. - if iszero(staticcall(gas(), VERIFIER, m, 0xa0, 0x00, 0x20)) { invalid() } - } - // Unlike RIP-7212, the verifier returns `uint256(0)` on failure. - // We shall not revert even if the verifier does not exist, - // to allow for workflows where reverting can cause trouble. - } - // Optimize for happy path. Users are unlikely to pass in malleable signatures. - isValid := lt(gt(s, _HALF_N), eq(1, mload(0x00))) - } - } - - /// @dev Returns if the RIP-7212 precompile exists. - function hasPrecompile() internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - // These values are taken from the standard Wycheproof test vectors. - // https://github.com/C2SP/wycheproof/blob/aca47066256c167f0ce04d611d718cc85654341e/testvectors/ecdsa_webcrypto_test.json#L1197 - mstore(m, 0x532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25) // `hash`. - mstore(add(m, 0x20), 0x5) // `r`. - mstore(add(m, 0x40), 0x1) // `s`. - mstore(add(m, 0x60), 0x4a03ef9f92eb268cafa601072489a56380fa0dc43171d7712813b3a19a1eb5e5) // `x`. - mstore(add(m, 0x80), 0x3e213e28a608ce9a2f4a17fd830c6654018a79b3e0263d91a8ba90622df6f2f0) // `y`. - // The `invalid` upon `staticcall` failure is solely for gas estimation. - if iszero(staticcall(gas(), RIP_PRECOMPILE, m, 0xa0, m, 0x20)) { invalid() } - result := eq(1, mload(m)) - } - } - - /// @dev Returns if either the RIP-7212 precompile or the verifier exists. - /// Since `verifySignature` is made not reverting, this function can be used to - /// manually implement a revert if the current chain does not have the contracts - /// to support secp256r1 signature recovery. - function hasPrecompileOrVerifier() internal view returns (bool result) { - result = hasPrecompile(); - /// @solidity memory-safe-assembly - assembly { - result := iszero(iszero(or(result, extcodesize(VERIFIER)))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `s` normalized to the lower half of the curve. - function normalized(bytes32 s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := xor(s, mul(xor(sub(N, s), s), gt(s, _HALF_N))) - } - } - - /// @dev Helper function for `abi.decode(encoded, (bytes32, bytes32))`. - /// If `encoded.length < 64`, `(x, y)` will be `(0, 0)`, which is an invalid point. - function tryDecodePoint(bytes memory encoded) internal pure returns (bytes32 x, bytes32 y) { - /// @solidity memory-safe-assembly - assembly { - let t := gt(mload(encoded), 0x3f) - x := mul(mload(add(encoded, 0x20)), t) - y := mul(mload(add(encoded, 0x40)), t) - } - } - - /// @dev Helper function for `abi.decode(encoded, (bytes32, bytes32))`. - /// If `encoded.length < 64`, `(x, y)` will be `(0, 0)`, which is an invalid point. - function tryDecodePointCalldata(bytes calldata encoded) - internal - pure - returns (bytes32 x, bytes32 y) - { - /// @solidity memory-safe-assembly - assembly { - let t := gt(encoded.length, 0x3f) - x := mul(calldataload(encoded.offset), t) - y := mul(calldataload(add(encoded.offset, 0x20)), t) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/RedBlackTreeLib.sol b/grouperBot/lib/solady/src/utils/RedBlackTreeLib.sol deleted file mode 100644 index d0b55b1..0000000 --- a/grouperBot/lib/solady/src/utils/RedBlackTreeLib.sol +++ /dev/null @@ -1,718 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for managing a red-black-tree in storage. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/RedBlackTreeLib.sol) -/// @author Modified from BokkyPooBahsRedBlackTreeLibrary (https://github.com/bokkypoobah/BokkyPooBahsRedBlackTreeLibrary) -/// @dev This implementation does not support the zero (i.e. empty) value. -/// This implementation supports up to 2147483647 values. -library RedBlackTreeLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The value cannot be zero. - error ValueIsEmpty(); - - /// @dev Cannot insert a value that already exists. - error ValueAlreadyExists(); - - /// @dev Cannot remove a value that does not exist. - error ValueDoesNotExist(); - - /// @dev The pointer is out of bounds. - error PointerOutOfBounds(); - - /// @dev The tree is full. - error TreeIsFull(); - - /// @dev `bytes4(keccak256(bytes("ValueAlreadyExists()")))`. - uint256 internal constant ERROR_VALUE_ALREADY_EXISTS = 0xbb33e6ac; - - /// @dev `bytes4(keccak256(bytes("ValueDoesNotExist()")))`. - uint256 internal constant ERROR_VALUE_DOES_NOT_EXISTS = 0xb113638a; - - /// @dev `bytes4(keccak256(bytes("PointerOutOfBounds()")))`. - uint256 internal constant ERROR_POINTER_OUT_OF_BOUNDS = 0xccd52fbc; - - /// @dev `bytes4(keccak256(bytes("TreeIsFull()")))`. - uint256 internal constant ERROR_TREE_IS_FULL = 0xed732d0c; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A red-black-tree in storage. - struct Tree { - uint256 _spacer; - } - - // Custom storage: - // ``` - // mstore(0x20, tree.slot) - // mstore(0x00, _NODES_SLOT_SEED) - // let nodes := shl(_NODES_SLOT_SHIFT, keccak256(0x00, 0x40)) - // - // let root := shr(128, sload(nodes)) - // let totalNodes := and(sload(nodes), _BITMASK_KEY) - // - // let nodePacked := sload(or(nodes, nodeIndex)) - // let nodeLeft := and(nodePacked, _BITMASK_KEY) - // let nodeRight := and(shr(_BITPOS_RIGHT, nodePacked), _BITMASK_KEY) - // let nodeParent := and(shr(_BITPOS_PARENT, nodePacked), _BITMASK_KEY) - // let nodeRed := and(shr(_BITPOS_RED, nodePacked), 1) - // - // let nodeValue := shr(_BITPOS_PACKED_VALUE, nodePacked) - // if iszero(nodeValue) { - // nodeValue := sload(or(_BIT_FULL_VALUE_SLOT, or(nodes, nodeIndex))) - // } - // ``` - // - // Bits Layout of the Root Index Slot: - // - [0..30] `totalNodes` - // - [128..159] `rootNodeIndex` - // - // Bits Layout of a Node: - // - [0..30] `leftChildIndex` - // - [31..61] `rightChildIndex` - // - [62..92] `parentIndex` - // - [93] `isRed` - // - [96..255] `nodePackedValue` - - uint256 private constant _NODES_SLOT_SEED = 0x1dc27bb5462fdadcb; - uint256 private constant _NODES_SLOT_SHIFT = 32; - uint256 private constant _BITMASK_KEY = (1 << 31) - 1; - uint256 private constant _BITPOS_LEFT = 0; - uint256 private constant _BITPOS_RIGHT = 31; - uint256 private constant _BITPOS_PARENT = 31 * 2; - uint256 private constant _BITPOS_RED = 31 * 3; - uint256 private constant _BITMASK_RED = 1 << (31 * 3); - uint256 private constant _BITPOS_PACKED_VALUE = 96; - uint256 private constant _BITMASK_PACKED_VALUE = (1 << 160) - 1; - uint256 private constant _BIT_FULL_VALUE_SLOT = 1 << 31; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of unique values in the tree. - function size(Tree storage tree) internal view returns (uint256 result) { - uint256 nodes = _nodes(tree); - /// @solidity memory-safe-assembly - assembly { - result := and(sload(nodes), _BITMASK_KEY) - } - } - - /// @dev Returns an array of all the values in the tree in ascending sorted order. - /// WARNING! This function can exhaust the block gas limit if the tree is big. - /// It is intended for usage in off-chain view functions. - function values(Tree storage tree) internal view returns (uint256[] memory result) { - uint256 nodes = _nodes(tree); - /// @solidity memory-safe-assembly - assembly { - function visit(current_) { - if iszero(current_) { leave } // If the current node is null, leave. - current_ := or(mload(0x00), current_) // Current node's storage slot. - let packed_ := sload(current_) - visit(and(packed_, _BITMASK_KEY)) // Visit left child. - let value_ := shr(_BITPOS_PACKED_VALUE, packed_) // Current value. - if iszero(value_) { value_ := sload(or(current_, _BIT_FULL_VALUE_SLOT)) } - mstore(mload(0x20), value_) // Append the value to `results`. - mstore(0x20, add(0x20, mload(0x20))) // Advance the offset into `results`. - visit(and(shr(_BITPOS_RIGHT, packed_), _BITMASK_KEY)) // Visit right child. - } - result := mload(0x40) - let rootPacked := sload(nodes) - mstore(result, and(rootPacked, _BITMASK_KEY)) // Length of `result`. - mstore(0x00, nodes) // Cache the nodes pointer in scratch space. - mstore(0x20, add(result, 0x20)) // Cache the offset into `results` in scratch space. - mstore(0x40, add(mload(0x20), shl(5, mload(result)))) // Allocate memory. - visit(shr(128, rootPacked)) // Start the tree traversal from the root node. - } - } - - /// @dev Returns a pointer to the value `x`. - /// If the value `x` is not in the tree, the returned pointer will be empty. - function find(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes,, uint256 key) = _find(tree, x); - result = _pack(nodes, key); - } - - /// @dev Returns a pointer to the nearest value to `x`. - /// In a tie-breaker, the returned pointer will point to the smaller value. - /// If the tree is empty, the returned pointer will be empty. - function nearest(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - unchecked { - if (cursor == uint256(0)) return result; // Nothing found -- empty tree. - if (key != uint256(0)) return _pack(nodes, key); // Exact match. - bytes32 a = _pack(nodes, cursor); - uint256 aValue = value(a); - bytes32 b = x < aValue ? prev(a) : next(a); - if (b == bytes32(0)) return a; // Only node found. - uint256 bValue = value(b); - uint256 aDist = x < aValue ? aValue - x : x - aValue; - uint256 bDist = x < bValue ? bValue - x : x - bValue; - return (aDist == bDist ? aValue < bValue : aDist < bDist) ? a : b; - } - } - - /// @dev Returns a pointer to the nearest value lesser or equal to `x`. - /// If there is no value lesser or equal to `x`, the returned pointer will be empty. - function nearestBefore(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - if (cursor == uint256(0)) return result; // Nothing found -- empty tree. - if (key != uint256(0)) return _pack(nodes, key); // Exact match. - bytes32 a = _pack(nodes, cursor); - return value(a) < x ? a : prev(a); - } - - /// @dev Returns a pointer to the nearest value greater or equal to `x`. - /// If there is no value greater or equal to `x`, the returned pointer will be empty. - function nearestAfter(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - if (cursor == uint256(0)) return result; // Nothing found -- empty tree. - if (key != uint256(0)) return _pack(nodes, key); // Exact match. - bytes32 a = _pack(nodes, cursor); - return value(a) > x ? a : next(a); - } - - /// @dev Returns whether the value `x` exists. - function exists(Tree storage tree, uint256 x) internal view returns (bool result) { - (,, uint256 key) = _find(tree, x); - result = key != 0; - } - - /// @dev Inserts the value `x` into the tree. - /// Reverts if the value `x` already exists. - function insert(Tree storage tree, uint256 x) internal { - uint256 err = tryInsert(tree, x); - if (err != 0) _revert(err); - } - - /// @dev Inserts the value `x` into the tree. - /// Returns a non-zero error code upon failure instead of reverting - /// (except for reverting if `x` is an empty value). - function tryInsert(Tree storage tree, uint256 x) internal returns (uint256 err) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - err = _update(nodes, cursor, key, x, 0); - } - - /// @dev Removes the value `x` from the tree. - /// Reverts if the value does not exist. - function remove(Tree storage tree, uint256 x) internal { - uint256 err = tryRemove(tree, x); - if (err != 0) _revert(err); - } - - /// @dev Removes the value `x` from the tree. - /// Returns a non-zero error code upon failure instead of reverting - /// (except for reverting if `x` is an empty value). - function tryRemove(Tree storage tree, uint256 x) internal returns (uint256 err) { - (uint256 nodes,, uint256 key) = _find(tree, x); - err = _update(nodes, 0, key, 0, 1); - } - - /// @dev Removes the value at pointer `ptr` from the tree. - /// Reverts if `ptr` is empty (i.e. value does not exist), - /// or if `ptr` is out of bounds. - /// After removal, `ptr` may point to another existing value. - /// For safety, do not reuse `ptr` after calling remove on it. - function remove(bytes32 ptr) internal { - uint256 err = tryRemove(ptr); - if (err != 0) _revert(err); - } - - /// @dev Removes the value at pointer `ptr` from the tree. - /// Returns a non-zero error code upon failure instead of reverting. - function tryRemove(bytes32 ptr) internal returns (uint256 err) { - (uint256 nodes, uint256 key) = _unpack(ptr); - err = _update(nodes, 0, key, 0, 1); - } - - /// @dev Returns the value at pointer `ptr`. - /// If `ptr` is empty, the result will be zero. - function value(bytes32 ptr) internal view returns (uint256 result) { - if (ptr == bytes32(0)) return result; - /// @solidity memory-safe-assembly - assembly { - let packed := sload(ptr) - result := shr(_BITPOS_PACKED_VALUE, packed) - if iszero(result) { result := sload(or(ptr, _BIT_FULL_VALUE_SLOT)) } - } - } - - /// @dev Returns a pointer to the smallest value in the tree. - /// If the tree is empty, the returned pointer will be empty. - function first(Tree storage tree) internal view returns (bytes32 result) { - result = _end(tree, _BITPOS_LEFT); - } - - /// @dev Returns a pointer to the largest value in the tree. - /// If the tree is empty, the returned pointer will be empty. - function last(Tree storage tree) internal view returns (bytes32 result) { - result = _end(tree, _BITPOS_RIGHT); - } - - /// @dev Returns the pointer to the next largest value. - /// If there is no next value, or if `ptr` is empty, - /// the returned pointer will be empty. - function next(bytes32 ptr) internal view returns (bytes32 result) { - result = _step(ptr, _BITPOS_LEFT, _BITPOS_RIGHT); - } - - /// @dev Returns the pointer to the next smallest value. - /// If there is no previous value, or if `ptr` is empty, - /// the returned pointer will be empty. - function prev(bytes32 ptr) internal view returns (bytes32 result) { - result = _step(ptr, _BITPOS_RIGHT, _BITPOS_LEFT); - } - - /// @dev Returns whether the pointer is empty. - function isEmpty(bytes32 ptr) internal pure returns (bool result) { - result = ptr == bytes32(0); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unpacks the pointer `ptr` to its components. - function _unpack(bytes32 ptr) private pure returns (uint256 nodes, uint256 key) { - /// @solidity memory-safe-assembly - assembly { - nodes := shl(_NODES_SLOT_SHIFT, shr(_NODES_SLOT_SHIFT, ptr)) - key := and(_BITMASK_KEY, ptr) - } - } - - /// @dev Packs `nodes` and `key` into a single pointer. - function _pack(uint256 nodes, uint256 key) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mul(or(nodes, key), iszero(iszero(key))) - } - } - - /// @dev Returns the pointer to either end of the tree. - function _end(Tree storage tree, uint256 L) private view returns (bytes32 result) { - uint256 nodes = _nodes(tree); - /// @solidity memory-safe-assembly - assembly { - result := shr(128, sload(nodes)) - if result { - for {} 1 {} { - let packed := sload(or(nodes, result)) - let left := and(shr(L, packed), _BITMASK_KEY) - if iszero(left) { break } - result := left - } - } - } - result = _pack(nodes, uint256(result)); - } - - /// @dev Step the pointer `ptr` forwards or backwards. - function _step(bytes32 ptr, uint256 L, uint256 R) private view returns (bytes32 result) { - if (ptr == bytes32(0)) return ptr; - (uint256 nodes, uint256 target) = _unpack(ptr); - /// @solidity memory-safe-assembly - assembly { - let packed := sload(ptr) - for { result := and(shr(R, packed), _BITMASK_KEY) } 1 {} { - if iszero(result) { - result := and(shr(_BITPOS_PARENT, packed), _BITMASK_KEY) - for {} 1 {} { - if iszero(result) { break } - packed := sload(or(nodes, result)) - if iszero(eq(target, and(shr(R, packed), _BITMASK_KEY))) { break } - target := result - result := and(shr(_BITPOS_PARENT, packed), _BITMASK_KEY) - } - break - } - for {} 1 {} { - packed := sload(or(nodes, result)) - let left := and(shr(L, packed), _BITMASK_KEY) - if iszero(left) { break } - result := left - } - break - } - } - result = _pack(nodes, uint256(result)); - } - - /// @dev Inserts or delete the value `x` from the tree. - function _update(uint256 nodes, uint256 cursor, uint256 key, uint256 x, uint256 mode) - private - returns (uint256 err) - { - /// @solidity memory-safe-assembly - assembly { - function getKey(packed_, bitpos_) -> index_ { - index_ := and(_BITMASK_KEY, shr(bitpos_, packed_)) - } - - function setKey(packed_, bitpos_, key_) -> result_ { - result_ := or(and(not(shl(bitpos_, _BITMASK_KEY)), packed_), shl(bitpos_, key_)) - } - - function rotate(nodes_, key_, L, R) { - let packed_ := sload(or(nodes_, key_)) - let cursor_ := getKey(packed_, R) - let parent_ := getKey(packed_, _BITPOS_PARENT) - let cursorPacked_ := sload(or(nodes_, cursor_)) - let cursorLeft_ := getKey(cursorPacked_, L) - - if cursorLeft_ { - let s_ := or(nodes_, cursorLeft_) - sstore(s_, setKey(sload(s_), _BITPOS_PARENT, key_)) - } - - for {} 1 {} { - if iszero(parent_) { - mstore(0x00, cursor_) - break - } - let s_ := or(nodes_, parent_) - let parentPacked_ := sload(s_) - if eq(key_, getKey(parentPacked_, L)) { - sstore(s_, setKey(parentPacked_, L, cursor_)) - break - } - sstore(s_, setKey(parentPacked_, R, cursor_)) - break - } - packed_ := setKey(packed_, R, cursorLeft_) - sstore(or(nodes_, key_), setKey(packed_, _BITPOS_PARENT, cursor_)) - cursorPacked_ := setKey(cursorPacked_, _BITPOS_PARENT, parent_) - sstore(or(nodes_, cursor_), setKey(cursorPacked_, L, key_)) - } - - function insert(nodes_, cursor_, key_, x_) -> err_ { - if key_ { - err_ := ERROR_VALUE_ALREADY_EXISTS - leave - } - - let totalNodes_ := add(shr(128, mload(0x20)), 1) - if gt(totalNodes_, _BITMASK_KEY) { - err_ := ERROR_TREE_IS_FULL - leave - } - - mstore(0x20, shl(128, totalNodes_)) - - { - let packed_ := or(_BITMASK_RED, shl(_BITPOS_PARENT, cursor_)) - let nodePointer_ := or(nodes_, totalNodes_) - - for {} 1 {} { - if iszero(gt(x_, _BITMASK_PACKED_VALUE)) { - packed_ := or(shl(_BITPOS_PACKED_VALUE, x_), packed_) - break - } - sstore(or(nodePointer_, _BIT_FULL_VALUE_SLOT), x_) - break - } - sstore(nodePointer_, packed_) - - for {} 1 {} { - if iszero(cursor_) { - mstore(0x00, totalNodes_) - break - } - let s_ := or(nodes_, cursor_) - let cPacked_ := sload(s_) - let cValue_ := shr(_BITPOS_PACKED_VALUE, cPacked_) - if iszero(cValue_) { cValue_ := sload(or(s_, _BIT_FULL_VALUE_SLOT)) } - if iszero(lt(x_, cValue_)) { - sstore(s_, setKey(cPacked_, _BITPOS_RIGHT, totalNodes_)) - break - } - sstore(s_, setKey(cPacked_, _BITPOS_LEFT, totalNodes_)) - break - } - } - - // Insert fixup workflow: - - key_ := totalNodes_ - let BR := _BITMASK_RED - for {} iszero(eq(key_, mload(0x00))) {} { - let packed_ := sload(or(nodes_, key_)) - let parent_ := getKey(packed_, _BITPOS_PARENT) - let parentPacked_ := sload(or(nodes_, parent_)) - if iszero(and(BR, parentPacked_)) { break } - - let grandParent_ := getKey(parentPacked_, _BITPOS_PARENT) - let grandParentPacked_ := sload(or(nodes_, grandParent_)) - - let R := mul(eq(parent_, getKey(grandParentPacked_, 0)), _BITPOS_RIGHT) - let L := xor(R, _BITPOS_RIGHT) - - let c_ := getKey(grandParentPacked_, R) - let cPacked_ := sload(or(nodes_, c_)) - if iszero(and(BR, cPacked_)) { - if eq(key_, getKey(parentPacked_, R)) { - key_ := parent_ - rotate(nodes_, key_, L, R) - parent_ := getKey(sload(or(nodes_, key_)), _BITPOS_PARENT) - parentPacked_ := sload(or(nodes_, parent_)) - } - sstore(or(nodes_, parent_), and(parentPacked_, not(BR))) - let s_ := or(nodes_, grandParent_) - sstore(s_, or(sload(s_), BR)) - rotate(nodes_, grandParent_, R, L) - break - } - sstore(or(nodes_, parent_), and(parentPacked_, not(BR))) - sstore(or(nodes_, c_), and(cPacked_, not(BR))) - sstore(or(nodes_, grandParent_), or(grandParentPacked_, BR)) - key_ := grandParent_ - } - let root_ := or(nodes_, mload(0x00)) - sstore(root_, and(sload(root_), not(BR))) - } - - function removeFixup(nodes_, key_) { - let BR := _BITMASK_RED - for {} iszero(eq(key_, mload(0x00))) {} { - let packed_ := sload(or(nodes_, key_)) - if and(BR, packed_) { break } - - let parent_ := getKey(packed_, _BITPOS_PARENT) - let parentPacked_ := sload(or(nodes_, parent_)) - - let R := mul(eq(key_, getKey(parentPacked_, 0)), _BITPOS_RIGHT) - let L := xor(R, _BITPOS_RIGHT) - - let cursor_ := getKey(parentPacked_, R) - let cursorPacked_ := sload(or(nodes_, cursor_)) - - if and(BR, cursorPacked_) { - sstore(or(nodes_, cursor_), and(cursorPacked_, not(BR))) - sstore(or(nodes_, parent_), or(parentPacked_, BR)) - rotate(nodes_, parent_, L, R) - cursor_ := getKey(sload(or(nodes_, parent_)), R) - cursorPacked_ := sload(or(nodes_, cursor_)) - } - - let cursorLeft_ := getKey(cursorPacked_, L) - let cursorLeftPacked_ := sload(or(nodes_, cursorLeft_)) - let cursorRight_ := getKey(cursorPacked_, R) - let cursorRightPacked_ := sload(or(nodes_, cursorRight_)) - - if iszero(and(BR, or(cursorLeftPacked_, cursorRightPacked_))) { - sstore(or(nodes_, cursor_), or(cursorPacked_, BR)) - key_ := parent_ - continue - } - - if iszero(and(BR, cursorRightPacked_)) { - sstore(or(nodes_, cursorLeft_), and(cursorLeftPacked_, not(BR))) - sstore(or(nodes_, cursor_), or(cursorPacked_, BR)) - rotate(nodes_, cursor_, R, L) - cursor_ := getKey(sload(or(nodes_, parent_)), R) - cursorPacked_ := sload(or(nodes_, cursor_)) - cursorRight_ := getKey(cursorPacked_, R) - cursorRightPacked_ := sload(or(nodes_, cursorRight_)) - } - - parentPacked_ := sload(or(nodes_, parent_)) - // forgefmt: disable-next-item - sstore(or(nodes_, cursor_), xor(cursorPacked_, and(BR, xor(cursorPacked_, parentPacked_)))) - sstore(or(nodes_, parent_), and(parentPacked_, not(BR))) - sstore(or(nodes_, cursorRight_), and(cursorRightPacked_, not(BR))) - rotate(nodes_, parent_, L, R) - break - } - sstore(or(nodes_, key_), and(sload(or(nodes_, key_)), not(BR))) - } - - function replaceParent(nodes_, parent_, a_, b_) { - if iszero(parent_) { - mstore(0x00, a_) - leave - } - let s_ := or(nodes_, parent_) - let p_ := sload(s_) - let t_ := iszero(eq(b_, getKey(p_, _BITPOS_LEFT))) - sstore(s_, setKey(p_, mul(t_, _BITPOS_RIGHT), a_)) - } - - // In `remove`, the parent of the null value (index 0) may be temporarily set - // to a non-zero value. This is an optimization that unifies the removal cases. - function remove(nodes_, key_) -> err_ { - if gt(key_, shr(128, mload(0x20))) { - err_ := ERROR_POINTER_OUT_OF_BOUNDS - leave - } - if iszero(key_) { - err_ := ERROR_VALUE_DOES_NOT_EXISTS - leave - } - - let cursor_ := key_ - { - let packed_ := sload(or(nodes_, key_)) - let left_ := getKey(packed_, _BITPOS_LEFT) - let right_ := getKey(packed_, _BITPOS_RIGHT) - if mul(left_, right_) { - for { cursor_ := right_ } 1 {} { - let cursorLeft_ := getKey(sload(or(nodes_, cursor_)), _BITPOS_LEFT) - if iszero(cursorLeft_) { break } - cursor_ := cursorLeft_ - } - } - } - - let cursorPacked_ := sload(or(nodes_, cursor_)) - let probe_ := getKey(cursorPacked_, _BITPOS_LEFT) - probe_ := getKey(cursorPacked_, mul(iszero(probe_), _BITPOS_RIGHT)) - - let yParent_ := getKey(cursorPacked_, _BITPOS_PARENT) - let probeSlot_ := or(nodes_, probe_) - sstore(probeSlot_, setKey(sload(probeSlot_), _BITPOS_PARENT, yParent_)) - replaceParent(nodes_, yParent_, probe_, cursor_) - - if iszero(eq(cursor_, key_)) { - let packed_ := sload(or(nodes_, key_)) - replaceParent(nodes_, getKey(packed_, _BITPOS_PARENT), cursor_, key_) - - let leftSlot_ := or(nodes_, getKey(packed_, _BITPOS_LEFT)) - sstore(leftSlot_, setKey(sload(leftSlot_), _BITPOS_PARENT, cursor_)) - - let rightSlot_ := or(nodes_, getKey(packed_, _BITPOS_RIGHT)) - sstore(rightSlot_, setKey(sload(rightSlot_), _BITPOS_PARENT, cursor_)) - - // Copy `left`, `right`, `red` from `key_` to `cursor_`. - // forgefmt: disable-next-item - sstore(or(nodes_, cursor_), xor(cursorPacked_, - and(xor(packed_, cursorPacked_), sub(shl(_BITPOS_PACKED_VALUE, 1), 1)))) - - let t_ := cursor_ - cursor_ := key_ - key_ := t_ - } - - if iszero(and(_BITMASK_RED, cursorPacked_)) { removeFixup(nodes_, probe_) } - - // Remove last workflow: - - let last_ := shr(128, mload(0x20)) - let lastPacked_ := sload(or(nodes_, last_)) - let lastValue_ := shr(_BITPOS_PACKED_VALUE, lastPacked_) - let lastFullValue_ := 0 - if iszero(lastValue_) { - lastValue_ := sload(or(_BIT_FULL_VALUE_SLOT, or(nodes_, last_))) - lastFullValue_ := lastValue_ - } - - let cursorValue_ := shr(_BITPOS_PACKED_VALUE, sload(or(nodes_, cursor_))) - let cursorFullValue_ := 0 - if iszero(cursorValue_) { - cursorValue_ := sload(or(_BIT_FULL_VALUE_SLOT, or(nodes_, cursor_))) - cursorFullValue_ := cursorValue_ - } - - if iszero(eq(lastValue_, cursorValue_)) { - sstore(or(nodes_, cursor_), lastPacked_) - if iszero(eq(lastFullValue_, cursorFullValue_)) { - sstore(or(_BIT_FULL_VALUE_SLOT, or(nodes_, cursor_)), lastFullValue_) - } - for { let lastParent_ := getKey(lastPacked_, _BITPOS_PARENT) } 1 {} { - if iszero(lastParent_) { - mstore(0x00, cursor_) - break - } - let s_ := or(nodes_, lastParent_) - let p_ := sload(s_) - let t_ := iszero(eq(last_, getKey(p_, _BITPOS_LEFT))) - sstore(s_, setKey(p_, mul(t_, _BITPOS_RIGHT), cursor_)) - break - } - let lastRight_ := getKey(lastPacked_, _BITPOS_RIGHT) - if lastRight_ { - let s_ := or(nodes_, lastRight_) - sstore(s_, setKey(sload(s_), _BITPOS_PARENT, cursor_)) - } - let lastLeft_ := getKey(lastPacked_, _BITPOS_LEFT) - if lastLeft_ { - let s_ := or(nodes_, lastLeft_) - sstore(s_, setKey(sload(s_), _BITPOS_PARENT, cursor_)) - } - } - sstore(or(nodes_, last_), 0) - if lastFullValue_ { sstore(or(_BIT_FULL_VALUE_SLOT, or(nodes_, last_)), 0) } - - mstore(0x20, shl(128, sub(last_, 1))) - } - - mstore(0x00, codesize()) // Zeroize the first 0x10 bytes. - mstore(0x10, sload(nodes)) - - for {} 1 {} { - if iszero(mode) { - err := insert(nodes, cursor, key, x) - break - } - err := remove(nodes, key) - break - } - - sstore(nodes, mload(0x10)) - } - } - - /// @dev Returns the pointer to the `nodes` for the tree. - function _nodes(Tree storage tree) private pure returns (uint256 nodes) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, tree.slot) - mstore(0x00, _NODES_SLOT_SEED) - nodes := shl(_NODES_SLOT_SHIFT, keccak256(0x00, 0x40)) - } - } - - /// @dev Finds `x` in `tree`. The `key` will be zero if `x` is not found. - function _find(Tree storage tree, uint256 x) - private - view - returns (uint256 nodes, uint256 cursor, uint256 key) - { - if (x == uint256(0)) _revert(0xc94f1877); // `ValueIsEmpty()`. - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, tree.slot) - mstore(0x00, _NODES_SLOT_SEED) - nodes := shl(_NODES_SLOT_SHIFT, keccak256(0x00, 0x40)) - // Layout scratch space so that `mload(0x00) == 0`, `mload(0x01) == _BITPOS_RIGHT`. - mstore(0x01, _BITPOS_RIGHT) // `_BITPOS_RIGHT` is 31. - for { let probe := shr(128, sload(nodes)) } probe {} { - cursor := probe - let nodePacked := sload(or(nodes, probe)) - let nodeValue := shr(_BITPOS_PACKED_VALUE, nodePacked) - if iszero(nodeValue) { - nodeValue := sload(or(or(nodes, probe), _BIT_FULL_VALUE_SLOT)) - } - if eq(nodeValue, x) { - key := cursor - break - } - probe := and(shr(mload(gt(x, nodeValue)), nodePacked), _BITMASK_KEY) - } - } - } - - /// @dev Helper to revert `err` efficiently. - function _revert(uint256 err) private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, err) - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ReentrancyGuard.sol b/grouperBot/lib/solady/src/utils/ReentrancyGuard.sol deleted file mode 100644 index 0ea63f1..0000000 --- a/grouperBot/lib/solady/src/utils/ReentrancyGuard.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Reentrancy guard mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ReentrancyGuard.sol) -abstract contract ReentrancyGuard { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unauthorized reentrant call. - error Reentrancy(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to: `uint72(bytes9(keccak256("_REENTRANCY_GUARD_SLOT")))`. - /// 9 bytes is large enough to avoid collisions with lower slots, - /// but not too large to result in excessive bytecode bloat. - uint256 private constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* REENTRANCY GUARD */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Guards a function from reentrancy. - modifier nonReentrant() virtual { - /// @solidity memory-safe-assembly - assembly { - if eq(sload(_REENTRANCY_GUARD_SLOT), address()) { - mstore(0x00, 0xab143c06) // `Reentrancy()`. - revert(0x1c, 0x04) - } - sstore(_REENTRANCY_GUARD_SLOT, address()) - } - _; - /// @solidity memory-safe-assembly - assembly { - sstore(_REENTRANCY_GUARD_SLOT, codesize()) - } - } - - /// @dev Guards a view function from read-only reentrancy. - modifier nonReadReentrant() virtual { - /// @solidity memory-safe-assembly - assembly { - if eq(sload(_REENTRANCY_GUARD_SLOT), address()) { - mstore(0x00, 0xab143c06) // `Reentrancy()`. - revert(0x1c, 0x04) - } - } - _; - } -} diff --git a/grouperBot/lib/solady/src/utils/ReentrancyGuardTransient.sol b/grouperBot/lib/solady/src/utils/ReentrancyGuardTransient.sol deleted file mode 100644 index 3192549..0000000 --- a/grouperBot/lib/solady/src/utils/ReentrancyGuardTransient.sol +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -/// @notice Reentrancy guard mixin (transient storage variant). -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ReentrancyGuardTransient.sol) -/// -/// @dev Note: This implementation utilizes the `TSTORE` and `TLOAD` opcodes. -/// Please ensure that the chain you are deploying on supports them. -abstract contract ReentrancyGuardTransient { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unauthorized reentrant call. - error Reentrancy(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to: `uint32(bytes4(keccak256("Reentrancy()"))) | 1 << 71`. - /// 9 bytes is large enough to avoid collisions in practice, - /// but not too large to result in excessive bytecode bloat. - uint256 private constant _REENTRANCY_GUARD_SLOT = 0x8000000000ab143c06; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* REENTRANCY GUARD */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Guards a function from reentrancy. - modifier nonReentrant() virtual { - if (_useTransientReentrancyGuardOnlyOnMainnet()) { - uint256 s = _REENTRANCY_GUARD_SLOT; - if (block.chainid == 1) { - /// @solidity memory-safe-assembly - assembly { - if tload(s) { - mstore(0x00, s) // `Reentrancy()`. - revert(0x1c, 0x04) - } - tstore(s, address()) - } - } else { - /// @solidity memory-safe-assembly - assembly { - if eq(sload(s), address()) { - mstore(0x00, s) // `Reentrancy()`. - revert(0x1c, 0x04) - } - sstore(s, address()) - } - } - } else { - /// @solidity memory-safe-assembly - assembly { - if tload(_REENTRANCY_GUARD_SLOT) { - mstore(0x00, 0xab143c06) // `Reentrancy()`. - revert(0x1c, 0x04) - } - tstore(_REENTRANCY_GUARD_SLOT, address()) - } - } - _; - if (_useTransientReentrancyGuardOnlyOnMainnet()) { - uint256 s = _REENTRANCY_GUARD_SLOT; - if (block.chainid == 1) { - /// @solidity memory-safe-assembly - assembly { - tstore(s, 0) - } - } else { - /// @solidity memory-safe-assembly - assembly { - sstore(s, s) - } - } - } else { - /// @solidity memory-safe-assembly - assembly { - tstore(_REENTRANCY_GUARD_SLOT, 0) - } - } - } - - /// @dev Guards a view function from read-only reentrancy. - modifier nonReadReentrant() virtual { - if (_useTransientReentrancyGuardOnlyOnMainnet()) { - uint256 s = _REENTRANCY_GUARD_SLOT; - if (block.chainid == 1) { - /// @solidity memory-safe-assembly - assembly { - if tload(s) { - mstore(0x00, s) // `Reentrancy()`. - revert(0x1c, 0x04) - } - } - } else { - /// @solidity memory-safe-assembly - assembly { - if eq(sload(s), address()) { - mstore(0x00, s) // `Reentrancy()`. - revert(0x1c, 0x04) - } - } - } - } else { - /// @solidity memory-safe-assembly - assembly { - if tload(_REENTRANCY_GUARD_SLOT) { - mstore(0x00, 0xab143c06) // `Reentrancy()`. - revert(0x1c, 0x04) - } - } - } - _; - } - - /// @dev For widespread compatibility with L2s. - /// Only Ethereum mainnet is expensive anyways. - function _useTransientReentrancyGuardOnlyOnMainnet() internal view virtual returns (bool) { - return true; - } -} diff --git a/grouperBot/lib/solady/src/utils/SSTORE2.sol b/grouperBot/lib/solady/src/utils/SSTORE2.sol deleted file mode 100644 index 1e760b7..0000000 --- a/grouperBot/lib/solady/src/utils/SSTORE2.sol +++ /dev/null @@ -1,259 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Read and write to persistent storage at a fraction of the cost. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SSTORE2.sol) -/// @author Saw-mon-and-Natalie (https://github.com/Saw-mon-and-Natalie) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol) -/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol) -/// @author Modified from SSTORE3 (https://github.com/Philogy/sstore3) -library SSTORE2 { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The proxy initialization code. - uint256 private constant _CREATE3_PROXY_INITCODE = 0x67363d3d37363d34f03d5260086018f3; - - /// @dev Hash of the `_CREATE3_PROXY_INITCODE`. - /// Equivalent to `keccak256(abi.encodePacked(hex"67363d3d37363d34f03d5260086018f3"))`. - bytes32 internal constant CREATE3_PROXY_INITCODE_HASH = - 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unable to deploy the storage contract. - error DeploymentFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* WRITE LOGIC */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Writes `data` into the bytecode of a storage contract and returns its address. - function write(bytes memory data) internal returns (address pointer) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(data) // Let `l` be `n + 1`. +1 as we prefix a STOP opcode. - /** - * ---------------------------------------------------+ - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------| - * 61 l | PUSH2 l | l | | - * 80 | DUP1 | l l | | - * 60 0xa | PUSH1 0xa | 0xa l l | | - * 3D | RETURNDATASIZE | 0 0xa l l | | - * 39 | CODECOPY | l | [0..l): code | - * 3D | RETURNDATASIZE | 0 l | [0..l): code | - * F3 | RETURN | | [0..l): code | - * 00 | STOP | | | - * ---------------------------------------------------+ - * @dev Prefix the bytecode with a STOP opcode to ensure it cannot be called. - * Also PUSH2 is used since max contract size cap is 24,576 bytes which is less than 2 ** 16. - */ - // Do a out-of-gas revert if `n + 1` is more than 2 bytes. - mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n))) - // Deploy a new contract with the generated creation code. - pointer := create(0, add(data, 0x15), add(n, 0xb)) - if iszero(pointer) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(data, n) // Restore the length of `data`. - } - } - - /// @dev Writes `data` into the bytecode of a storage contract with `salt` - /// and returns its normal CREATE2 deterministic address. - function writeCounterfactual(bytes memory data, bytes32 salt) - internal - returns (address pointer) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(data) - // Do a out-of-gas revert if `n + 1` is more than 2 bytes. - mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n))) - // Deploy a new contract with the generated creation code. - pointer := create2(0, add(data, 0x15), add(n, 0xb), salt) - if iszero(pointer) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(data, n) // Restore the length of `data`. - } - } - - /// @dev Writes `data` into the bytecode of a storage contract and returns its address. - /// This uses the so-called "CREATE3" workflow, - /// which means that `pointer` is agnostic to `data, and only depends on `salt`. - function writeDeterministic(bytes memory data, bytes32 salt) - internal - returns (address pointer) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(data) - mstore(0x00, _CREATE3_PROXY_INITCODE) // Store the `_PROXY_INITCODE`. - let proxy := create2(0, 0x10, 0x10, salt) - if iszero(proxy) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(0x14, proxy) // Store the proxy's address. - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01). - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex). - mstore(0x00, 0xd694) - mstore8(0x34, 0x01) // Nonce of the proxy contract (1). - pointer := keccak256(0x1e, 0x17) - - // Do a out-of-gas revert if `n + 1` is more than 2 bytes. - mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n))) - if iszero( - mul( // The arguments of `mul` are evaluated last to first. - extcodesize(pointer), - call(gas(), proxy, 0, add(data, 0x15), add(n, 0xb), codesize(), 0x00) - ) - ) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - mstore(data, n) // Restore the length of `data`. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ADDRESS CALCULATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the initialization code hash of the storage contract for `data`. - /// Used for mining vanity addresses with create2crunch. - function initCodeHash(bytes memory data) internal pure returns (bytes32 hash) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(data) - // Do a out-of-gas revert if `n + 1` is more than 2 bytes. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0xfffe)) - mstore(data, add(0x61000180600a3d393df300, shl(0x40, n))) - hash := keccak256(add(data, 0x15), add(n, 0xb)) - mstore(data, n) // Restore the length of `data`. - } - } - - /// @dev Equivalent to `predictCounterfactualAddress(data, salt, address(this))` - function predictCounterfactualAddress(bytes memory data, bytes32 salt) - internal - view - returns (address pointer) - { - pointer = predictCounterfactualAddress(data, salt, address(this)); - } - - /// @dev Returns the CREATE2 address of the storage contract for `data` - /// deployed with `salt` by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictCounterfactualAddress(bytes memory data, bytes32 salt, address deployer) - internal - pure - returns (address predicted) - { - bytes32 hash = initCodeHash(data); - /// @solidity memory-safe-assembly - assembly { - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, hash) - mstore(0x01, shl(96, deployer)) - mstore(0x15, salt) - predicted := keccak256(0x00, 0x55) - // Restore the part of the free memory pointer that has been overwritten. - mstore(0x35, 0) - } - } - - /// @dev Equivalent to `predictDeterministicAddress(salt, address(this))`. - function predictDeterministicAddress(bytes32 salt) internal view returns (address pointer) { - pointer = predictDeterministicAddress(salt, address(this)); - } - - /// @dev Returns the "CREATE3" deterministic address for `salt` with `deployer`. - function predictDeterministicAddress(bytes32 salt, address deployer) - internal - pure - returns (address pointer) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, deployer) // Store `deployer`. - mstore8(0x0b, 0xff) // Store the prefix. - mstore(0x20, salt) // Store the salt. - mstore(0x40, CREATE3_PROXY_INITCODE_HASH) // Store the bytecode hash. - - mstore(0x14, keccak256(0x0b, 0x55)) // Store the proxy's address. - mstore(0x40, m) // Restore the free memory pointer. - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01). - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex). - mstore(0x00, 0xd694) - mstore8(0x34, 0x01) // Nonce of the proxy contract (1). - pointer := keccak256(0x1e, 0x17) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* READ LOGIC */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Equivalent to `read(pointer, 0, 2 ** 256 - 1)`. - function read(address pointer) internal view returns (bytes memory data) { - /// @solidity memory-safe-assembly - assembly { - data := mload(0x40) - let n := and(0xffffffffff, sub(extcodesize(pointer), 0x01)) - extcodecopy(pointer, add(data, 0x1f), 0x00, add(n, 0x21)) - mstore(data, n) // Store the length. - mstore(0x40, add(n, add(data, 0x40))) // Allocate memory. - } - } - - /// @dev Equivalent to `read(pointer, start, 2 ** 256 - 1)`. - function read(address pointer, uint256 start) internal view returns (bytes memory data) { - /// @solidity memory-safe-assembly - assembly { - data := mload(0x40) - let n := and(0xffffffffff, sub(extcodesize(pointer), 0x01)) - let l := sub(n, and(0xffffff, mul(lt(start, n), start))) - extcodecopy(pointer, add(data, 0x1f), start, add(l, 0x21)) - mstore(data, mul(sub(n, start), lt(start, n))) // Store the length. - mstore(0x40, add(data, add(0x40, mload(data)))) // Allocate memory. - } - } - - /// @dev Returns a slice of the data on `pointer` from `start` to `end`. - /// `start` and `end` will be clamped to the range `[0, args.length]`. - /// The `pointer` MUST be deployed via the SSTORE2 write functions. - /// Otherwise, the behavior is undefined. - /// Out-of-gas reverts if `pointer` does not have any code. - function read(address pointer, uint256 start, uint256 end) - internal - view - returns (bytes memory data) - { - /// @solidity memory-safe-assembly - assembly { - data := mload(0x40) - if iszero(lt(end, 0xffff)) { end := 0xffff } - let d := mul(sub(end, start), lt(start, end)) - extcodecopy(pointer, add(data, 0x1f), start, add(d, 0x01)) - if iszero(and(0xff, mload(add(data, d)))) { - let n := sub(extcodesize(pointer), 0x01) - returndatacopy(returndatasize(), returndatasize(), shr(40, n)) - d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n)))) - } - mstore(data, d) // Store the length. - mstore(add(add(data, 0x20), d), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(data, 0x40), d)) // Allocate memory. - } - } -} diff --git a/grouperBot/lib/solady/src/utils/SafeCastLib.sol b/grouperBot/lib/solady/src/utils/SafeCastLib.sol deleted file mode 100644 index 1fbcb61..0000000 --- a/grouperBot/lib/solady/src/utils/SafeCastLib.sol +++ /dev/null @@ -1,673 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Safe integer casting library that reverts on overflow. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeCastLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol) -/// @dev Optimized for runtime gas for very high number of optimizer runs (i.e. >= 1000000). -library SafeCastLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unable to cast to the target type due to overflow. - error Overflow(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UNSIGNED INTEGER SAFE CASTING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Casts `x` to a uint8. Reverts on overflow. - function toUint8(uint256 x) internal pure returns (uint8) { - if (x >= 1 << 8) _revertOverflow(); - return uint8(x); - } - - /// @dev Casts `x` to a uint16. Reverts on overflow. - function toUint16(uint256 x) internal pure returns (uint16) { - if (x >= 1 << 16) _revertOverflow(); - return uint16(x); - } - - /// @dev Casts `x` to a uint24. Reverts on overflow. - function toUint24(uint256 x) internal pure returns (uint24) { - if (x >= 1 << 24) _revertOverflow(); - return uint24(x); - } - - /// @dev Casts `x` to a uint32. Reverts on overflow. - function toUint32(uint256 x) internal pure returns (uint32) { - if (x >= 1 << 32) _revertOverflow(); - return uint32(x); - } - - /// @dev Casts `x` to a uint40. Reverts on overflow. - function toUint40(uint256 x) internal pure returns (uint40) { - if (x >= 1 << 40) _revertOverflow(); - return uint40(x); - } - - /// @dev Casts `x` to a uint48. Reverts on overflow. - function toUint48(uint256 x) internal pure returns (uint48) { - if (x >= 1 << 48) _revertOverflow(); - return uint48(x); - } - - /// @dev Casts `x` to a uint56. Reverts on overflow. - function toUint56(uint256 x) internal pure returns (uint56) { - if (x >= 1 << 56) _revertOverflow(); - return uint56(x); - } - - /// @dev Casts `x` to a uint64. Reverts on overflow. - function toUint64(uint256 x) internal pure returns (uint64) { - if (x >= 1 << 64) _revertOverflow(); - return uint64(x); - } - - /// @dev Casts `x` to a uint72. Reverts on overflow. - function toUint72(uint256 x) internal pure returns (uint72) { - if (x >= 1 << 72) _revertOverflow(); - return uint72(x); - } - - /// @dev Casts `x` to a uint80. Reverts on overflow. - function toUint80(uint256 x) internal pure returns (uint80) { - if (x >= 1 << 80) _revertOverflow(); - return uint80(x); - } - - /// @dev Casts `x` to a uint88. Reverts on overflow. - function toUint88(uint256 x) internal pure returns (uint88) { - if (x >= 1 << 88) _revertOverflow(); - return uint88(x); - } - - /// @dev Casts `x` to a uint96. Reverts on overflow. - function toUint96(uint256 x) internal pure returns (uint96) { - if (x >= 1 << 96) _revertOverflow(); - return uint96(x); - } - - /// @dev Casts `x` to a uint104. Reverts on overflow. - function toUint104(uint256 x) internal pure returns (uint104) { - if (x >= 1 << 104) _revertOverflow(); - return uint104(x); - } - - /// @dev Casts `x` to a uint112. Reverts on overflow. - function toUint112(uint256 x) internal pure returns (uint112) { - if (x >= 1 << 112) _revertOverflow(); - return uint112(x); - } - - /// @dev Casts `x` to a uint120. Reverts on overflow. - function toUint120(uint256 x) internal pure returns (uint120) { - if (x >= 1 << 120) _revertOverflow(); - return uint120(x); - } - - /// @dev Casts `x` to a uint128. Reverts on overflow. - function toUint128(uint256 x) internal pure returns (uint128) { - if (x >= 1 << 128) _revertOverflow(); - return uint128(x); - } - - /// @dev Casts `x` to a uint136. Reverts on overflow. - function toUint136(uint256 x) internal pure returns (uint136) { - if (x >= 1 << 136) _revertOverflow(); - return uint136(x); - } - - /// @dev Casts `x` to a uint144. Reverts on overflow. - function toUint144(uint256 x) internal pure returns (uint144) { - if (x >= 1 << 144) _revertOverflow(); - return uint144(x); - } - - /// @dev Casts `x` to a uint152. Reverts on overflow. - function toUint152(uint256 x) internal pure returns (uint152) { - if (x >= 1 << 152) _revertOverflow(); - return uint152(x); - } - - /// @dev Casts `x` to a uint160. Reverts on overflow. - function toUint160(uint256 x) internal pure returns (uint160) { - if (x >= 1 << 160) _revertOverflow(); - return uint160(x); - } - - /// @dev Casts `x` to a uint168. Reverts on overflow. - function toUint168(uint256 x) internal pure returns (uint168) { - if (x >= 1 << 168) _revertOverflow(); - return uint168(x); - } - - /// @dev Casts `x` to a uint176. Reverts on overflow. - function toUint176(uint256 x) internal pure returns (uint176) { - if (x >= 1 << 176) _revertOverflow(); - return uint176(x); - } - - /// @dev Casts `x` to a uint184. Reverts on overflow. - function toUint184(uint256 x) internal pure returns (uint184) { - if (x >= 1 << 184) _revertOverflow(); - return uint184(x); - } - - /// @dev Casts `x` to a uint192. Reverts on overflow. - function toUint192(uint256 x) internal pure returns (uint192) { - if (x >= 1 << 192) _revertOverflow(); - return uint192(x); - } - - /// @dev Casts `x` to a uint200. Reverts on overflow. - function toUint200(uint256 x) internal pure returns (uint200) { - if (x >= 1 << 200) _revertOverflow(); - return uint200(x); - } - - /// @dev Casts `x` to a uint208. Reverts on overflow. - function toUint208(uint256 x) internal pure returns (uint208) { - if (x >= 1 << 208) _revertOverflow(); - return uint208(x); - } - - /// @dev Casts `x` to a uint216. Reverts on overflow. - function toUint216(uint256 x) internal pure returns (uint216) { - if (x >= 1 << 216) _revertOverflow(); - return uint216(x); - } - - /// @dev Casts `x` to a uint224. Reverts on overflow. - function toUint224(uint256 x) internal pure returns (uint224) { - if (x >= 1 << 224) _revertOverflow(); - return uint224(x); - } - - /// @dev Casts `x` to a uint232. Reverts on overflow. - function toUint232(uint256 x) internal pure returns (uint232) { - if (x >= 1 << 232) _revertOverflow(); - return uint232(x); - } - - /// @dev Casts `x` to a uint240. Reverts on overflow. - function toUint240(uint256 x) internal pure returns (uint240) { - if (x >= 1 << 240) _revertOverflow(); - return uint240(x); - } - - /// @dev Casts `x` to a uint248. Reverts on overflow. - function toUint248(uint256 x) internal pure returns (uint248) { - if (x >= 1 << 248) _revertOverflow(); - return uint248(x); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* SIGNED INTEGER SAFE CASTING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Casts `x` to a int8. Reverts on overflow. - function toInt8(int256 x) internal pure returns (int8) { - unchecked { - if (((1 << 7) + uint256(x)) >> 8 == uint256(0)) return int8(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int16. Reverts on overflow. - function toInt16(int256 x) internal pure returns (int16) { - unchecked { - if (((1 << 15) + uint256(x)) >> 16 == uint256(0)) return int16(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int24. Reverts on overflow. - function toInt24(int256 x) internal pure returns (int24) { - unchecked { - if (((1 << 23) + uint256(x)) >> 24 == uint256(0)) return int24(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int32. Reverts on overflow. - function toInt32(int256 x) internal pure returns (int32) { - unchecked { - if (((1 << 31) + uint256(x)) >> 32 == uint256(0)) return int32(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int40. Reverts on overflow. - function toInt40(int256 x) internal pure returns (int40) { - unchecked { - if (((1 << 39) + uint256(x)) >> 40 == uint256(0)) return int40(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int48. Reverts on overflow. - function toInt48(int256 x) internal pure returns (int48) { - unchecked { - if (((1 << 47) + uint256(x)) >> 48 == uint256(0)) return int48(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int56. Reverts on overflow. - function toInt56(int256 x) internal pure returns (int56) { - unchecked { - if (((1 << 55) + uint256(x)) >> 56 == uint256(0)) return int56(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int64. Reverts on overflow. - function toInt64(int256 x) internal pure returns (int64) { - unchecked { - if (((1 << 63) + uint256(x)) >> 64 == uint256(0)) return int64(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int72. Reverts on overflow. - function toInt72(int256 x) internal pure returns (int72) { - unchecked { - if (((1 << 71) + uint256(x)) >> 72 == uint256(0)) return int72(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int80. Reverts on overflow. - function toInt80(int256 x) internal pure returns (int80) { - unchecked { - if (((1 << 79) + uint256(x)) >> 80 == uint256(0)) return int80(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int88. Reverts on overflow. - function toInt88(int256 x) internal pure returns (int88) { - unchecked { - if (((1 << 87) + uint256(x)) >> 88 == uint256(0)) return int88(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int96. Reverts on overflow. - function toInt96(int256 x) internal pure returns (int96) { - unchecked { - if (((1 << 95) + uint256(x)) >> 96 == uint256(0)) return int96(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int104. Reverts on overflow. - function toInt104(int256 x) internal pure returns (int104) { - unchecked { - if (((1 << 103) + uint256(x)) >> 104 == uint256(0)) return int104(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int112. Reverts on overflow. - function toInt112(int256 x) internal pure returns (int112) { - unchecked { - if (((1 << 111) + uint256(x)) >> 112 == uint256(0)) return int112(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int120. Reverts on overflow. - function toInt120(int256 x) internal pure returns (int120) { - unchecked { - if (((1 << 119) + uint256(x)) >> 120 == uint256(0)) return int120(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int128. Reverts on overflow. - function toInt128(int256 x) internal pure returns (int128) { - unchecked { - if (((1 << 127) + uint256(x)) >> 128 == uint256(0)) return int128(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int136. Reverts on overflow. - function toInt136(int256 x) internal pure returns (int136) { - unchecked { - if (((1 << 135) + uint256(x)) >> 136 == uint256(0)) return int136(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int144. Reverts on overflow. - function toInt144(int256 x) internal pure returns (int144) { - unchecked { - if (((1 << 143) + uint256(x)) >> 144 == uint256(0)) return int144(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int152. Reverts on overflow. - function toInt152(int256 x) internal pure returns (int152) { - unchecked { - if (((1 << 151) + uint256(x)) >> 152 == uint256(0)) return int152(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int160. Reverts on overflow. - function toInt160(int256 x) internal pure returns (int160) { - unchecked { - if (((1 << 159) + uint256(x)) >> 160 == uint256(0)) return int160(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int168. Reverts on overflow. - function toInt168(int256 x) internal pure returns (int168) { - unchecked { - if (((1 << 167) + uint256(x)) >> 168 == uint256(0)) return int168(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int176. Reverts on overflow. - function toInt176(int256 x) internal pure returns (int176) { - unchecked { - if (((1 << 175) + uint256(x)) >> 176 == uint256(0)) return int176(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int184. Reverts on overflow. - function toInt184(int256 x) internal pure returns (int184) { - unchecked { - if (((1 << 183) + uint256(x)) >> 184 == uint256(0)) return int184(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int192. Reverts on overflow. - function toInt192(int256 x) internal pure returns (int192) { - unchecked { - if (((1 << 191) + uint256(x)) >> 192 == uint256(0)) return int192(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int200. Reverts on overflow. - function toInt200(int256 x) internal pure returns (int200) { - unchecked { - if (((1 << 199) + uint256(x)) >> 200 == uint256(0)) return int200(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int208. Reverts on overflow. - function toInt208(int256 x) internal pure returns (int208) { - unchecked { - if (((1 << 207) + uint256(x)) >> 208 == uint256(0)) return int208(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int216. Reverts on overflow. - function toInt216(int256 x) internal pure returns (int216) { - unchecked { - if (((1 << 215) + uint256(x)) >> 216 == uint256(0)) return int216(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int224. Reverts on overflow. - function toInt224(int256 x) internal pure returns (int224) { - unchecked { - if (((1 << 223) + uint256(x)) >> 224 == uint256(0)) return int224(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int232. Reverts on overflow. - function toInt232(int256 x) internal pure returns (int232) { - unchecked { - if (((1 << 231) + uint256(x)) >> 232 == uint256(0)) return int232(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int240. Reverts on overflow. - function toInt240(int256 x) internal pure returns (int240) { - unchecked { - if (((1 << 239) + uint256(x)) >> 240 == uint256(0)) return int240(x); - _revertOverflow(); - } - } - - /// @dev Casts `x` to a int248. Reverts on overflow. - function toInt248(int256 x) internal pure returns (int248) { - unchecked { - if (((1 << 247) + uint256(x)) >> 248 == uint256(0)) return int248(x); - _revertOverflow(); - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER SAFE CASTING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Casts `x` to a int8. Reverts on overflow. - function toInt8(uint256 x) internal pure returns (int8) { - if (x >= 1 << 7) _revertOverflow(); - return int8(int256(x)); - } - - /// @dev Casts `x` to a int16. Reverts on overflow. - function toInt16(uint256 x) internal pure returns (int16) { - if (x >= 1 << 15) _revertOverflow(); - return int16(int256(x)); - } - - /// @dev Casts `x` to a int24. Reverts on overflow. - function toInt24(uint256 x) internal pure returns (int24) { - if (x >= 1 << 23) _revertOverflow(); - return int24(int256(x)); - } - - /// @dev Casts `x` to a int32. Reverts on overflow. - function toInt32(uint256 x) internal pure returns (int32) { - if (x >= 1 << 31) _revertOverflow(); - return int32(int256(x)); - } - - /// @dev Casts `x` to a int40. Reverts on overflow. - function toInt40(uint256 x) internal pure returns (int40) { - if (x >= 1 << 39) _revertOverflow(); - return int40(int256(x)); - } - - /// @dev Casts `x` to a int48. Reverts on overflow. - function toInt48(uint256 x) internal pure returns (int48) { - if (x >= 1 << 47) _revertOverflow(); - return int48(int256(x)); - } - - /// @dev Casts `x` to a int56. Reverts on overflow. - function toInt56(uint256 x) internal pure returns (int56) { - if (x >= 1 << 55) _revertOverflow(); - return int56(int256(x)); - } - - /// @dev Casts `x` to a int64. Reverts on overflow. - function toInt64(uint256 x) internal pure returns (int64) { - if (x >= 1 << 63) _revertOverflow(); - return int64(int256(x)); - } - - /// @dev Casts `x` to a int72. Reverts on overflow. - function toInt72(uint256 x) internal pure returns (int72) { - if (x >= 1 << 71) _revertOverflow(); - return int72(int256(x)); - } - - /// @dev Casts `x` to a int80. Reverts on overflow. - function toInt80(uint256 x) internal pure returns (int80) { - if (x >= 1 << 79) _revertOverflow(); - return int80(int256(x)); - } - - /// @dev Casts `x` to a int88. Reverts on overflow. - function toInt88(uint256 x) internal pure returns (int88) { - if (x >= 1 << 87) _revertOverflow(); - return int88(int256(x)); - } - - /// @dev Casts `x` to a int96. Reverts on overflow. - function toInt96(uint256 x) internal pure returns (int96) { - if (x >= 1 << 95) _revertOverflow(); - return int96(int256(x)); - } - - /// @dev Casts `x` to a int104. Reverts on overflow. - function toInt104(uint256 x) internal pure returns (int104) { - if (x >= 1 << 103) _revertOverflow(); - return int104(int256(x)); - } - - /// @dev Casts `x` to a int112. Reverts on overflow. - function toInt112(uint256 x) internal pure returns (int112) { - if (x >= 1 << 111) _revertOverflow(); - return int112(int256(x)); - } - - /// @dev Casts `x` to a int120. Reverts on overflow. - function toInt120(uint256 x) internal pure returns (int120) { - if (x >= 1 << 119) _revertOverflow(); - return int120(int256(x)); - } - - /// @dev Casts `x` to a int128. Reverts on overflow. - function toInt128(uint256 x) internal pure returns (int128) { - if (x >= 1 << 127) _revertOverflow(); - return int128(int256(x)); - } - - /// @dev Casts `x` to a int136. Reverts on overflow. - function toInt136(uint256 x) internal pure returns (int136) { - if (x >= 1 << 135) _revertOverflow(); - return int136(int256(x)); - } - - /// @dev Casts `x` to a int144. Reverts on overflow. - function toInt144(uint256 x) internal pure returns (int144) { - if (x >= 1 << 143) _revertOverflow(); - return int144(int256(x)); - } - - /// @dev Casts `x` to a int152. Reverts on overflow. - function toInt152(uint256 x) internal pure returns (int152) { - if (x >= 1 << 151) _revertOverflow(); - return int152(int256(x)); - } - - /// @dev Casts `x` to a int160. Reverts on overflow. - function toInt160(uint256 x) internal pure returns (int160) { - if (x >= 1 << 159) _revertOverflow(); - return int160(int256(x)); - } - - /// @dev Casts `x` to a int168. Reverts on overflow. - function toInt168(uint256 x) internal pure returns (int168) { - if (x >= 1 << 167) _revertOverflow(); - return int168(int256(x)); - } - - /// @dev Casts `x` to a int176. Reverts on overflow. - function toInt176(uint256 x) internal pure returns (int176) { - if (x >= 1 << 175) _revertOverflow(); - return int176(int256(x)); - } - - /// @dev Casts `x` to a int184. Reverts on overflow. - function toInt184(uint256 x) internal pure returns (int184) { - if (x >= 1 << 183) _revertOverflow(); - return int184(int256(x)); - } - - /// @dev Casts `x` to a int192. Reverts on overflow. - function toInt192(uint256 x) internal pure returns (int192) { - if (x >= 1 << 191) _revertOverflow(); - return int192(int256(x)); - } - - /// @dev Casts `x` to a int200. Reverts on overflow. - function toInt200(uint256 x) internal pure returns (int200) { - if (x >= 1 << 199) _revertOverflow(); - return int200(int256(x)); - } - - /// @dev Casts `x` to a int208. Reverts on overflow. - function toInt208(uint256 x) internal pure returns (int208) { - if (x >= 1 << 207) _revertOverflow(); - return int208(int256(x)); - } - - /// @dev Casts `x` to a int216. Reverts on overflow. - function toInt216(uint256 x) internal pure returns (int216) { - if (x >= 1 << 215) _revertOverflow(); - return int216(int256(x)); - } - - /// @dev Casts `x` to a int224. Reverts on overflow. - function toInt224(uint256 x) internal pure returns (int224) { - if (x >= 1 << 223) _revertOverflow(); - return int224(int256(x)); - } - - /// @dev Casts `x` to a int232. Reverts on overflow. - function toInt232(uint256 x) internal pure returns (int232) { - if (x >= 1 << 231) _revertOverflow(); - return int232(int256(x)); - } - - /// @dev Casts `x` to a int240. Reverts on overflow. - function toInt240(uint256 x) internal pure returns (int240) { - if (x >= 1 << 239) _revertOverflow(); - return int240(int256(x)); - } - - /// @dev Casts `x` to a int248. Reverts on overflow. - function toInt248(uint256 x) internal pure returns (int248) { - if (x >= 1 << 247) _revertOverflow(); - return int248(int256(x)); - } - - /// @dev Casts `x` to a int256. Reverts on overflow. - function toInt256(uint256 x) internal pure returns (int256) { - if (int256(x) >= 0) return int256(x); - _revertOverflow(); - } - - /// @dev Casts `x` to a uint256. Reverts on overflow. - function toUint256(int256 x) internal pure returns (uint256) { - if (x >= 0) return uint256(x); - _revertOverflow(); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - function _revertOverflow() private pure { - /// @solidity memory-safe-assembly - assembly { - // Store the function selector of `Overflow()`. - mstore(0x00, 0x35278d12) - // Revert with (offset, size). - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/SafeTransferLib.sol b/grouperBot/lib/solady/src/utils/SafeTransferLib.sol deleted file mode 100644 index 2e86732..0000000 --- a/grouperBot/lib/solady/src/utils/SafeTransferLib.sol +++ /dev/null @@ -1,683 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @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) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) -/// @author Permit2 operations from (https://github.com/Uniswap/permit2/blob/main/src/libraries/Permit2Lib.sol) -/// -/// @dev Note: -/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection. -library SafeTransferLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ETH transfer has failed. - error ETHTransferFailed(); - - /// @dev The ERC20 `transferFrom` has failed. - error TransferFromFailed(); - - /// @dev The ERC20 `transfer` has failed. - error TransferFailed(); - - /// @dev The ERC20 `approve` has failed. - error ApproveFailed(); - - /// @dev The ERC20 `totalSupply` query has failed. - error TotalSupplyQueryFailed(); - - /// @dev The Permit2 operation has failed. - error Permit2Failed(); - - /// @dev The Permit2 amount must be less than `2**160 - 1`. - error Permit2AmountOverflow(); - - /// @dev The Permit2 approve operation has failed. - error Permit2ApproveFailed(); - - /// @dev The Permit2 lockdown operation has failed. - error Permit2LockdownFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes. - uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300; - - /// @dev Suggested gas stipend for contract receiving ETH to perform a few - /// storage reads and writes, but low enough to prevent griefing. - uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000; - - /// @dev The unique EIP-712 domain separator for the DAI token contract. - bytes32 internal constant DAI_DOMAIN_SEPARATOR = - 0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7; - - /// @dev The address for the WETH9 contract on Ethereum mainnet. - address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; - - /// @dev The canonical Permit2 address. - /// [Github](https://github.com/Uniswap/permit2) - /// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) - address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; - - /// @dev The canonical address of the `SELFDESTRUCT` ETH mover. - /// See: https://gist.github.com/Vectorized/1cb8ad4cf393b1378e08f23f79bd99fa - /// [Etherscan](https://etherscan.io/address/0x00000000000073c48c8055bD43D1A53799176f0D) - address internal constant ETH_MOVER = 0x00000000000073c48c8055bD43D1A53799176f0D; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ETH OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants. - // - // The regular variants: - // - Forwards all remaining gas to the target. - // - Reverts if the target reverts. - // - Reverts if the current contract has insufficient balance. - // - // The force variants: - // - Forwards with an optional gas stipend - // (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases). - // - If the target reverts, or if the gas stipend is exhausted, - // creates a temporary contract to force send the ETH via `SELFDESTRUCT`. - // Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758. - // - Reverts if the current contract has insufficient balance. - // - // The try variants: - // - Forwards with a mandatory gas stipend. - // - Instead of reverting, returns whether the transfer succeeded. - - /// @dev Sends `amount` (in wei) ETH to `to`. - function safeTransferETH(address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Sends all the ETH in the current contract to `to`. - function safeTransferAllETH(address to) internal { - /// @solidity memory-safe-assembly - assembly { - // Transfer all the ETH and check if it succeeded or not. - if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`. - function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal { - /// @solidity memory-safe-assembly - assembly { - if lt(selfbalance(), amount) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, to) // Store the address in scratch space. - mstore8(0x0b, 0x73) // Opcode `PUSH20`. - mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. - if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. - } - } - } - - /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`. - function forceSafeTransferAllETH(address to, uint256 gasStipend) internal { - /// @solidity memory-safe-assembly - assembly { - if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, to) // Store the address in scratch space. - mstore8(0x0b, 0x73) // Opcode `PUSH20`. - mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. - if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. - } - } - } - - /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`. - function forceSafeTransferETH(address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - if lt(selfbalance(), amount) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, to) // Store the address in scratch space. - mstore8(0x0b, 0x73) // Opcode `PUSH20`. - mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. - if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. - } - } - } - - /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`. - function forceSafeTransferAllETH(address to) internal { - /// @solidity memory-safe-assembly - assembly { - // forgefmt: disable-next-item - if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) { - mstore(0x00, to) // Store the address in scratch space. - mstore8(0x0b, 0x73) // Opcode `PUSH20`. - mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. - if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. - } - } - } - - /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`. - function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend) - internal - returns (bool success) - { - /// @solidity memory-safe-assembly - assembly { - success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00) - } - } - - /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`. - function trySafeTransferAllETH(address to, uint256 gasStipend) - internal - returns (bool success) - { - /// @solidity memory-safe-assembly - assembly { - success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00) - } - } - - /// @dev Force transfers ETH to `to`, without triggering the fallback (if any). - /// This method attempts to use a separate contract to send via `SELFDESTRUCT`, - /// and upon failure, deploys a minimal vault to accrue the ETH. - function safeMoveETH(address to, uint256 amount) internal returns (address vault) { - /// @solidity memory-safe-assembly - assembly { - to := shr(96, shl(96, to)) // Clean upper 96 bits. - for { let mover := ETH_MOVER } iszero(eq(to, address())) {} { - let selfBalanceBefore := selfbalance() - if or(lt(selfBalanceBefore, amount), eq(to, mover)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - if extcodesize(mover) { - let balanceBefore := balance(to) // Check via delta, in case `SELFDESTRUCT` is bricked. - mstore(0x00, to) - pop(call(gas(), mover, amount, 0x00, 0x20, codesize(), 0x00)) - // If `address(to).balance >= amount + balanceBefore`, skip vault workflow. - if iszero(lt(balance(to), add(amount, balanceBefore))) { break } - // Just in case `SELFDESTRUCT` is changed to not revert and do nothing. - if lt(selfBalanceBefore, selfbalance()) { invalid() } - } - let m := mload(0x40) - // If the mover is missing or bricked, deploy a minimal vault - // that withdraws all ETH to `to` when being called only by `to`. - // forgefmt: disable-next-item - mstore(add(m, 0x20), 0x33146025575b600160005260206000f35b3d3d3d3d47335af1601a5760003dfd) - mstore(m, or(to, shl(160, 0x6035600b3d3960353df3fe73))) - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, keccak256(m, 0x40)) - mstore(0x01, shl(96, address())) // Deployer. - mstore(0x15, 0) // Salt. - vault := keccak256(0x00, 0x55) - pop(call(gas(), vault, amount, codesize(), 0x00, codesize(), 0x00)) - // The vault returns a single word on success. Failure reverts with empty data. - if iszero(returndatasize()) { - if iszero(create2(0, m, 0x40, 0)) { revert(codesize(), codesize()) } // For gas estimation. - } - mstore(0x40, m) // Restore the free memory pointer. - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC20 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. - /// Reverts upon failure. - /// - /// 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 { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, amount) // Store the `amount` argument. - mstore(0x40, to) // Store the `to` argument. - mstore(0x2c, shl(96, from)) // Store the `from` argument. - mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`. - let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x7939f424) // `TransferFromFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. - /// - /// The `from` account must have at least `amount` approved for the current contract to manage. - function trySafeTransferFrom(address token, address from, address to, uint256 amount) - internal - returns (bool success) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, amount) // Store the `amount` argument. - mstore(0x40, to) // Store the `to` argument. - mstore(0x2c, shl(96, from)) // Store the `from` argument. - mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`. - success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - success := lt(or(iszero(extcodesize(token)), returndatasize()), success) - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Sends all of ERC20 `token` from `from` to `to`. - /// Reverts upon failure. - /// - /// The `from` account must have their entire balance approved for the current contract to manage. - 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. - mstore(0x40, to) // Store the `to` argument. - mstore(0x2c, shl(96, from)) // Store the `from` argument. - mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`. - // Read the balance, reverting upon failure. - if iszero( - and( // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x1f), // At least 32 bytes returned. - staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20) - ) - ) { - mstore(0x00, 0x7939f424) // `TransferFromFailed()`. - revert(0x1c, 0x04) - } - mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`. - amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it. - // Perform the transfer, reverting upon failure. - let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x7939f424) // `TransferFromFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. - /// Reverts upon failure. - function safeTransfer(address token, address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`. - // Perform the transfer, reverting upon failure. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x90b8ec18) // `TransferFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @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) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. - mstore(0x20, address()) // Store the address of the current contract. - // Read the balance, reverting upon failure. - if iszero( - and( // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x1f), // At least 32 bytes returned. - staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20) - ) - ) { - mstore(0x00, 0x90b8ec18) // `TransferFailed()`. - revert(0x1c, 0x04) - } - mstore(0x14, to) // Store the `to` argument. - amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it. - mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`. - // Perform the transfer, reverting upon failure. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x90b8ec18) // `TransferFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. - /// Reverts upon failure. - function safeApprove(address token, address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. - /// If the initial attempt to approve fails, attempts to reset the approved amount to zero, - /// then retries the approval again (some tokens, e.g. USDT, requires this). - /// Reverts upon failure. - function safeApproveWithRetry(address token, address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. - // Perform the approval, retrying upon failure. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x34, 0) // Store 0 for the `amount`. - mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. - pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval. - mstore(0x34, amount) // Store back the original `amount`. - // Retry the approval, reverting upon failure. - success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - // Check the `extcodesize` again just in case the token selfdestructs lol. - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`. - revert(0x1c, 0x04) - } - } - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @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) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, account) // Store the `account` argument. - mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`. - amount := - mul( // The arguments of `mul` are evaluated from right to left. - 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) - ) - ) - } - } - - /// @dev Performs a `token.balanceOf(account)` check. - /// `implemented` denotes whether the `token` does not implement `balanceOf`. - /// `amount` is zero if the `token` does not implement `balanceOf`. - function checkBalanceOf(address token, address account) - internal - view - returns (bool implemented, uint256 amount) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, account) // Store the `account` argument. - mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`. - implemented := - 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), implemented) - } - } - - /// @dev Returns the total supply of the `token`. - /// Reverts if the token does not exist or does not implement `totalSupply()`. - function totalSupply(address token) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x18160ddd) // `totalSupply()`. - if iszero( - and(gt(returndatasize(), 0x1f), staticcall(gas(), token, 0x1c, 0x04, 0x00, 0x20)) - ) { - mstore(0x00, 0x54cd9435) // `TotalSupplyQueryFailed()`. - revert(0x1c, 0x04) - } - result := mload(0x00) - } - } - - /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. - /// If the initial attempt fails, try to use Permit2 to transfer the token. - /// Reverts upon failure. - /// - /// The `from` account must have at least `amount` approved for the current contract to manage. - function safeTransferFrom2(address token, address from, address to, uint256 amount) internal { - if (!trySafeTransferFrom(token, from, to, amount)) { - permit2TransferFrom(token, from, to, amount); - } - } - - /// @dev Sends `amount` of ERC20 `token` from `from` to `to` via Permit2. - /// Reverts upon failure. - function permit2TransferFrom(address token, address from, address to, uint256 amount) - internal - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(m, 0x74), shr(96, shl(96, token))) - mstore(add(m, 0x54), amount) - mstore(add(m, 0x34), to) - mstore(add(m, 0x20), shl(96, from)) - // `transferFrom(address,address,uint160,address)`. - mstore(m, 0x36c78516000000000000000000000000) - let p := PERMIT2 - let exists := eq(chainid(), 1) - if iszero(exists) { exists := iszero(iszero(extcodesize(p))) } - if iszero( - and( - call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00), - lt(iszero(extcodesize(token)), exists) // Token has code and Permit2 exists. - ) - ) { - mstore(0x00, 0x7939f4248757f0fd) // `TransferFromFailed()` or `Permit2AmountOverflow()`. - revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04) - } - } - } - - /// @dev Permit a user to spend a given amount of - /// another user's tokens via native EIP-2612 permit if possible, falling - /// back to Permit2 if native permit fails or is not implemented on the token. - function permit2( - address token, - address owner, - address spender, - uint256 amount, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) internal { - bool success; - /// @solidity memory-safe-assembly - assembly { - for {} shl(96, xor(token, WETH9)) {} { - mstore(0x00, 0x3644e515) // `DOMAIN_SEPARATOR()`. - if iszero( - and( // The arguments of `and` are evaluated from right to left. - lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)), // Returns 1 non-zero word. - // Gas stipend to limit gas burn for tokens that don't refund gas when - // an non-existing function is called. 5K should be enough for a SLOAD. - staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20) - ) - ) { break } - // After here, we can be sure that token is a contract. - let m := mload(0x40) - mstore(add(m, 0x34), spender) - mstore(add(m, 0x20), shl(96, owner)) - mstore(add(m, 0x74), deadline) - if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) { - mstore(0x14, owner) - mstore(0x00, 0x7ecebe00000000000000000000000000) // `nonces(address)`. - mstore( - add(m, 0x94), - lt(iszero(amount), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20)) - ) - mstore(m, 0x8fcbaf0c000000000000000000000000) // `IDAIPermit.permit`. - // `nonces` is already at `add(m, 0x54)`. - // `amount != 0` is already stored at `add(m, 0x94)`. - mstore(add(m, 0xb4), and(0xff, v)) - mstore(add(m, 0xd4), r) - mstore(add(m, 0xf4), s) - success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00) - break - } - mstore(m, 0xd505accf000000000000000000000000) // `IERC20Permit.permit`. - mstore(add(m, 0x54), amount) - mstore(add(m, 0x94), and(0xff, v)) - mstore(add(m, 0xb4), r) - mstore(add(m, 0xd4), s) - success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00) - break - } - } - if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s); - } - - /// @dev Simple permit on the Permit2 contract. - function simplePermit2( - address token, - address owner, - address spender, - uint256 amount, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) internal { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, 0x927da105) // `allowance(address,address,address)`. - { - let addressMask := shr(96, not(0)) - mstore(add(m, 0x20), and(addressMask, owner)) - mstore(add(m, 0x40), and(addressMask, token)) - mstore(add(m, 0x60), and(addressMask, spender)) - mstore(add(m, 0xc0), and(addressMask, spender)) - } - let p := mul(PERMIT2, iszero(shr(160, amount))) - if iszero( - and( // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x5f), // Returns 3 words: `amount`, `expiration`, `nonce`. - staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60) - ) - ) { - mstore(0x00, 0x6b836e6b8757f0fd) // `Permit2Failed()` or `Permit2AmountOverflow()`. - revert(add(0x18, shl(2, iszero(p))), 0x04) - } - mstore(m, 0x2b67b570) // `Permit2.permit` (PermitSingle variant). - // `owner` is already `add(m, 0x20)`. - // `token` is already at `add(m, 0x40)`. - mstore(add(m, 0x60), amount) - mstore(add(m, 0x80), 0xffffffffffff) // `expiration = type(uint48).max`. - // `nonce` is already at `add(m, 0xa0)`. - // `spender` is already at `add(m, 0xc0)`. - mstore(add(m, 0xe0), deadline) - mstore(add(m, 0x100), 0x100) // `signature` offset. - mstore(add(m, 0x120), 0x41) // `signature` length. - mstore(add(m, 0x140), r) - mstore(add(m, 0x160), s) - mstore(add(m, 0x180), shl(248, v)) - if iszero( // Revert if token does not have code, or if the call fails. - mul(extcodesize(token), call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00))) { - mstore(0x00, 0x6b836e6b) // `Permit2Failed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Approves `spender` to spend `amount` of `token` for `address(this)`. - function permit2Approve(address token, address spender, uint160 amount, uint48 expiration) - internal - { - /// @solidity memory-safe-assembly - assembly { - let addressMask := shr(96, not(0)) - let m := mload(0x40) - mstore(m, 0x87517c45) // `approve(address,address,uint160,uint48)`. - mstore(add(m, 0x20), and(addressMask, token)) - mstore(add(m, 0x40), and(addressMask, spender)) - mstore(add(m, 0x60), and(addressMask, amount)) - mstore(add(m, 0x80), and(0xffffffffffff, expiration)) - if iszero(call(gas(), PERMIT2, 0, add(m, 0x1c), 0xa0, codesize(), 0x00)) { - mstore(0x00, 0x324f14ae) // `Permit2ApproveFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Revokes an approval for `token` and `spender` for `address(this)`. - function permit2Lockdown(address token, address spender) internal { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, 0xcc53287f) // `Permit2.lockdown`. - mstore(add(m, 0x20), 0x20) // Offset of the `approvals`. - mstore(add(m, 0x40), 1) // `approvals.length`. - mstore(add(m, 0x60), shr(96, shl(96, token))) - mstore(add(m, 0x80), shr(96, shl(96, spender))) - if iszero(call(gas(), PERMIT2, 0, add(m, 0x1c), 0xa0, codesize(), 0x00)) { - mstore(0x00, 0x96b3de23) // `Permit2LockdownFailed()`. - revert(0x1c, 0x04) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/SemVerLib.sol b/grouperBot/lib/solady/src/utils/SemVerLib.sol deleted file mode 100644 index 09b5e09..0000000 --- a/grouperBot/lib/solady/src/utils/SemVerLib.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for comparing SemVers. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SemVerLib.sol) -library SemVerLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* COMPARISON */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns -1 if `a < b`, 0 if `a == b`, 1 if `a > b`. - /// For efficiency, this is a forgiving, non-reverting parser: - /// - Early returns if a strict order can be determined. - /// - Skips the first byte if it is `v` (case insensitive). - /// - If a strict order cannot be determined, returns 0. - /// To convert a regular string to a small string (bytes32), use `LibString.toSmallString`. - function cmp(bytes32 a, bytes32 b) internal pure returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - function mmp(i_, a_) -> _r, _o { - for { _o := i_ } iszero(gt(sub(byte(_o, a_), 48), 9)) { _o := add(1, _o) } { - _r := add(mul(10, _r), sub(byte(_o, a_), 48)) - } - } - function pre(i_, a_) -> hasNonDigit_, _r, _o { - mstore(0x00, 0) - for { _o := i_ } 1 { _o := add(1, _o) } { - let c_ := byte(_o, a_) - if and(1, shr(c_, 0x480000000001)) { break } // '\x00', '.', '+' - let digit_ := sub(c_, 48) - hasNonDigit_ := or(hasNonDigit_, gt(digit_, 9)) - _r := add(mul(10, _r), digit_) - mstore8(sub(_o, i_), c_) - } - mstore(shl(5, hasNonDigit_), _r) // Overwrite if it's numeric. - _r := mload(0x00) - } - let x, i := mmp(eq(118, or(32, byte(0, a))), a) // 'v', 'V' - let y, j := mmp(eq(118, or(32, byte(0, b))), b) // 'v', 'V' - result := sub(gt(x, y), lt(x, y)) - for {} 1 {} { - let u := eq(byte(i, a), 46) // `.` - let v := eq(byte(j, b), 46) // `.` - if iszero(lt(result, or(u, v))) { break } - if u { u, i := mmp(add(i, 1), a) } // `.` - if v { v, j := mmp(add(j, 1), b) } // `.` - result := sub(gt(u, v), lt(u, v)) - } - if iszero(result) { - let u := eq(byte(i, a), 45) // `-` - let v := eq(byte(j, b), 45) // `-` - result := sub(lt(u, v), gt(u, v)) - for {} lt(result, u) {} { - u, x, i := pre(add(i, 1), a) - v, y, j := pre(add(j, 1), b) - result := sub(gt(u, v), lt(u, v)) - if result { break } - result := sub(gt(x, y), lt(x, y)) - if result { break } - u := eq(byte(i, a), 46) // `.` - v := eq(byte(j, b), 46) // `.` - result := sub(gt(u, v), lt(u, v)) - } - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/SignatureCheckerLib.sol b/grouperBot/lib/solady/src/utils/SignatureCheckerLib.sol deleted file mode 100644 index c4f69f5..0000000 --- a/grouperBot/lib/solady/src/utils/SignatureCheckerLib.sol +++ /dev/null @@ -1,527 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Signature verification helper that supports both ECDSA signatures from EOAs -/// and ERC1271 signatures from smart contract wallets like Argent and Gnosis safe. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SignatureCheckerLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol) -/// -/// @dev Note: -/// - The signature checking functions use the ecrecover precompile (0x1). -/// - The `bytes memory signature` variants use the identity precompile (0x4) -/// to copy memory internally. -/// - Unlike ECDSA signatures, contract signatures are revocable. -/// - As of Solady version 0.0.134, all `bytes signature` variants accept both -/// regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures. -/// See: https://eips.ethereum.org/EIPS/eip-2098 -/// This is for calldata efficiency on smart accounts prevalent on L2s. -/// -/// WARNING! Do NOT use signatures as unique identifiers: -/// - Use a nonce in the digest to prevent replay attacks on the same contract. -/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts. -/// EIP-712 also enables readable signing of typed data for better user safety. -/// This implementation does NOT check if a signature is non-malleable. -library SignatureCheckerLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* SIGNATURE CHECKING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether `signature` is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - switch mload(signature) - case 64 { - let vs := mload(add(signature, 0x40)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. - mstore(0x60, mload(add(signature, 0x40))) // `s`. - } - default { break } - mstore(0x00, hash) - mstore(0x40, mload(add(signature, 0x20))) // `r`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - // Copy the `signature` over. - let n := add(0x20, mload(signature)) - let copied := staticcall(gas(), 4, signature, n, add(m, 0x44), n) - isValid := staticcall(gas(), signer, m, add(returndatasize(), 0x44), d, 0x20) - isValid := and(eq(mload(d), f), and(isValid, copied)) - break - } - } - } - - /// @dev Returns whether `signature` is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - switch signature.length - case 64 { - let vs := calldataload(add(signature.offset, 0x20)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, calldataload(signature.offset)) // `r`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. - calldatacopy(0x40, signature.offset, 0x40) // `r`, `s`. - } - default { break } - mstore(0x00, hash) - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), signature.length) - // Copy the `signature` over. - calldatacopy(add(m, 0x64), signature.offset, signature.length) - isValid := staticcall(gas(), signer, m, add(signature.length, 0x64), d, 0x20) - isValid := and(eq(mload(d), f), isValid) - break - } - } - } - - /// @dev Returns whether the signature (`r`, `vs`) is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - mstore(0x00, hash) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, r) // `r`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`. - mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - break - } - } - } - - /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - mstore(0x00, hash) - mstore(0x20, and(v, 0xff)) // `v`. - mstore(0x40, r) // `r`. - mstore(0x60, s) // `s`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), s) // `s`. - mstore8(add(m, 0xa4), v) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1271 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: These ERC1271 operations do NOT have an ECDSA fallback. - - /// @dev Returns whether `signature` is valid for `hash` for an ERC1271 `signer` contract. - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes memory signature) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - // Copy the `signature` over. - let n := add(0x20, mload(signature)) - let copied := staticcall(gas(), 4, signature, n, add(m, 0x44), n) - isValid := staticcall(gas(), signer, m, add(returndatasize(), 0x44), d, 0x20) - isValid := and(eq(mload(d), f), and(isValid, copied)) - } - } - - /// @dev Returns whether `signature` is valid for `hash` for an ERC1271 `signer` contract. - function isValidERC1271SignatureNowCalldata( - address signer, - bytes32 hash, - bytes calldata signature - ) internal view returns (bool isValid) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), signature.length) - // Copy the `signature` over. - calldatacopy(add(m, 0x64), signature.offset, signature.length) - isValid := staticcall(gas(), signer, m, add(signature.length, 0x64), d, 0x20) - isValid := and(eq(mload(d), f), isValid) - } - } - - /// @dev Returns whether the signature (`r`, `vs`) is valid for `hash` - /// for an ERC1271 `signer` contract. - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`. - mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - } - } - - /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `hash` - /// for an ERC1271 `signer` contract. - function isValidERC1271SignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), s) // `s`. - mstore8(add(m, 0xa4), v) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC6492 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: These ERC6492 operations now include an ECDSA fallback at the very end. - // The calldata variants are excluded for brevity. - - /// @dev Returns whether `signature` is valid for `hash`. - /// If the signature is postfixed with the ERC6492 magic number, it will attempt to - /// deploy / prepare the `signer` smart account before doing a regular ERC1271 check. - /// Note: This function is NOT reentrancy safe. - /// The verifier must be deployed. - /// Otherwise, the function will return false if `signer` is not yet deployed / prepared. - /// See: https://gist.github.com/Vectorized/011d6becff6e0a73e42fe100f8d7ef04 - /// With a dedicated verifier, this function is safe to use in contracts - /// that have been granted special permissions. - function isValidERC6492SignatureNowAllowSideEffects( - address signer, - bytes32 hash, - bytes memory signature - ) internal returns (bool isValid) { - /// @solidity memory-safe-assembly - assembly { - function callIsValidSignature(signer_, hash_, signature_) -> _isValid { - let m_ := mload(0x40) - let f_ := shl(224, 0x1626ba7e) - mstore(m_, f_) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m_, 0x04), hash_) - let d_ := add(m_, 0x24) - mstore(d_, 0x40) // The offset of the `signature` in the calldata. - let n_ := add(0x20, mload(signature_)) - let copied_ := staticcall(gas(), 4, signature_, n_, add(m_, 0x44), n_) - _isValid := staticcall(gas(), signer_, m_, add(returndatasize(), 0x44), d_, 0x20) - _isValid := and(eq(mload(d_), f_), and(_isValid, copied_)) - } - let noCode := iszero(extcodesize(signer)) - let n := mload(signature) - for {} 1 {} { - if iszero(eq(mload(add(signature, n)), mul(0x6492, div(not(isValid), 0xffff)))) { - if iszero(noCode) { isValid := callIsValidSignature(signer, hash, signature) } - break - } - if iszero(noCode) { - let o := add(signature, 0x20) // Signature bytes. - isValid := callIsValidSignature(signer, hash, add(o, mload(add(o, 0x40)))) - if isValid { break } - } - let m := mload(0x40) - mstore(m, signer) - mstore(add(m, 0x20), hash) - pop( - call( - gas(), // Remaining gas. - 0x0000bc370E4DC924F427d84e2f4B9Ec81626ba7E, // Non-reverting verifier. - 0, // Send zero ETH. - m, // Start of memory. - add(returndatasize(), 0x40), // Length of calldata in memory. - staticcall(gas(), 4, add(signature, 0x20), n, add(m, 0x40), n), // 1. - 0x00 // Length of returndata to write. - ) - ) - isValid := returndatasize() - break - } - // Do `ecrecover` fallback if `noCode && !isValid`. - for {} gt(noCode, isValid) {} { - switch n - case 64 { - let vs := mload(add(signature, 0x40)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. - mstore(0x60, mload(add(signature, 0x40))) // `s`. - } - default { break } - let m := mload(0x40) - mstore(0x00, hash) - mstore(0x40, mload(add(signature, 0x20))) // `r`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - } - } - - /// @dev Returns whether `signature` is valid for `hash`. - /// If the signature is postfixed with the ERC6492 magic number, it will attempt - /// to use a reverting verifier to deploy / prepare the `signer` smart account - /// and do a `isValidSignature` check via the reverting verifier. - /// Note: This function is reentrancy safe. - /// The reverting verifier must be deployed. - /// Otherwise, the function will return false if `signer` is not yet deployed / prepared. - /// See: https://gist.github.com/Vectorized/846a474c855eee9e441506676800a9ad - function isValidERC6492SignatureNow(address signer, bytes32 hash, bytes memory signature) - internal - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - function callIsValidSignature(signer_, hash_, signature_) -> _isValid { - let m_ := mload(0x40) - let f_ := shl(224, 0x1626ba7e) - mstore(m_, f_) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m_, 0x04), hash_) - let d_ := add(m_, 0x24) - mstore(d_, 0x40) // The offset of the `signature` in the calldata. - let n_ := add(0x20, mload(signature_)) - let copied_ := staticcall(gas(), 4, signature_, n_, add(m_, 0x44), n_) - _isValid := staticcall(gas(), signer_, m_, add(returndatasize(), 0x44), d_, 0x20) - _isValid := and(eq(mload(d_), f_), and(_isValid, copied_)) - } - let noCode := iszero(extcodesize(signer)) - let n := mload(signature) - for {} 1 {} { - if iszero(eq(mload(add(signature, n)), mul(0x6492, div(not(isValid), 0xffff)))) { - if iszero(noCode) { isValid := callIsValidSignature(signer, hash, signature) } - break - } - if iszero(noCode) { - let o := add(signature, 0x20) // Signature bytes. - isValid := callIsValidSignature(signer, hash, add(o, mload(add(o, 0x40)))) - if isValid { break } - } - let m := mload(0x40) - mstore(m, signer) - mstore(add(m, 0x20), hash) - let willBeZeroIfRevertingVerifierExists := - call( - gas(), // Remaining gas. - 0x00007bd799e4A591FeA53f8A8a3E9f931626Ba7e, // Reverting verifier. - 0, // Send zero ETH. - m, // Start of memory. - add(returndatasize(), 0x40), // Length of calldata in memory. - staticcall(gas(), 4, add(signature, 0x20), n, add(m, 0x40), n), // 1. - 0x00 // Length of returndata to write. - ) - isValid := gt(returndatasize(), willBeZeroIfRevertingVerifierExists) - break - } - // Do `ecrecover` fallback if `noCode && !isValid`. - for {} gt(noCode, isValid) {} { - switch n - case 64 { - let vs := mload(add(signature, 0x40)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. - mstore(0x60, mload(add(signature, 0x40))) // `s`. - } - default { break } - let m := mload(0x40) - mstore(0x00, hash) - mstore(0x40, mload(add(signature, 0x20))) // `r`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HASHING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns an Ethereum Signed Message, created from a `hash`. - /// This produces a hash corresponding to the one signed with the - /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) - /// JSON-RPC method as part of EIP-191. - function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, hash) // Store into scratch space for keccak256. - mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes. - result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`. - } - } - - /// @dev Returns an Ethereum Signed Message, created from `s`. - /// This produces a hash corresponding to the one signed with the - /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) - /// JSON-RPC method as part of EIP-191. - /// Note: Supports lengths of `s` up to 999999 bytes. - function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let sLength := mload(s) - let o := 0x20 - mstore(o, "\x19Ethereum Signed Message:\n") // 26 bytes, zero-right-padded. - mstore(0x00, 0x00) - // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`. - for { let temp := sLength } 1 {} { - o := sub(o, 1) - mstore8(o, add(48, mod(temp, 10))) - temp := div(temp, 10) - if iszero(temp) { break } - } - let n := sub(0x3a, o) // Header length: `26 + 32 - o`. - // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20)) - mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header. - result := keccak256(add(s, sub(0x20, n)), add(n, sLength)) - mstore(s, sLength) // Restore the length. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EMPTY CALLDATA HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns an empty calldata bytes. - function emptySignature() internal pure returns (bytes calldata signature) { - /// @solidity memory-safe-assembly - assembly { - signature.length := 0 - } - } -} diff --git a/grouperBot/lib/solady/src/utils/UUPSUpgradeable.sol b/grouperBot/lib/solady/src/utils/UUPSUpgradeable.sol deleted file mode 100644 index 124c3a3..0000000 --- a/grouperBot/lib/solady/src/utils/UUPSUpgradeable.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {CallContextChecker} from "./CallContextChecker.sol"; - -/// @notice UUPS proxy mixin. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/UUPSUpgradeable.sol) -/// @author Modified from OpenZeppelin -/// (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/UUPSUpgradeable.sol) -/// -/// @dev Note: -/// - This implementation is intended to be used with ERC1967 proxies. -/// See: `LibClone.deployERC1967` and related functions. -/// - This implementation is NOT compatible with legacy OpenZeppelin proxies -/// which do not store the implementation at `_ERC1967_IMPLEMENTATION_SLOT`. -abstract contract UUPSUpgradeable is CallContextChecker { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The upgrade failed. - error UpgradeFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when the proxy's implementation is upgraded. - event Upgraded(address indexed implementation); - - /// @dev `keccak256(bytes("Upgraded(address)"))`. - uint256 private constant _UPGRADED_EVENT_SIGNATURE = - 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UUPS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Please override this function to check if `msg.sender` is authorized - /// to upgrade the proxy to `newImplementation`, reverting if not. - /// ``` - /// function _authorizeUpgrade(address) internal override onlyOwner {} - /// ``` - function _authorizeUpgrade(address newImplementation) internal virtual; - - /// @dev Returns the storage slot used by the implementation, - /// as specified in [ERC1822](https://eips.ethereum.org/EIPS/eip-1822). - /// - /// Note: The `notDelegated` modifier prevents accidental upgrades to - /// an implementation that is a proxy contract. - function proxiableUUID() public view virtual notDelegated returns (bytes32) { - // This function must always return `_ERC1967_IMPLEMENTATION_SLOT` to comply with ERC1967. - return _ERC1967_IMPLEMENTATION_SLOT; - } - - /// @dev Upgrades the proxy's implementation to `newImplementation`. - /// Emits a {Upgraded} event. - /// - /// Note: Passing in empty `data` skips the delegatecall to `newImplementation`. - function upgradeToAndCall(address newImplementation, bytes calldata data) - public - payable - virtual - onlyProxy - { - _authorizeUpgrade(newImplementation); - /// @solidity memory-safe-assembly - assembly { - newImplementation := shr(96, shl(96, newImplementation)) // Clears upper 96 bits. - mstore(0x00, returndatasize()) - mstore(0x01, 0x52d1902d) // `proxiableUUID()`. - let s := _ERC1967_IMPLEMENTATION_SLOT - // Check if `newImplementation` implements `proxiableUUID` correctly. - if iszero(eq(mload(staticcall(gas(), newImplementation, 0x1d, 0x04, 0x01, 0x20)), s)) { - mstore(0x01, 0x55299b49) // `UpgradeFailed()`. - revert(0x1d, 0x04) - } - // Emit the {Upgraded} event. - log2(codesize(), 0x00, _UPGRADED_EVENT_SIGNATURE, newImplementation) - sstore(s, newImplementation) // Updates the implementation. - - // Perform a delegatecall to `newImplementation` if `data` is non-empty. - if data.length { - // Forwards the `data` to `newImplementation` via delegatecall. - let m := mload(0x40) - calldatacopy(m, data.offset, data.length) - if iszero(delegatecall(gas(), newImplementation, m, data.length, codesize(), 0x00)) - { - // Bubble up the revert if the call reverts. - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/UpgradeableBeacon.sol b/grouperBot/lib/solady/src/utils/UpgradeableBeacon.sol deleted file mode 100644 index 6810dff..0000000 --- a/grouperBot/lib/solady/src/utils/UpgradeableBeacon.sol +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Upgradeable beacon for ERC1967 beacon proxies. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/UpgradeableBeacon.sol) -/// @author Modified from OpenZeppelin -/// (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/beacon/UpgradeableBeacon.sol) -/// -/// @dev Note: -/// - The implementation is intended to be used with ERC1967 beacon proxies. -/// See: `LibClone.deployERC1967BeaconProxy` and related functions. -/// - For gas efficiency, the ownership functionality is baked into this contract. -/// -/// Optimized creation code (hex-encoded): -/// `60406101c73d393d5160205180821760a01c3d3d3e803b1560875781684343a0dc92ed22dbfc558068911c5a209f08d5ec5e557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b3d38a23d7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e03d38a3610132806100953d393df35b636d3e283b3d526004601cfdfe3d3560e01c635c60da1b14610120573d3560e01c80638da5cb5b1461010e5780633659cfe61460021b8163f2fde38b1460011b179063715018a6141780153d3d3e684343a0dc92ed22dbfc805490813303610101573d9260068116610089575b508290557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e03d38a3005b925060048035938460a01c60243610173d3d3e146100ba5782156100ad573861005f565b637448fbae3d526004601cfd5b82803b156100f4578068911c5a209f08d5ec5e557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b3d38a2005b636d3e283b3d526004601cfd5b6382b429003d526004601cfd5b684343a0dc92ed22dbfc543d5260203df35b68911c5a209f08d5ec5e543d5260203df3`. -/// See: https://gist.github.com/Vectorized/365bd7f6e9a848010f00adb9e50a2516 -/// -/// To get the initialization code: -/// `abi.encodePacked(creationCode, abi.encode(initialOwner, initialImplementation))` -/// -/// This optimized bytecode is compiled via Yul and is not verifiable via Etherscan -/// at the time of writing. For best gas efficiency, deploy the Yul version. -/// The Solidity version is provided as an interface / reference. -contract UpgradeableBeacon { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The new implementation is not a deployed contract. - error NewImplementationHasNoCode(); - - /// @dev The caller is not authorized to perform the operation. - error Unauthorized(); - - /// @dev The `newOwner` cannot be the zero address. - error NewOwnerIsZeroAddress(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when the proxy's implementation is upgraded. - event Upgraded(address indexed implementation); - - /// @dev The ownership is transferred from `oldOwner` to `newOwner`. - /// This event is intentionally kept the same as OpenZeppelin's Ownable to be - /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), - /// despite it not being as lightweight as a single argument event. - event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); - - /// @dev `keccak256(bytes("Upgraded(address)"))`. - uint256 private constant _UPGRADED_EVENT_SIGNATURE = - 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b; - - /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`. - uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE = - 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage slot for the implementation address. - /// `uint72(bytes9(keccak256("_UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT")))`. - uint256 internal constant _UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT = 0x911c5a209f08d5ec5e; - - /// @dev The storage slot for the owner address. - /// `uint72(bytes9(keccak256("_UPGRADEABLE_BEACON_OWNER_SLOT")))`. - uint256 internal constant _UPGRADEABLE_BEACON_OWNER_SLOT = 0x4343a0dc92ed22dbfc; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor(address initialOwner, address initialImplementation) payable { - _constructUpgradeableBeacon(initialOwner, initialImplementation); - } - - /// @dev Called in the constructor. Override as required. - function _constructUpgradeableBeacon(address initialOwner, address initialImplementation) - internal - virtual - { - _initializeUpgradeableBeacon(initialOwner, initialImplementation); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UPGRADEABLE BEACON OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Required to be called in the constructor or initializer. - /// This function does not guard against double-initialization. - function _initializeUpgradeableBeacon(address initialOwner, address initialImplementation) - internal - virtual - { - // We don't need to check if `initialOwner` is the zero address here, - // as some use cases may not want the beacon to be owned. - _setOwner(initialOwner); - _setImplementation(initialImplementation); - } - - /// @dev Sets the implementation directly without authorization guard. - function _setImplementation(address newImplementation) internal virtual { - /// @solidity memory-safe-assembly - assembly { - newImplementation := shr(96, shl(96, newImplementation)) // Clean the upper 96 bits. - if iszero(extcodesize(newImplementation)) { - mstore(0x00, 0x6d3e283b) // `NewImplementationHasNoCode()`. - revert(0x1c, 0x04) - } - sstore(_UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT, newImplementation) // Store the implementation. - // Emit the {Upgraded} event. - log2(codesize(), 0x00, _UPGRADED_EVENT_SIGNATURE, newImplementation) - } - } - - /// @dev Sets the owner directly without authorization guard. - function _setOwner(address newOwner) internal virtual { - /// @solidity memory-safe-assembly - assembly { - newOwner := shr(96, shl(96, newOwner)) // Clean the upper 96 bits. - let oldOwner := sload(_UPGRADEABLE_BEACON_OWNER_SLOT) - sstore(_UPGRADEABLE_BEACON_OWNER_SLOT, newOwner) // Store the owner. - // Emit the {OwnershipTransferred} event. - log3(codesize(), 0x00, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, oldOwner, newOwner) - } - } - - /// @dev Returns the implementation stored in the beacon. - /// See: https://eips.ethereum.org/EIPS/eip-1967#beacon-contract-address - function implementation() public view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(_UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT) - } - } - - /// @dev Returns the owner of the beacon. - function owner() public view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(_UPGRADEABLE_BEACON_OWNER_SLOT) - } - } - - /// @dev Allows the owner to upgrade the implementation. - function upgradeTo(address newImplementation) public virtual onlyOwner { - _setImplementation(newImplementation); - } - - /// @dev Allows the owner to transfer the ownership to `newOwner`. - function transferOwnership(address newOwner) public virtual onlyOwner { - /// @solidity memory-safe-assembly - assembly { - if iszero(shl(96, newOwner)) { - mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`. - revert(0x1c, 0x04) - } - } - _setOwner(newOwner); - } - - /// @dev Allows the owner to renounce their ownership. - function renounceOwnership() public virtual onlyOwner { - _setOwner(address(0)); - } - - /// @dev Throws if the sender is not the owner. - function _checkOwner() internal view virtual { - /// @solidity memory-safe-assembly - assembly { - // If the caller is not the stored owner, revert. - if iszero(eq(caller(), sload(_UPGRADEABLE_BEACON_OWNER_SLOT))) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MODIFIERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Marks a function as only callable by the owner. - modifier onlyOwner() virtual { - _checkOwner(); - _; - } -} diff --git a/grouperBot/lib/solady/src/utils/WebAuthn.sol b/grouperBot/lib/solady/src/utils/WebAuthn.sol deleted file mode 100644 index e2facb5..0000000 --- a/grouperBot/lib/solady/src/utils/WebAuthn.sol +++ /dev/null @@ -1,336 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Base64} from "./Base64.sol"; -import {P256} from "./P256.sol"; - -/// @notice WebAuthn helper. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/WebAuthn.sol) -/// @author Modified from Daimo WebAuthn (https://github.com/daimo-eth/p256-verifier/blob/master/src/WebAuthn.sol) -/// @author Modified from Coinbase WebAuthn (https://github.com/base-org/webauthn-sol/blob/main/src/WebAuthn.sol) -library WebAuthn { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helps make encoding and decoding easier, alleviates stack-too-deep. - struct WebAuthnAuth { - // The WebAuthn authenticator data. - // See: https://www.w3.org/TR/webauthn-2/#dom-authenticatorassertionresponse-authenticatordata. - bytes authenticatorData; - // The WebAuthn client data JSON. - // See: https://www.w3.org/TR/webauthn-2/#dom-authenticatorresponse-clientdatajson. - string clientDataJSON; - // Start index of "challenge":"..." in `clientDataJSON`. - uint256 challengeIndex; - // Start index of "type":"..." in `clientDataJSON`. - uint256 typeIndex; - // The r value of secp256r1 signature. - bytes32 r; - // The s value of secp256r1 signature. - bytes32 s; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* WEBAUTHN VERIFICATION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Verifies a Webauthn Authentication Assertion. - /// See: https://www.w3.org/TR/webauthn-2/#sctn-verifying-assertion. - /// - /// We do not verify all the steps as described in the specification, only ones - /// relevant to our context. Please carefully read through this list before usage. - /// - /// Specifically, we do verify the following: - /// - Verify that `authenticatorData` (which comes from the authenticator, - /// such as iCloud Keychain) indicates a well-formed assertion with the - /// "User Present" bit set. If `requireUserVerification` is set, checks that the - /// authenticator enforced user verification. User verification should be required - /// if, and only if, `options.userVerification` is set to required in the request. - /// - Verifies that the client JSON is of type "webauthn.get", - /// i.e. the client was responding to a request to assert authentication. - /// - Verifies that the client JSON contains the requested challenge. - /// - Verifies that (r, s) constitute a valid signature over both the - /// `authData` and client JSON, for public key (x, y). - /// - /// We make some assumptions about the particular use case of this verifier, - /// so we do NOT verify the following: - /// - Does NOT verify that the origin in the `clientDataJSON` matches the - /// Relying Party's origin: it is considered the authenticator's responsibility to - /// ensure that the user is interacting with the correct RP. This is enforced by - /// most high quality authenticators properly, particularly the iCloud Keychain - /// and Google Password Manager were tested. - /// - Does NOT verify That `topOrigin` in `clientDataJSON` is well-formed: - /// We assume it would never be present, i.e. the credentials are never used in a - /// cross-origin/iframe context. The website/app set up should disallow cross-origin - /// usage of the credentials. This is the default behavior for created credentials - /// in common settings. - /// - Does NOT verify that the `rpIdHash` in `authenticatorData` is the SHA-256 hash - /// of the RP ID expected by the Relying Party: - /// this means that we rely on the authenticator to properly enforce - /// credentials to be used only by the correct RP. - /// This is generally enforced with features like Apple App Site Association - /// and Google Asset Links. To protect from edge cases in which a previously-linked - /// RP ID is removed from the authorized RP IDs, we recommend that messages - /// signed by the authenticator include some expiry mechanism. - /// - Does NOT verify the credential backup state: this assumes the credential backup - /// state is NOT used as part of Relying Party business logic or policy. - /// - Does NOT verify the values of the client extension outputs: - /// this assumes that the Relying Party does not use client extension outputs. - /// - Does NOT verify the signature counter: signature counters are intended to enable - /// risk scoring for the Relying Party. This assumes risk scoring is not used as part - /// of Relying Party business logic or policy. - /// - Does NOT verify the attestation object: this assumes that - /// response.attestationObject is NOT present in the response, - /// i.e. the RP does not intend to verify an attestation. - function verify( - bytes memory challenge, - bool requireUserVerification, - WebAuthnAuth memory auth, - bytes32 x, - bytes32 y - ) internal view returns (bool result) { - bytes32 messageHash; - string memory encoded = Base64.encode(challenge, true, true); - /// @solidity memory-safe-assembly - assembly { - let clientDataJSON := mload(add(auth, 0x20)) - let n := mload(clientDataJSON) // `clientDataJSON`'s length. - let o := add(clientDataJSON, 0x20) // Start of `clientData`'s bytes. - { - let c := mload(add(auth, 0x40)) // Challenge index in `clientDataJSON`. - let t := mload(add(auth, 0x60)) // Type index in `clientDataJSON`. - let l := mload(encoded) // Cache `encoded`'s length. - let q := add(l, 0x0d) // Length of `encoded` prefixed with '"challenge":"'. - mstore(encoded, shr(152, '"challenge":"')) // Temp prefix with '"challenge":"'. - result := - and( - // 11. Verify JSON's type. Also checks for possible addition overflows. - and( - eq(shr(88, mload(add(o, t))), shr(88, '"type":"webauthn.get"')), - lt(shr(128, or(t, c)), lt(add(0x14, t), n)) - ), - // 12. Verify JSON's challenge. Includes a check for the closing '"'. - and( - eq(keccak256(add(o, c), q), keccak256(add(encoded, 0x13), q)), - and(eq(byte(0, mload(add(add(o, c), q))), 34), lt(add(q, c), n)) - ) - ) - mstore(encoded, l) // Restore `encoded`'s length, in case of string interning. - } - // Skip 13., 14., 15. - let l := mload(mload(auth)) // Length of `authenticatorData`. - // 16. Verify that the "User Present" flag is set (bit 0). - // 17. Verify that the "User Verified" flag is set (bit 2), if required. - // See: https://www.w3.org/TR/webauthn-2/#flags. - let u := or(1, shl(2, iszero(iszero(requireUserVerification)))) - result := and(and(result, gt(l, 0x20)), eq(and(mload(add(mload(auth), 0x21)), u), u)) - if result { - let p := add(mload(auth), 0x20) // Start of `authenticatorData`'s bytes. - let e := add(p, l) // Location of the word after `authenticatorData`. - let w := mload(e) // Cache the word after `authenticatorData`. - // 19. Compute `sha256(clientDataJSON)`. - // 20. Compute `sha256(authenticatorData ‖ sha256(clientDataJSON))`. - // forgefmt: disable-next-item - messageHash := mload(staticcall(gas(), - shl(1, staticcall(gas(), 2, o, n, e, 0x20)), p, add(l, 0x20), 0x01, 0x20)) - mstore(e, w) // Restore the word after `authenticatorData`, in case of reuse. - // `returndatasize()` is `0x20` on `sha256` success, and `0x00` otherwise. - if iszero(returndatasize()) { invalid() } - } - } - // `P256.verifySignature` returns false if `s > N/2` due to the malleability check. - if (result) result = P256.verifySignature(messageHash, auth.r, auth.s, x, y); - } - - /// @dev Plain variant of verify. - function verify( - bytes memory challenge, - bool requireUserVerification, - bytes memory authenticatorData, - string memory clientDataJSON, - uint256 challengeIndex, - uint256 typeIndex, - bytes32 r, - bytes32 s, - bytes32 x, - bytes32 y - ) internal view returns (bool) { - return verify( - challenge, - requireUserVerification, - WebAuthnAuth(authenticatorData, clientDataJSON, challengeIndex, typeIndex, r, s), - x, - y - ); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ENCODING / DECODING HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `abi.encode(auth)`. - function encodeAuth(WebAuthnAuth memory auth) internal pure returns (bytes memory) { - return abi.encode(auth); - } - - /// @dev Performs a best-effort attempt to `abi.decode(auth)`. Won't revert. - /// If any fields cannot be successfully extracted, `decoded` will not be populated, - /// which will cause `verify` to return false (as `clientDataJSON` is empty). - function tryDecodeAuth(bytes memory encodedAuth) - internal - pure - returns (WebAuthnAuth memory decoded) - { - /// @solidity memory-safe-assembly - assembly { - for { let n := mload(encodedAuth) } iszero(lt(n, 0xc0)) {} { - let o := add(encodedAuth, 0x20) // Start of `encodedAuth`'s bytes. - let e := add(o, n) // End of `encodedAuth` in memory. - let p := add(mload(o), o) // Start of `encodedAuth`. - if or(gt(add(p, 0xc0), e), lt(p, o)) { break } - let authenticatorData := add(mload(p), p) - let clientDataJSON := add(mload(add(p, 0x20)), p) - if or( - or(gt(authenticatorData, e), lt(authenticatorData, p)), - or(gt(clientDataJSON, e), lt(clientDataJSON, p)) - ) { break } - if or( - gt(add(add(authenticatorData, 0x20), mload(authenticatorData)), e), - gt(add(add(clientDataJSON, 0x20), mload(clientDataJSON)), e) - ) { break } - mstore(decoded, authenticatorData) // `authenticatorData`. - mstore(add(decoded, 0x20), clientDataJSON) // `clientDataJSON`. - mstore(add(decoded, 0x40), mload(add(p, 0x40))) // `challengeIndex`. - mstore(add(decoded, 0x60), mload(add(p, 0x60))) // `typeIndex`. - mstore(add(decoded, 0x80), mload(add(p, 0x80))) // `r`. - mstore(add(decoded, 0xa0), mload(add(p, 0xa0))) // `s`. - break - } - } - } - - /// @dev Returns the compact encoding of `auth`: - /// ``` - /// abi.encodePacked( - /// uint16(auth.authenticatorData.length), - /// bytes(auth.authenticatorData), - /// bytes(auth.clientDataJSON), - /// uint16(auth.challengeIndex), - /// uint16(auth.typeIndex), - /// bytes32(auth.r), - /// bytes32(auth.s) - /// ) - /// ``` - /// Returns the empty string if any length or index exceeds 16 bits. - function tryEncodeAuthCompact(WebAuthnAuth memory auth) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - function copyBytes(o_, s_, c_) -> _e { - mstore(o_, shl(240, mload(s_))) - o_ := add(o_, c_) - _e := add(o_, mload(s_)) // The end of the bytes. - for { let d_ := sub(add(0x20, s_), o_) } 1 {} { - mstore(o_, mload(add(d_, o_))) - o_ := add(o_, 0x20) - if iszero(lt(o_, _e)) { break } - } - } - let clientDataJSON := mload(add(0x20, auth)) - let c := mload(add(0x40, auth)) // `challengeIndex`. - let t := mload(add(0x60, auth)) // `typeIndex`. - // If none of the lengths are more than `0xffff`. - if iszero(shr(16, or(or(t, c), or(mload(mload(auth)), mload(clientDataJSON))))) { - result := mload(0x40) - // `authenticatorData`, `clientDataJSON`. - let o := copyBytes(copyBytes(add(result, 0x20), mload(auth), 2), clientDataJSON, 0) - mstore(o, or(shl(240, c), shl(224, t))) // `challengeIndex`, `typeIndex`. - mstore(add(o, 0x04), mload(add(0x80, auth))) // `r`. - mstore(add(o, 0x24), mload(add(0xa0, auth))) // `s`. - mstore(result, sub(add(o, 0x24), result)) // Store the length. - mstore(add(o, 0x44), 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x64)) // Allocate memory . - } - } - } - - /// @dev Approximately the same gas as `tryDecodeAuth`, but helps save on calldata. - /// If any fields cannot be successfully extracted, `decoded` will not be populated, - /// which will cause `verify` to return false (as `clientDataJSON` is empty). - function tryDecodeAuthCompact(bytes memory encodedAuth) - internal - pure - returns (WebAuthnAuth memory decoded) - { - /// @solidity memory-safe-assembly - assembly { - function extractBytes(o_, l_) -> _m { - _m := mload(0x40) // Grab the free memory pointer. - let s_ := add(_m, 0x20) - for { let i_ := 0 } 1 {} { - mstore(add(s_, i_), mload(add(o_, i_))) - i_ := add(i_, 0x20) - if iszero(lt(i_, l_)) { break } - } - mstore(_m, l_) // Store the length. - mstore(add(l_, s_), 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, add(l_, s_))) // Allocate memory. - } - let n := mload(encodedAuth) - if iszero(lt(n, 0x46)) { - let o := add(encodedAuth, 0x20) // Start of `encodedAuth`'s bytes. - let e := add(o, n) // End of `encodedAuth` in memory. - n := shr(240, mload(o)) // Length of `authenticatorData`. - let a := add(o, 0x02) // Start of `authenticatorData`. - let c := add(a, n) // Start of `clientDataJSON`. - let j := sub(e, 0x44) // Start of `challengeIndex`. - if iszero(gt(c, j)) { - mstore(decoded, extractBytes(a, n)) // `authenticatorData`. - mstore(add(decoded, 0x20), extractBytes(c, sub(j, c))) // `clientDataJSON`. - mstore(add(decoded, 0x40), shr(240, mload(j))) // `challengeIndex`. - mstore(add(decoded, 0x60), shr(240, mload(add(j, 0x02)))) // `typeIndex`. - mstore(add(decoded, 0x80), mload(add(j, 0x04))) // `r`. - mstore(add(decoded, 0xa0), mload(add(j, 0x24))) // `s`. - } - } - } - } - - /// @dev Calldata variant of `tryDecodeAuthCompact`. - function tryDecodeAuthCompactCalldata(bytes calldata encodedAuth) - internal - pure - returns (WebAuthnAuth memory decoded) - { - /// @solidity memory-safe-assembly - assembly { - function extractBytes(o_, l_) -> _m { - _m := mload(0x40) // Grab the free memory pointer. - let s_ := add(_m, 0x20) - calldatacopy(s_, o_, l_) - mstore(_m, l_) // Store the length. - mstore(add(l_, s_), 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, add(l_, s_))) // Allocate memory. - } - if iszero(lt(encodedAuth.length, 0x46)) { - let e := add(encodedAuth.offset, encodedAuth.length) // End of `encodedAuth`. - let n := shr(240, calldataload(encodedAuth.offset)) // Length of `authenticatorData`. - let a := add(encodedAuth.offset, 0x02) // Start of `authenticatorData`. - let c := add(a, n) // Start of `clientDataJSON`. - let j := sub(e, 0x44) // Start of `challengeIndex`. - if iszero(gt(c, j)) { - mstore(decoded, extractBytes(a, n)) // `authenticatorData`. - mstore(add(decoded, 0x20), extractBytes(c, sub(j, c))) // `clientDataJSON`. - mstore(add(decoded, 0x40), shr(240, calldataload(j))) // `challengeIndex`. - mstore(add(decoded, 0x60), shr(240, calldataload(add(j, 0x02)))) // `typeIndex`. - mstore(add(decoded, 0x80), calldataload(add(j, 0x04))) // `r`. - mstore(add(decoded, 0xa0), calldataload(add(j, 0x24))) // `s`. - } - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/delegatexyz/DelegateCheckerLib.sol b/grouperBot/lib/solady/src/utils/ext/delegatexyz/DelegateCheckerLib.sol deleted file mode 100644 index 7ca3eb2..0000000 --- a/grouperBot/lib/solady/src/utils/ext/delegatexyz/DelegateCheckerLib.sol +++ /dev/null @@ -1,341 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for efficient querying of the delegate registries. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/delegate/DelegateCheckerLib.sol) -library DelegateCheckerLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The canonical delegate registry V1. - /// See: https://etherscan.io/address/0x00000000000076a84fef008cdabe6409d2fe638b - address internal constant DELEGATE_REGISTRY_V1 = 0x00000000000076A84feF008CDAbe6409d2FE638B; - - /// @dev The canonical delegate registry V2. - /// See: https://etherscan.io/address/0x00000000000000447e69651d841bD8D104Bed493 - address internal constant DELEGATE_REGISTRY_V2 = 0x00000000000000447e69651d841bD8D104Bed493; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DELEGATE CHECKING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: - // - `to` is the delegate. Typically called the "hot wallet". - // - `from` is the grantor of the delegate rights. Typically called the "cold vault". - - /// @dev Returns if `to` is a delegate of `from`. - /// ``` - /// v2.checkDelegateForAll(to, from, "") || - /// v1.checkDelegateForAll(to, from) - /// ``` - function checkDelegateForAll(address to, address from) internal view returns (bool isValid) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - // `0x60` is already 0. - mstore(0x40, from) - mstore(0x2c, shl(96, to)) - mstore(0x0c, 0xe839bd53000000000000000000000000) // `checkDelegateForAll(address,address,bytes32)`. - isValid := eq(mload(staticcall(gas(), DELEGATE_REGISTRY_V2, 0x1c, 0x64, 0x01, 0x20)), 1) - if iszero(isValid) { - mstore(0x01, 0x9c395bc200) // `checkDelegateForAll(address,address)`. - isValid := - eq(mload(staticcall(gas(), DELEGATE_REGISTRY_V1, 0x1c, 0x44, 0x01, 0x20)), 1) - } - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Returns if `to` is a delegate of `from`. - /// ``` - /// v2.checkDelegateForAll(to, from, rights) || - /// (rights == "" && v1.checkDelegateForAll(to, from)) - /// ``` - function checkDelegateForAll(address to, address from, bytes32 rights) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(0x60, rights) - mstore(0x40, from) - mstore(0x2c, shl(96, to)) - mstore(0x0c, 0xe839bd53000000000000000000000000) // `checkDelegateForAll(address,address,bytes32)`. - isValid := eq(mload(staticcall(gas(), DELEGATE_REGISTRY_V2, 0x1c, 0x64, 0x01, 0x20)), 1) - if iszero(or(rights, isValid)) { - mstore(0x01, 0x9c395bc200) // `checkDelegateForAll(address,address)`. - isValid := - eq(mload(staticcall(gas(), DELEGATE_REGISTRY_V1, 0x1c, 0x44, 0x01, 0x20)), 1) - } - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_`. - /// ``` - /// v2.checkDelegateForContract(to, from, contract_, "") || - /// v1.checkDelegateForContract(to, from, contract_) - /// ``` - /// Returns true if `checkDelegateForAll(to, from)` returns true. - function checkDelegateForContract(address to, address from, address contract_) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0x80, m), 0) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForContract(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0x8988eea9000000000000000000000000) - isValid := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0x84, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - if iszero(isValid) { - mstore(m, 0x90c9a2d0) // `checkDelegateForContract(address,address,address)`. - isValid := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x64, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_`. - /// ``` - /// v2.checkDelegateForContract(to, from, contract_, rights) || - /// (rights == "" && v1.checkDelegateForContract(to, from, contract_)) - /// ``` - /// Returns true if `checkDelegateForAll(to, from, rights)` returns true. - function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0x80, m), rights) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForContract(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0x8988eea9000000000000000000000000) - isValid := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0x84, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - if iszero(or(rights, isValid)) { - mstore(m, 0x90c9a2d0) // `checkDelegateForContract(address,address,address)`. - isValid := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x64, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_` and token `id`. - /// ``` - /// v2.checkDelegateForERC721(to, from, contract_, id, "") || - /// v1.checkDelegateForToken(to, from, contract_, id) - /// ``` - /// Returns true if `checkDelegateForContract(to, from, contract_)` returns true. - function checkDelegateForERC721(address to, address from, address contract_, uint256 id) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0xa0, m), 0) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC721(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb9f36874000000000000000000000000) - isValid := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0xa4, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - if iszero(isValid) { - mstore(m, 0xaba69cf8) // `checkDelegateForToken(address,address,address,uint256)`. - isValid := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x84, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_` and token `id`. - /// ``` - /// v2.checkDelegateForERC721(to, from, contract_, id, rights) || - /// (rights == "" && v1.checkDelegateForToken(to, from, contract_, id)) - /// ``` - /// Returns true if `checkDelegateForContract(to, from, contract_, rights)` returns true. - function checkDelegateForERC721( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal view returns (bool isValid) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0xa0, m), rights) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC721(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb9f36874000000000000000000000000) - isValid := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0xa4, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - if iszero(or(rights, isValid)) { - mstore(m, 0xaba69cf8) // `checkDelegateForToken(address,address,address,uint256)`. - isValid := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x84, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - } - - /// @dev Returns the amount of an ERC20 token for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// max( - /// v2.checkDelegateForERC20(to, from, contract_, ""), - /// v1.checkDelegateForContract(to, from, contract_) ? type(uint256).max : 0 - /// ) - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_)` returns true. - function checkDelegateForERC20(address to, address from, address contract_) - internal - view - returns (uint256 amount) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let o := add(0x80, m) - mstore(o, 0) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC20(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0xba63c817000000000000000000000000) - amount := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0x84, o, 0x20) - amount := mul(mload(o), amount) - if not(amount) { - mstore(m, 0x90c9a2d0) // `checkDelegateForContract(address,address,address)`. - let t := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x64, m, 0x20) - amount := or(sub(0, and(eq(mload(m), 1), t)), amount) - } - } - } - - /// @dev Returns the amount of an ERC20 token for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// max( - /// v2.checkDelegateForERC20(to, from, contract_, rights), - /// (rights == "" && v1.checkDelegateForContract(to, from, contract_)) ? type(uint256).max : 0 - /// ) - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_, rights)` returns true. - function checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) - internal - view - returns (uint256 amount) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(0x00, 0) - mstore(add(0x80, m), rights) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC20(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0xba63c817000000000000000000000000) - amount := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0x84, 0x00, 0x20) - amount := mul(mload(0x00), amount) - if iszero(or(rights, iszero(not(amount)))) { - mstore(m, 0x90c9a2d0) // `checkDelegateForContract(address,address,address)`. - let t := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x64, m, 0x20) - amount := or(sub(0, and(eq(mload(m), 1), t)), amount) - } - } - } - - /// @dev Returns the amount of an ERC1155 token `id` for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// max( - /// v2.checkDelegateForERC1155(to, from, contract_, id, ""), - /// v1.checkDelegateForContract(to, from, contract_, id) ? type(uint256).max : 0 - /// ) - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_)` returns true. - function checkDelegateForERC1155(address to, address from, address contract_, uint256 id) - internal - view - returns (uint256 amount) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let o := add(0xa0, m) - mstore(o, 0) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC1155(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb8705875000000000000000000000000) - amount := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0xa4, o, 0x20) - amount := mul(mload(o), amount) - if not(amount) { - mstore(m, 0x90c9a2d0) // `checkDelegateForContract(address,address,address)`. - let t := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x64, m, 0x20) - amount := or(sub(0, and(eq(mload(m), 1), t)), amount) - } - } - } - - /// @dev Returns the amount of an ERC1155 token `id` for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// max( - /// v2.checkDelegateForERC1155(to, from, contract_, id, rights), - /// (rights == "" && v1.checkDelegateForContract(to, from, contract_, id)) ? type(uint256).max : 0 - /// ) - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_, rights)` returns true. - function checkDelegateForERC1155( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal view returns (uint256 amount) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(0x00, 0) - mstore(add(0xa0, m), rights) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC1155(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb8705875000000000000000000000000) - amount := staticcall(gas(), DELEGATE_REGISTRY_V2, add(m, 0x1c), 0xa4, 0x00, 0x20) - amount := mul(mload(0x00), amount) - if iszero(or(rights, iszero(not(amount)))) { - mstore(m, 0x90c9a2d0) // `checkDelegateForContract(address,address,address)`. - let t := staticcall(gas(), DELEGATE_REGISTRY_V1, add(m, 0x1c), 0x64, m, 0x20) - amount := or(sub(0, and(eq(mload(m), 1), t)), amount) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/ithaca/BLS.sol b/grouperBot/lib/solady/src/utils/ext/ithaca/BLS.sol deleted file mode 100644 index 8c21ad9..0000000 --- a/grouperBot/lib/solady/src/utils/ext/ithaca/BLS.sol +++ /dev/null @@ -1,354 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -/// @notice BLS wrapper. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/BLS.sol) -/// @author Ithaca (https://github.com/ithacaxyz/odyssey-examples/blob/main/chapter1/contracts/src/libraries/BLS.sol) -/// -/// @dev Precompile addresses come from the BLS addresses submodule in AlphaNet, see -/// See: (https://github.com/paradigmxyz/alphanet/blob/main/crates/precompile/src/addresses.rs) -/// -/// Note: -/// - This implementation uses `mcopy`, since any chain that is edgy enough to -/// implement the BLS precompiles will definitely have implemented cancun. -/// - For efficiency, we use the legacy `staticcall` to call the precompiles. -/// For the intended use case in an entry points that requires gas-introspection, -/// which requires legacy bytecode, this won't be a blocker. -library BLS { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRUCTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // We use flattened structs to make encoding more efficient. - // All structs use Big endian encoding. - // See: https://eips.ethereum.org/EIPS/eip-2537 - - /// @dev A representation of a base field element (Fp) in the BLS12-381 curve. - /// Due to the size of `p`, - /// `0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab` - /// the top 16 bytes are always zeroes. - struct Fp { - bytes32 a; // Upper 32 bytes. - bytes32 b; // Lower 32 bytes. - } - - /// @dev A representation of an extension field element (Fp2) in the BLS12-381 curve. - struct Fp2 { - bytes32 c0_a; - bytes32 c0_b; - bytes32 c1_a; - bytes32 c1_b; - } - - /// @dev A representation of a point on the G1 curve of BLS12-381. - struct G1Point { - bytes32 x_a; - bytes32 x_b; - bytes32 y_a; - bytes32 y_b; - } - - /// @dev A representation of a point on the G2 curve of BLS12-381. - struct G2Point { - bytes32 x_c0_a; - bytes32 x_c0_b; - bytes32 x_c1_a; - bytes32 x_c1_b; - bytes32 y_c0_a; - bytes32 y_c0_b; - bytes32 y_c1_a; - bytes32 y_c1_b; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRECOMPILE ADDRESSES */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev For addition of two points on the BLS12-381 G1 curve, - address internal constant BLS12_G1ADD = 0x000000000000000000000000000000000000000b; - - /// @dev For multi-scalar multiplication (MSM) on the BLS12-381 G1 curve. - address internal constant BLS12_G1MSM = 0x000000000000000000000000000000000000000C; - - /// @dev For addition of two points on the BLS12-381 G2 curve. - address internal constant BLS12_G2ADD = 0x000000000000000000000000000000000000000d; - - /// @dev For multi-scalar multiplication (MSM) on the BLS12-381 G2 curve. - address internal constant BLS12_G2MSM = 0x000000000000000000000000000000000000000E; - - /// @dev For performing a pairing check on the BLS12-381 curve. - address internal constant BLS12_PAIRING_CHECK = 0x000000000000000000000000000000000000000F; - - /// @dev For mapping a Fp to a point on the BLS12-381 G1 curve. - address internal constant BLS12_MAP_FP_TO_G1 = 0x0000000000000000000000000000000000000010; - - /// @dev For mapping a Fp2 to a point on the BLS12-381 G2 curve. - address internal constant BLS12_MAP_FP2_TO_G2 = 0x0000000000000000000000000000000000000011; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // A custom error for each precompile helps us in debugging which precompile has failed. - - /// @dev The G1Add operation failed. - error G1AddFailed(); - - /// @dev The G1MSM operation failed. - error G1MSMFailed(); - - /// @dev The G2Add operation failed. - error G2AddFailed(); - - /// @dev The G2MSM operation failed. - error G2MSMFailed(); - - /// @dev The pairing operation failed. - error PairingFailed(); - - /// @dev The MapFpToG1 operation failed. - error MapFpToG1Failed(); - - /// @dev The MapFpToG2 operation failed. - error MapFp2ToG2Failed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Adds two G1 points. Returns a new G1 point. - function add(G1Point memory point0, G1Point memory point1) - internal - view - returns (G1Point memory result) - { - assembly ("memory-safe") { - mcopy(result, point0, 0x80) - mcopy(add(result, 0x80), point1, 0x80) - if iszero( - and( - eq(returndatasize(), 0x80), - staticcall(gas(), BLS12_G1ADD, result, 0x100, result, 0x80) - ) - ) { - mstore(0x00, 0xd6cc76eb) // `G1AddFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Multi-scalar multiplication of G1 points with scalars. Returns a new G1 point. - function msm(G1Point[] memory points, bytes32[] memory scalars) - internal - view - returns (G1Point memory result) - { - assembly ("memory-safe") { - let k := mload(points) - let d := sub(scalars, points) - for { let i := 0 } iszero(eq(i, k)) { i := add(i, 1) } { - points := add(points, 0x20) - let o := add(result, mul(0xa0, i)) - mcopy(o, mload(points), 0x80) - mstore(add(o, 0x80), mload(add(points, d))) - } - if iszero( - and( - and(eq(k, mload(scalars)), eq(returndatasize(), 0x80)), - staticcall(gas(), BLS12_G1MSM, result, mul(0xa0, k), result, 0x80) - ) - ) { - mstore(0x00, 0x5f776986) // `G1MSMFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Adds two G2 points. Returns a new G2 point. - function add(G2Point memory point0, G2Point memory point1) - internal - view - returns (G2Point memory result) - { - assembly ("memory-safe") { - mcopy(result, point0, 0x100) - mcopy(add(result, 0x100), point1, 0x100) - if iszero( - and( - eq(returndatasize(), 0x100), - staticcall(gas(), BLS12_G2ADD, result, 0x200, result, 0x100) - ) - ) { - mstore(0x00, 0xc55e5e33) // `G2AddFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Multi-scalar multiplication of G2 points with scalars. Returns a new G2 point. - function msm(G2Point[] memory points, bytes32[] memory scalars) - internal - view - returns (G2Point memory result) - { - assembly ("memory-safe") { - let k := mload(points) - let d := sub(scalars, points) - for { let i := 0 } iszero(eq(i, k)) { i := add(i, 1) } { - points := add(points, 0x20) - let o := add(result, mul(0x120, i)) - mcopy(o, mload(points), 0x100) - mstore(add(o, 0x100), mload(add(d, points))) - } - if iszero( - and( - and(eq(k, mload(scalars)), eq(returndatasize(), 0x100)), - staticcall(gas(), BLS12_G2MSM, result, mul(0x120, k), result, 0x100) - ) - ) { - mstore(0x00, 0xe3dc5425) // `G2MSMFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Checks the pairing of G1 points with G2 points. Returns whether the pairing is valid. - function pairing(G1Point[] memory g1Points, G2Point[] memory g2Points) - internal - view - returns (bool result) - { - assembly ("memory-safe") { - let k := mload(g1Points) - let m := mload(0x40) - let d := sub(g2Points, g1Points) - for { let i := 0 } iszero(eq(i, k)) { i := add(i, 1) } { - g1Points := add(g1Points, 0x20) - let o := add(m, mul(0x180, i)) - mcopy(o, mload(g1Points), 0x80) - mcopy(add(o, 0x80), mload(add(d, g1Points)), 0x100) - } - if iszero( - and( - and(eq(k, mload(g2Points)), eq(returndatasize(), 0x20)), - staticcall(gas(), BLS12_PAIRING_CHECK, m, mul(0x180, k), 0x00, 0x20) - ) - ) { - mstore(0x00, 0x4df45e2f) // `PairingFailed()`. - revert(0x1c, 0x04) - } - result := mload(0x00) - } - } - - /// @dev Maps a Fp element to a G1 point. - function toG1(Fp memory element) internal view returns (G1Point memory result) { - assembly ("memory-safe") { - if iszero( - and( - eq(returndatasize(), 0x80), - staticcall(gas(), BLS12_MAP_FP_TO_G1, element, 0x40, result, 0x80) - ) - ) { - mstore(0x00, 0x24a289fc) // `MapFpToG1Failed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Maps a Fp2 element to a G2 point. - function toG2(Fp2 memory element) internal view returns (G2Point memory result) { - assembly ("memory-safe") { - if iszero( - and( - eq(returndatasize(), 0x100), - staticcall(gas(), BLS12_MAP_FP2_TO_G2, element, 0x80, result, 0x100) - ) - ) { - mstore(0x00, 0x89083b91) // `MapFp2ToG2Failed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Computes a point in G2 from a message. - function hashToG2(bytes memory message) internal view returns (G2Point memory result) { - assembly ("memory-safe") { - function dstPrime(o_, i_) -> _o { - mstore8(o_, i_) // 1. - mstore(add(o_, 0x01), "BLS_SIG_BLS12381G2_XMD:SHA-256_S") // 32. - mstore(add(o_, 0x21), "SWU_RO_NUL_\x2b") // 12. - _o := add(0x2d, o_) - } - - function sha2(data_, n_) -> _h { - if iszero( - and(eq(returndatasize(), 0x20), staticcall(gas(), 2, data_, n_, 0x00, 0x20)) - ) { revert(calldatasize(), 0x00) } - _h := mload(0x00) - } - - function modfield(s_, b_) { - mcopy(add(s_, 0x60), b_, 0x40) - if iszero( - and(eq(returndatasize(), 0x40), staticcall(gas(), 5, s_, 0x100, b_, 0x40)) - ) { revert(calldatasize(), 0x00) } - } - - function mapToG2(s_, r_) { - if iszero( - and( - eq(returndatasize(), 0x100), - staticcall(gas(), BLS12_MAP_FP2_TO_G2, s_, 0x80, r_, 0x100) - ) - ) { - mstore(0x00, 0x89083b91) // `MapFp2ToG2Failed()`. - revert(0x1c, 0x04) - } - } - - let b := mload(0x40) - let s := add(b, 0x100) - calldatacopy(s, calldatasize(), 0x40) - mcopy(add(0x40, s), add(0x20, message), mload(message)) - let o := add(add(0x40, s), mload(message)) - mstore(o, shl(240, 256)) - let b0 := sha2(s, sub(dstPrime(add(0x02, o), 0), s)) - mstore(0x20, b0) - mstore(s, b0) - mstore(b, sha2(s, sub(dstPrime(add(0x20, s), 1), s))) - let j := b - for { let i := 2 } 1 {} { - mstore(s, xor(b0, mload(j))) - j := add(j, 0x20) - mstore(j, sha2(s, sub(dstPrime(add(0x20, s), i), s))) - i := add(i, 1) - if eq(i, 9) { break } - } - - mstore(add(s, 0x00), 0x40) - mstore(add(s, 0x20), 0x20) - mstore(add(s, 0x40), 0x40) - mstore(add(s, 0xa0), 1) - mstore(add(s, 0xc0), 0x000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd7) - mstore(add(s, 0xe0), 0x64774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab) - modfield(s, add(b, 0x00)) - modfield(s, add(b, 0x40)) - modfield(s, add(b, 0x80)) - modfield(s, add(b, 0xc0)) - - mapToG2(b, result) - mapToG2(add(0x80, b), add(0x100, result)) - - if iszero( - and( - eq(returndatasize(), 0x100), - staticcall(gas(), BLS12_G2ADD, result, 0x200, result, 0x100) - ) - ) { - mstore(0x00, 0xc55e5e33) // `G2AddFailed()`. - revert(0x1c, 0x04) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967BeaconProxy.sol b/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967BeaconProxy.sol deleted file mode 100644 index ad7f5fe..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967BeaconProxy.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice A sufficiently minimal ERC1967 beacon proxy tailor-made for ZKsync. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/ERC1967BeaconProxy.sol) -contract ERC1967BeaconProxy { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when the proxy's beacon is upgraded. - event BeaconUpgraded(address indexed beacon); - - /// @dev `keccak256(bytes("BeaconUpgraded(address)"))`. - uint256 private constant _BEACON_UPGRADED_EVENT_SIGNATURE = - 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. - bytes32 internal constant _ERC1967_BEACON_SLOT = - 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; - - /// @dev The storage slot for the deployer. - /// `uint256(keccak256("ERC1967BeaconProxy.deployer")) - 1`. - bytes32 internal constant _ERC1967_BEACON_PROXY_DEPLOYER_SLOT = - 0xabc1f855dddf3277214739f5a08d8b9db61505a97fd0c09e835a2d800705b3bc; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor() payable { - /// @solidity memory-safe-assembly - assembly { - sstore(_ERC1967_BEACON_PROXY_DEPLOYER_SLOT, caller()) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* FALLBACK */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - fallback() external payable virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, 0) // Optimization trick to remove free memory pointer initialization. - // For the special case of 1-byte calldata, return the implementation. - if eq(calldatasize(), 1) { - mstore(0x00, 0x5c60da1b) // `implementation()`. - let s := staticcall(gas(), sload(_ERC1967_BEACON_SLOT), 0x1c, 0x04, 0x00, 0x20) - if iszero(and(gt(returndatasize(), 0x1f), s)) { revert(0x00, 0x00) } - return(0x00, 0x20) // Return the implementation. - } - // Deployer workflow. - if eq(caller(), sload(_ERC1967_BEACON_PROXY_DEPLOYER_SLOT)) { - sstore(_ERC1967_BEACON_SLOT, calldataload(0x00)) - // Emit the {Upgraded} event. - log2(0x00, 0x00, _BEACON_UPGRADED_EVENT_SIGNATURE, calldataload(0x00)) - stop() // End the context. - } - // Query the beacon. - mstore(0x00, 0x5c60da1b) // `implementation()`. - let s := staticcall(gas(), sload(_ERC1967_BEACON_SLOT), 0x1c, 0x04, 0x00, 0x20) - if iszero(and(gt(returndatasize(), 0x1f), s)) { revert(0x00, 0x00) } - let implementation := mload(0x00) - // Perform the delegatecall. - calldatacopy(0x00, 0x00, calldatasize()) - s := delegatecall(gas(), implementation, 0x00, calldatasize(), 0x00, 0x00) - returndatacopy(0x00, 0x00, returndatasize()) - if iszero(s) { revert(0x00, returndatasize()) } - return(0x00, returndatasize()) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967Factory.sol b/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967Factory.sol deleted file mode 100644 index 4637e6f..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967Factory.sol +++ /dev/null @@ -1,457 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC1967Proxy} from "./ERC1967Proxy.sol"; -import {UpgradeableBeacon} from "./UpgradeableBeacon.sol"; -import {ERC1967BeaconProxy} from "./ERC1967BeaconProxy.sol"; - -/// @notice A factory for deploying minimal ERC1967 proxies on ZKsync. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/ERC1967Factory.sol) -/// -/// @dev This factory can be used in one of the following ways: -/// 1. Deploying a fresh copy with each contract. -/// Easier to test. In ZKsync VM, factory dependency bytecode is not included in the -/// factory bytecode, so you do not need to worry too much about bytecode size limits. -/// 2. Loading it from a storage variable which is set to the canonical address. -/// See: ERC1967FactoryConstants.ADDRESS. -/// -/// This factory is crafted to be compatible with both ZKsync VM and regular EVM. -/// This is so that when ZKsync achieves full EVM equivalence, -/// this factory can still be used via the fresh copy per contract way. -contract ERC1967Factory { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The caller is not authorized to call the function. - error Unauthorized(); - - /// @dev The proxy deployment failed. - error DeploymentFailed(); - - /// @dev The upgrade failed. - error UpgradeFailed(); - - /// @dev The salt does not start with the caller. - error SaltDoesNotStartWithCaller(); - - /// @dev No initialization code hash exists for the instance hash. - error NoInitCodeHashFound(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The admin of a `instance` has been changed. Applies to both proxies and beacons. - event AdminChanged(address indexed instance, address indexed admin); - - /// @dev The implementation for `instance` has been upgraded. Applies to both proxies and beacons. - event Upgraded(address indexed instance, address indexed implementation); - - /// @dev A proxy has been deployed. - event ProxyDeployed( - address indexed proxy, address indexed implementation, address indexed admin - ); - - /// @dev A beacon has been deployed. - event BeaconDeployed( - address indexed beacon, address indexed implementation, address indexed admin - ); - - /// @dev A beacon proxy has been deployed. - event BeaconProxyDeployed(address indexed beaconProxy, address indexed beacon); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The hash of the proxy. - bytes32 public proxyHash; - - /// @dev The hash of the upgradeable beacon. - bytes32 public beaconHash; - - /// @dev The hash of the beacon proxy. - bytes32 public beaconProxyHash; - - /// @dev Whether to use the CREATE2 address prediction workflow for ZKsync VM. - bool internal _useZKsyncCreate2Prediction; - - /// @dev Maps the instance hash to the initialization code hash. - mapping(bytes32 => bytes32) internal _initCodeHashes; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor() payable { - bytes32 proxySalt = keccak256(abi.encode(address(this), bytes32("proxySalt"))); - address proxyAddress = address(new ERC1967Proxy{salt: proxySalt}()); - - proxyHash = _extcodehash(proxyAddress); - beaconHash = _extcodehash(address(new UpgradeableBeacon())); - beaconProxyHash = _extcodehash(address(new ERC1967BeaconProxy())); - - if (_predictDeterministicAddressZKsync(proxyHash, proxySalt) == proxyAddress) { - _useZKsyncCreate2Prediction = true; - } else { - _initCodeHashes[proxyHash] = keccak256(type(ERC1967Proxy).creationCode); - _initCodeHashes[beaconHash] = keccak256(type(UpgradeableBeacon).creationCode); - _initCodeHashes[beaconProxyHash] = keccak256(type(ERC1967BeaconProxy).creationCode); - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ADMIN FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the admin of the `instance`. - /// Returns `address(0)` if `instance` is a beacon proxy. - /// Works for both proxies and beacons. - function adminOf(address instance) public view returns (address admin) { - /// @solidity memory-safe-assembly - assembly { - admin := mul(sload(instance), gt(instance, 0xff)) - } - } - - /// @dev Sets the admin of the `instance`. - /// The caller of this function must be the admin of `instance`. - /// Works for both proxies and beacons. - function changeAdmin(address instance, address admin) public { - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(sload(instance), caller())) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - sstore(instance, admin) - } - emit AdminChanged(instance, admin); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UPGRADE FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Upgrades `instance` to point to `implementation`. - /// The caller of this function must be the admin of `instance`. - /// Works for both proxies and beacons. - function upgrade(address instance, address implementation) public payable { - upgradeAndCall(instance, implementation, _emptyData()); - } - - /// @dev Upgrades `instance` to point to `implementation`. - /// Then, calls it with abi encoded `data`. - /// The caller of this function must be the admin of `instance`. - /// Works for both proxies and beacons. - function upgradeAndCall(address instance, address implementation, bytes calldata data) - public - payable - { - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(sload(instance), caller())) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - let m := mload(0x40) - mstore(m, implementation) - calldatacopy(add(m, 0x20), data.offset, data.length) - if iszero(call(gas(), instance, callvalue(), m, add(0x20, data.length), 0x00, 0x00)) { - if iszero(returndatasize()) { - mstore(0x00, 0x55299b49) // `UpgradeFailed()`. - revert(0x1c, 0x04) - } - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - } - emit Upgraded(instance, implementation); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PROXY DEPLOYMENT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a proxy for `implementation`, with `admin`, and returns its address. - /// The value passed into this function will be forwarded to the proxu. - function deployProxy(address implementation, address admin) public payable returns (address) { - return deployProxyAndCall(implementation, admin, _emptyData()); - } - - /// @dev Deploys a proxy for `implementation`, with `admin`, and returns its address. - /// The value passed into this function will be forwarded to the proxu. - /// Then, calls the proxy with abi encoded `data`. - function deployProxyAndCall(address implementation, address admin, bytes calldata data) - public - payable - returns (address) - { - return _deploy(0, uint160(implementation), uint160(admin), "", false, data); - } - - /// @dev Deploys a proxy for `implementation`, with `admin`, `salt`, - /// and returns its deterministic address. - /// The value passed into this function will be forwarded to the proxy. - function deployProxyDeterministic(address implementation, address admin, bytes32 salt) - public - payable - returns (address) - { - return deployProxyDeterministicAndCall(implementation, admin, salt, _emptyData()); - } - - /// @dev Deploys a proxy for `implementation`, with `admin`, `salt`, - /// and returns its deterministic address. - /// The value passed into this function will be forwarded to the proxy. - /// Then, calls the proxy with abi encoded `data`. - function deployProxyDeterministicAndCall( - address implementation, - address admin, - bytes32 salt, - bytes calldata data - ) public payable returns (address) { - return _deploy(0, uint160(implementation), uint160(admin), salt, true, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BEACON DEPLOYMENT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a beacon with `implementation` and `admin`, and returns its address. - function deployBeacon(address implementation, address admin) public returns (address) { - return _deploy(1, uint160(implementation), uint160(admin), "", false, _emptyData()); - } - - /// @dev Deploys a beacon with `implementation` and `admin`, with `salt`, - /// and returns its deterministic address. - function deployBeaconDeterministic(address implementation, address admin, bytes32 salt) - public - payable - returns (address) - { - return _deploy(1, uint160(implementation), uint160(admin), salt, true, _emptyData()); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BEACON PROXY DEPLOYMENT */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Deploys a beacon proxy referring to `beacon`, and returns its address. - /// The value passed into this function will be forwarded to the beacon proxy. - function deployBeaconProxy(address beacon) public payable returns (address) { - return deployBeaconProxyAndCall(beacon, _emptyData()); - } - - /// @dev Deploys a beacon proxy referring to `beacon`, and returns its address. - /// The value passed into this function will be forwarded to the beacon proxy. - /// Then, calls the beacon proxy with abi encoded `data`. - function deployBeaconProxyAndCall(address beacon, bytes calldata data) - public - payable - returns (address) - { - return _deploy(2, uint160(beacon), 0, "", false, data); - } - - /// @dev Deploys a beacon proxy referring to `beacon`, with `salt`, - /// and returns its deterministic address. - /// The value passed into this function will be forwarded to the beacon proxy. - function deployBeaconProxyDeterministic(address beacon, bytes32 salt) - public - payable - returns (address) - { - return deployBeaconProxyDeterministicAndCall(beacon, salt, _emptyData()); - } - - /// @dev Deploys a beacon proxy referring to `beacon`, with `salt`, - /// and returns its deterministic address. - /// The value passed into this function will be forwarded to the beacon proxy. - /// Then, calls the beacon proxy with abi encoded `data`. - function deployBeaconProxyDeterministicAndCall( - address beacon, - bytes32 salt, - bytes calldata data - ) public payable returns (address) { - return _deploy(2, uint160(beacon), 0, salt, true, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PUBLIC HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the address of the instance deployed with `salt`. - /// `instanceHash` is one of `proxyHash`, `beaconProxyHash`, `beaconHash`. - function predictDeterministicAddress(bytes32 instanceHash, bytes32 salt) - public - view - returns (address) - { - if (_useZKsyncCreate2Prediction) { - return _predictDeterministicAddressZKsync(instanceHash, salt); - } - return _predictDeterministicAddressRegularEVM(instanceHash, salt); - } - - /// @dev Returns the implementation of `instance`. - /// If `instance` is not deployed, returns `address(0)`. - function implementationOf(address instance) public view returns (address result) { - bytes32 h = _extcodehash(instance); - if (h == proxyHash || h == beaconProxyHash) { - /// @solidity memory-safe-assembly - assembly { - let s := staticcall(gas(), instance, 0x00, 0x01, 0x00, 0x20) - if iszero(and(gt(returndatasize(), 0x1f), s)) { revert(0x00, 0x00) } - result := mload(0x00) - } - } else if (h == beaconHash) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x5c60da1b) // `implementation()`. - let s := staticcall(gas(), instance, 0x1c, 0x04, 0x00, 0x20) - if iszero(and(gt(returndatasize(), 0x1f), s)) { revert(0x00, 0x00) } - result := mload(0x00) - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INTERNAL HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Validates the salt and returns it. - function _validateSalt(bytes32 salt) internal view returns (bytes32) { - /// @solidity memory-safe-assembly - assembly { - // If the salt does not start with the zero address or the caller. - if iszero(or(iszero(shr(96, salt)), eq(caller(), shr(96, salt)))) { - mstore(0x00, 0x2f634836) // `SaltDoesNotStartWithCaller()`. - revert(0x1c, 0x04) - } - } - return salt; - } - - /// @dev Performs the deployment optionality to deploy deterministically with a `salt`. - function _deploy( - uint256 codeType, - uint256 target, - uint256 admin, - bytes32 salt, - bool useSalt, - bytes calldata data - ) internal returns (address instance) { - if (codeType == 0) { - instance = address( - useSalt ? new ERC1967Proxy{salt: _validateSalt(salt)}() : new ERC1967Proxy() - ); - /// @solidity memory-safe-assembly - assembly { - sstore(instance, admin) - } - emit ProxyDeployed(instance, address(uint160(target)), address(uint160(admin))); - } else if (codeType == 1) { - instance = address( - useSalt - ? new UpgradeableBeacon{salt: _validateSalt(salt)}() - : new UpgradeableBeacon() - ); - /// @solidity memory-safe-assembly - assembly { - sstore(instance, admin) - } - emit BeaconDeployed(instance, address(uint160(target)), address(uint160(admin))); - } else { - instance = address( - useSalt - ? new ERC1967BeaconProxy{salt: _validateSalt(salt)}() - : new ERC1967BeaconProxy() - ); - emit BeaconProxyDeployed(instance, address(uint160(target))); - } - /// @solidity memory-safe-assembly - assembly { - // Revert if the creation fails. - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - // Make the initialization call. - let m := mload(0x40) - mstore(m, target) - calldatacopy(add(m, 0x20), data.offset, data.length) - if iszero(call(gas(), instance, callvalue(), m, add(0x20, data.length), 0x00, 0x00)) { - // Revert with the `DeploymentFailed` selector if there is no error returndata. - if iszero(returndatasize()) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - // Otherwise, bubble up the returned error. - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - } - } - - /// @dev Returns the `extcodehash` of `instance`. - function _extcodehash(address instance) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := extcodehash(instance) - } - } - - /// @dev Helper function to return an empty bytes calldata. - function _emptyData() internal pure returns (bytes calldata data) { - /// @solidity memory-safe-assembly - assembly { - data.length := 0 - } - } - - /// @dev Returns the predicted `CREATE2` address on ZKsync VM. - function _predictDeterministicAddressZKsync(bytes32 instanceHash, bytes32 salt) - internal - view - returns (address predicted) - { - bytes32 prefix = keccak256("zksyncCreate2"); - bytes32 emptyStringHash = keccak256(""); - /// @solidity memory-safe-assembly - assembly { - // The following is `keccak256(abi.encode(...))`. - let m := mload(0x40) - mstore(m, prefix) - mstore(add(m, 0x20), address()) - mstore(add(m, 0x40), salt) - mstore(add(m, 0x60), instanceHash) - mstore(add(m, 0x80), emptyStringHash) - predicted := keccak256(m, 0xa0) - } - } - - /// @dev Returns the predicted `CREATE2` address on regular EVM. - function _predictDeterministicAddressRegularEVM(bytes32 instanceHash, bytes32 salt) - internal - view - returns (address predicted) - { - bytes32 initCodeHash = _initCodeHashes[instanceHash]; - /// @solidity memory-safe-assembly - assembly { - if iszero(initCodeHash) { - mstore(0x00, 0xa3a58d1c) // `NoInitCodeHashFound()`. - revert(0x1c, 0x04) - } - // The following is `keccak256(abi.encodePacked(...))`. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, initCodeHash) - mstore(0x01, shl(96, address())) - mstore(0x15, salt) - predicted := keccak256(0x00, 0x55) - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967FactoryConstants.sol b/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967FactoryConstants.sol deleted file mode 100644 index 5a46fe0..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967FactoryConstants.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice The canonical address of the ERC1967Factory for ZKsync. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/ERC1967FactoryConstants.sol) -library ERC1967FactoryConstants { - /// @dev The canonical address for ERC1967Factory for ZKsync. - address internal constant ADDRESS = 0xc4151FeCa42Df507F158D1FBC4Eb5C145D9CE16B; -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967Proxy.sol b/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967Proxy.sol deleted file mode 100644 index 3c63458..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/ERC1967Proxy.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice A sufficiently minimal ERC1967 proxy tailor-made for ZKsync. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/ERC1967Proxy.sol) -contract ERC1967Proxy { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when the proxy's implementation is upgraded. - event Upgraded(address indexed implementation); - - /// @dev `keccak256(bytes("Upgraded(address)"))`. - uint256 private constant _UPGRADED_EVENT_SIGNATURE = - 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /// @dev The storage slot for the deployer. - /// `uint256(keccak256("ERC1967Proxy.deployer")) - 1`. - bytes32 internal constant _ERC1967_PROXY_DEPLOYER_SLOT = - 0xc20b8dda59e1f49cae9bbc6c3744edc7900ba02880cd7b33b5b82a96197202ba; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor() payable { - /// @solidity memory-safe-assembly - assembly { - sstore(_ERC1967_PROXY_DEPLOYER_SLOT, caller()) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* FALLBACK */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - fallback() external payable virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, 0) // Optimization trick to remove free memory pointer initialization. - // For the special case of 1-byte calldata, return the implementation. - if eq(calldatasize(), 1) { - mstore(0x00, sload(_ERC1967_IMPLEMENTATION_SLOT)) - return(0x00, 0x20) - } - // Deployer workflow. - if eq(caller(), sload(_ERC1967_PROXY_DEPLOYER_SLOT)) { - let newImplementation := calldataload(0x00) - sstore(_ERC1967_IMPLEMENTATION_SLOT, newImplementation) - if gt(calldatasize(), 0x20) { - let n := sub(calldatasize(), 0x20) - calldatacopy(0x00, 0x20, n) - if iszero(delegatecall(gas(), newImplementation, 0x00, n, 0x00, 0x00)) { - // Bubble up the revert if the call reverts. - returndatacopy(0x00, 0x00, returndatasize()) - revert(0x00, returndatasize()) - } - } - // Emit the {Upgraded} event. - log2(0x00, 0x00, _UPGRADED_EVENT_SIGNATURE, newImplementation) - stop() // End the context. - } - // Perform the delegatecall. - let implementation := sload(_ERC1967_IMPLEMENTATION_SLOT) - calldatacopy(0x00, 0x00, calldatasize()) - let s := delegatecall(gas(), implementation, 0x00, calldatasize(), 0x00, 0x00) - returndatacopy(0x00, 0x00, returndatasize()) - if iszero(s) { revert(0x00, returndatasize()) } - return(0x00, returndatasize()) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/SafeTransferLib.sol b/grouperBot/lib/solady/src/utils/ext/zksync/SafeTransferLib.sol deleted file mode 100644 index a968359..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/SafeTransferLib.sol +++ /dev/null @@ -1,387 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {SingleUseETHVault} from "./SingleUseETHVault.sol"; - -/// @notice Library for force safe transferring ETH and ERC20s in ZKsync. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/SafeTransferLib.sol) -library SafeTransferLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev A single use ETH vault has been created for `to`, with `amount`. - event SingleUseETHVaultCreated(address indexed to, uint256 amount, address vault); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The ETH transfer has failed. - error ETHTransferFailed(); - - /// @dev The ERC20 `transferFrom` has failed. - error TransferFromFailed(); - - /// @dev The ERC20 `transfer` has failed. - error TransferFailed(); - - /// @dev The ERC20 `approve` has failed. - error ApproveFailed(); - - /// @dev The ERC20 `totalSupply` query has failed. - error TotalSupplyQueryFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Suggested gas stipend for contract receiving ETH to perform a few - /// storage reads and writes, but low enough to prevent griefing. - uint256 internal constant GAS_STIPEND_NO_GRIEF = 1000000; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ETH OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants. - // - // The regular variants: - // - Forwards all remaining gas to the target. - // - Reverts if the target reverts. - // - Reverts if the current contract has insufficient balance. - // - // The force variants: - // - Forwards with an optional gas stipend - // (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases). - // - If the target reverts, or if the gas stipend is exhausted, - // creates a temporary contract to force send the ETH via `SELFDESTRUCT`. - // Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758. - // - Reverts if the current contract has insufficient balance. - // - // The try variants: - // - Forwards with a mandatory gas stipend. - // - Instead of reverting, returns whether the transfer succeeded. - - /// @dev Sends `amount` (in wei) ETH to `to`. - function safeTransferETH(address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - if iszero(call(gas(), to, amount, 0x00, 0x00, 0x00, 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Sends all the ETH in the current contract to `to`. - function safeTransferAllETH(address to) internal { - /// @solidity memory-safe-assembly - assembly { - // Transfer all the ETH and check if it succeeded or not. - if iszero(call(gas(), to, selfbalance(), 0x00, 0x00, 0x00, 0x00)) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`. - /// If force transfer is used, returns the vault. Else returns `address(0)`. - function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) - internal - returns (address vault) - { - if (amount == uint256(0)) return address(0); // Early return if `amount` is zero. - uint256 selfBalanceBefore = address(this).balance; - /// @solidity memory-safe-assembly - assembly { - if lt(selfBalanceBefore, amount) { - mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. - revert(0x1c, 0x04) - } - pop(call(gasStipend, to, amount, 0x00, 0x00, 0x00, 0x00)) - } - if (address(this).balance == selfBalanceBefore) { - vault = address(new SingleUseETHVault()); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, shr(96, shl(96, to))) - if iszero(call(gas(), vault, amount, 0x00, 0x20, 0x00, 0x00)) { revert(0x00, 0x00) } - } - emit SingleUseETHVaultCreated(to, amount, vault); - } - } - - /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`. - /// If force transfer is used, returns the vault. Else returns `address(0)`. - function forceSafeTransferAllETH(address to, uint256 gasStipend) - internal - returns (address vault) - { - vault = forceSafeTransferETH(to, address(this).balance, gasStipend); - } - - /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`. - /// If force transfer is used, returns the vault. Else returns `address(0)`. - function forceSafeTransferETH(address to, uint256 amount) internal returns (address vault) { - vault = forceSafeTransferETH(to, amount, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`. - /// If force transfer is used, returns the vault. Else returns `address(0)`. - function forceSafeTransferAllETH(address to) internal returns (address vault) { - vault = forceSafeTransferETH(to, address(this).balance, GAS_STIPEND_NO_GRIEF); - } - - /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`. - function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend) - internal - returns (bool success) - { - /// @solidity memory-safe-assembly - assembly { - success := call(gasStipend, to, amount, 0x00, 0x00, 0x00, 0x00) - } - } - - /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`. - function trySafeTransferAllETH(address to, uint256 gasStipend) - internal - returns (bool success) - { - /// @solidity memory-safe-assembly - assembly { - success := call(gasStipend, to, selfbalance(), 0x00, 0x00, 0x00, 0x00) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC20 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. - /// Reverts upon failure. - /// - /// 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 { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, amount) // Store the `amount` argument. - mstore(0x40, to) // Store the `to` argument. - mstore(0x2c, shl(96, from)) // Store the `from` argument. - mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`. - let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x7939f424) // `TransferFromFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. - /// - /// The `from` account must have at least `amount` approved for the current contract to manage. - function trySafeTransferFrom(address token, address from, address to, uint256 amount) - internal - returns (bool success) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x60, amount) // Store the `amount` argument. - mstore(0x40, to) // Store the `to` argument. - mstore(0x2c, shl(96, from)) // Store the `from` argument. - mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`. - success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - success := lt(or(iszero(extcodesize(token)), returndatasize()), success) - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Sends all of ERC20 `token` from `from` to `to`. - /// Reverts upon failure. - /// - /// The `from` account must have their entire balance approved for the current contract to manage. - 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. - mstore(0x40, to) // Store the `to` argument. - mstore(0x2c, shl(96, from)) // Store the `from` argument. - mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`. - // Read the balance, reverting upon failure. - if iszero( - and( // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x1f), // At least 32 bytes returned. - staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20) - ) - ) { - mstore(0x00, 0x7939f424) // `TransferFromFailed()`. - revert(0x1c, 0x04) - } - mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`. - amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it. - // Perform the transfer, reverting upon failure. - let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x7939f424) // `TransferFromFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x60, 0) // Restore the zero slot to zero. - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. - /// Reverts upon failure. - function safeTransfer(address token, address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`. - // Perform the transfer, reverting upon failure. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x90b8ec18) // `TransferFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @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) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`. - mstore(0x20, address()) // Store the address of the current contract. - // Read the balance, reverting upon failure. - if iszero( - and( // The arguments of `and` are evaluated from right to left. - gt(returndatasize(), 0x1f), // At least 32 bytes returned. - staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20) - ) - ) { - mstore(0x00, 0x90b8ec18) // `TransferFailed()`. - revert(0x1c, 0x04) - } - mstore(0x14, to) // Store the `to` argument. - amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it. - mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`. - // Perform the transfer, reverting upon failure. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x90b8ec18) // `TransferFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. - /// Reverts upon failure. - function safeApprove(address token, address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`. - revert(0x1c, 0x04) - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract. - /// If the initial attempt to approve fails, attempts to reset the approved amount to zero, - /// then retries the approval again (some tokens, e.g. USDT, requires this). - /// Reverts upon failure. - function safeApproveWithRetry(address token, address to, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, to) // Store the `to` argument. - mstore(0x34, amount) // Store the `amount` argument. - mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. - // Perform the approval, retrying upon failure. - let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x34, 0) // Store 0 for the `amount`. - mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`. - pop(call(gas(), token, 0, 0x10, 0x44, 0x00, 0x00)) // Reset the approval. - mstore(0x34, amount) // Store back the original `amount`. - // Retry the approval, reverting upon failure. - success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20) - if iszero(and(eq(mload(0x00), 1), success)) { - // Check the `extcodesize` again just in case the token selfdestructs lol. - if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) { - mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`. - revert(0x1c, 0x04) - } - } - } - } - mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten. - } - } - - /// @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) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x14, account) // Store the `account` argument. - mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`. - amount := - mul( // The arguments of `mul` are evaluated from right to left. - 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) - ) - ) - } - } - - /// @dev Returns the total supply of the `token`. - /// Reverts if the token does not exist or does not implement `totalSupply()`. - function totalSupply(address token) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x18160ddd) // `totalSupply()`. - if iszero( - and(gt(returndatasize(), 0x1f), staticcall(gas(), token, 0x1c, 0x04, 0x00, 0x20)) - ) { - mstore(0x00, 0x54cd9435) // `TotalSupplyQueryFailed()`. - revert(0x1c, 0x04) - } - result := mload(0x00) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/SignatureCheckerLib.sol b/grouperBot/lib/solady/src/utils/ext/zksync/SignatureCheckerLib.sol deleted file mode 100644 index 6120e87..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/SignatureCheckerLib.sol +++ /dev/null @@ -1,367 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Signature verification helper that supports both ECDSA signatures from EOAs -/// and ERC1271 signatures from smart contract wallets like Argent and Gnosis safe. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/SignatureCheckerLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol) -/// -/// @dev Note: -/// - The signature checking functions use the ecrecover precompile (0x1). -/// - Unlike ECDSA signatures, contract signatures are revocable. -/// - As of Solady version 0.0.134, all `bytes signature` variants accept both -/// regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures. -/// See: https://eips.ethereum.org/EIPS/eip-2098 -/// This is for calldata efficiency on smart accounts prevalent on L2s. -/// -/// WARNING! Do NOT use signatures as unique identifiers: -/// - Use a nonce in the digest to prevent replay attacks on the same contract. -/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts. -/// EIP-712 also enables readable signing of typed data for better user safety. -/// This implementation does NOT check if a signature is non-malleable. -library SignatureCheckerLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* SIGNATURE CHECKING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns whether `signature` is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - switch mload(signature) - case 64 { - let vs := mload(add(signature, 0x40)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. - mstore(0x60, mload(add(signature, 0x40))) // `s`. - } - default { break } - mstore(0x00, hash) - mstore(0x40, mload(add(signature, 0x20))) // `r`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - // Copy the `signature` over. - let n := add(0x20, mload(signature)) - copy(add(m, 0x44), signature, n) - isValid := staticcall(gas(), signer, m, add(n, 0x44), d, 0x20) - isValid := and(eq(mload(d), f), isValid) - break - } - } - } - - /// @dev Returns whether `signature` is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - switch signature.length - case 64 { - let vs := calldataload(add(signature.offset, 0x20)) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, calldataload(signature.offset)) // `r`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - } - case 65 { - mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. - calldatacopy(0x40, signature.offset, 0x40) // `r`, `s`. - } - default { break } - mstore(0x00, hash) - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), signature.length) - // Copy the `signature` over. - calldatacopy(add(m, 0x64), signature.offset, signature.length) - isValid := staticcall(gas(), signer, m, add(signature.length, 0x64), d, 0x20) - isValid := and(eq(mload(d), f), isValid) - break - } - } - } - - /// @dev Returns whether the signature (`r`, `vs`) is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - mstore(0x00, hash) - mstore(0x20, add(shr(255, vs), 27)) // `v`. - mstore(0x40, r) // `r`. - mstore(0x60, shr(1, shl(1, vs))) // `s`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`. - mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - break - } - } - } - - /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `signer` and `hash`. - /// If `signer.code.length == 0`, then validate with `ecrecover`, else - /// it will validate with ERC1271 on `signer`. - function isValidSignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) - internal - view - returns (bool isValid) - { - if (signer == address(0)) return isValid; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - for {} 1 {} { - if iszero(extcodesize(signer)) { - mstore(0x00, hash) - mstore(0x20, and(v, 0xff)) // `v`. - mstore(0x40, r) // `r`. - mstore(0x60, s) // `s`. - let recovered := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) - isValid := gt(returndatasize(), shl(96, xor(signer, recovered))) - mstore(0x60, 0) // Restore the zero slot. - mstore(0x40, m) // Restore the free memory pointer. - break - } - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), s) // `s`. - mstore8(add(m, 0xa4), v) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ERC1271 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: These ERC1271 operations do NOT have an ECDSA fallback. - - /// @dev Returns whether `signature` is valid for `hash` for an ERC1271 `signer` contract. - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes memory signature) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - function copy(dst_, src_, n_) { - for { let i_ := 0 } lt(i_, n_) { i_ := add(0x20, i_) } { - mstore(add(dst_, i_), mload(add(src_, i_))) - } - } - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - // Copy the `signature` over. - let n := add(0x20, mload(signature)) - copy(add(m, 0x44), signature, n) - isValid := staticcall(gas(), signer, m, add(n, 0x44), d, 0x20) - isValid := and(eq(mload(d), f), isValid) - } - } - - /// @dev Returns whether `signature` is valid for `hash` for an ERC1271 `signer` contract. - function isValidERC1271SignatureNowCalldata( - address signer, - bytes32 hash, - bytes calldata signature - ) internal view returns (bool isValid) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), signature.length) - // Copy the `signature` over. - calldatacopy(add(m, 0x64), signature.offset, signature.length) - isValid := staticcall(gas(), signer, m, add(signature.length, 0x64), d, 0x20) - isValid := and(eq(mload(d), f), isValid) - } - } - - /// @dev Returns whether the signature (`r`, `vs`) is valid for `hash` - /// for an ERC1271 `signer` contract. - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`. - mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - } - } - - /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `hash` - /// for an ERC1271 `signer` contract. - function isValidERC1271SignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) - internal - view - returns (bool isValid) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let f := shl(224, 0x1626ba7e) - mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`. - mstore(add(m, 0x04), hash) - let d := add(m, 0x24) - mstore(d, 0x40) // The offset of the `signature` in the calldata. - mstore(add(m, 0x44), 65) // Length of the signature. - mstore(add(m, 0x64), r) // `r`. - mstore(add(m, 0x84), s) // `s`. - mstore8(add(m, 0xa4), v) // `v`. - isValid := staticcall(gas(), signer, m, 0xa5, d, 0x20) - isValid := and(eq(mload(d), f), isValid) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HASHING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns an Ethereum Signed Message, created from a `hash`. - /// This produces a hash corresponding to the one signed with the - /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) - /// JSON-RPC method as part of EIP-191. - function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, hash) // Store into scratch space for keccak256. - mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes. - result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`. - } - } - - /// @dev Returns an Ethereum Signed Message, created from `s`. - /// This produces a hash corresponding to the one signed with the - /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) - /// JSON-RPC method as part of EIP-191. - /// Note: Supports lengths of `s` up to 999999 bytes. - function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let sLength := mload(s) - let o := 0x20 - mstore(o, "\x19Ethereum Signed Message:\n") // 26 bytes, zero-right-padded. - mstore(0x00, 0x00) - // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`. - for { let temp := sLength } 1 {} { - o := sub(o, 1) - mstore8(o, add(48, mod(temp, 10))) - temp := div(temp, 10) - if iszero(temp) { break } - } - let n := sub(0x3a, o) // Header length: `26 + 32 - o`. - // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes. - returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20)) - mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header. - result := keccak256(add(s, sub(0x20, n)), add(n, sLength)) - mstore(s, sLength) // Restore the length. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EMPTY CALLDATA HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns an empty calldata bytes. - function emptySignature() internal pure returns (bytes calldata signature) { - /// @solidity memory-safe-assembly - assembly { - signature.length := 0 - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/SingleUseETHVault.sol b/grouperBot/lib/solady/src/utils/ext/zksync/SingleUseETHVault.sol deleted file mode 100644 index 8dbb0b0..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/SingleUseETHVault.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice A single-use vault that allows a designated caller to withdraw all ETH in it. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/SingleUseETHVault.sol) -contract SingleUseETHVault { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unable to withdraw all. - error WithdrawAllFailed(); - - /// @dev Not authorized. - error Unauthorized(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* WITHDRAW ALL */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - fallback() external payable virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, 0) // Optimization trick to remove free memory pointer initialization. - let owner := sload(0) - // Initialization. - if iszero(owner) { - sstore(0, calldataload(0x00)) // Store the owner. - return(0x00, 0x00) // Early return. - } - // Authorization check. - if iszero(eq(caller(), owner)) { - mstore(0x00, 0x82b42900) // `Unauthorized()`. - revert(0x1c, 0x04) - } - let to := calldataload(0x00) - // If the calldata is less than 32 bytes, zero-left-pad it to 32 bytes. - // Then use the rightmost 20 bytes of the word as the `to` address. - // This allows for the calldata to be `abi.encode(to)` or `abi.encodePacked(to)`. - to := shr(mul(lt(calldatasize(), 0x20), shl(3, sub(0x20, calldatasize()))), to) - // If `to` is `address(0)`, set it to `msg.sender`. - to := xor(mul(xor(to, caller()), iszero(to)), to) - // Transfers the whole balance to `to`. - if iszero(call(gas(), to, selfbalance(), 0x00, 0x00, 0x00, 0x00)) { - mstore(0x00, 0x651aee10) // `WithdrawAllFailed()`. - revert(0x1c, 0x04) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/UpgradeableBeacon.sol b/grouperBot/lib/solady/src/utils/ext/zksync/UpgradeableBeacon.sol deleted file mode 100644 index cdbfa0e..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/UpgradeableBeacon.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice A sufficiently minimal upgradeable beacon tailor-made for ZKsync. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/UpgradeableBeacon.sol) -contract UpgradeableBeacon { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* EVENTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Emitted when the proxy's implementation is upgraded. - event Upgraded(address indexed implementation); - - /// @dev `keccak256(bytes("Upgraded(address)"))`. - uint256 private constant _UPGRADED_EVENT_SIGNATURE = - 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev To store the implementation. - uint256 private __implementation; - - /// @dev For upgrades / initialization. - uint256 private __deployer; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTRUCTOR */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - constructor() payable { - __deployer = uint256(uint160(msg.sender)); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UPGRADEABLE BEACON OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the implementation stored in the beacon. - /// See: https://eips.ethereum.org/EIPS/eip-1967#beacon-contract-address - function implementation() public view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(__implementation.slot) - } - } - - fallback() external virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, 0) // Optimization trick to remove free memory pointer initialization. - let newImplementation := calldataload(0x00) - // Revert if the caller is not the deployer. We will still allow the implementation - // to be set to an empty contract for simplicity. - if iszero(eq(caller(), sload(__deployer.slot))) { revert(0x00, 0x00) } - sstore(__implementation.slot, newImplementation) - // Emit the {Upgraded} event. - log2(0x00, 0x00, _UPGRADED_EVENT_SIGNATURE, newImplementation) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/ext/zksync/delegatexyz/DelegateCheckerLib.sol b/grouperBot/lib/solady/src/utils/ext/zksync/delegatexyz/DelegateCheckerLib.sol deleted file mode 100644 index 88b0736..0000000 --- a/grouperBot/lib/solady/src/utils/ext/zksync/delegatexyz/DelegateCheckerLib.sol +++ /dev/null @@ -1,301 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Library for efficient querying of the delegate registry on ZKsync. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/delegatexyz/DelegateCheckerLib.sol) -library DelegateCheckerLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The canonical delegate registry V2 on ZKsync. - /// There's no V1 on ZKsync. - /// See: https://sepolia.abscan.org/address/0x0000000059A24EB229eED07Ac44229DB56C5d797 - address internal constant DELEGATE_REGISTRY_V2 = 0x0000000059A24EB229eED07Ac44229DB56C5d797; - - /// @dev The storage slot to store an override address for the `DELEGATE_REGISTRY_V2`. - /// If the address is non-zero, it will be used instead. - /// This is so that you can avoid using `vm.etch` in ZKsync Foundry, - /// and instead use `vm.store` instead. - bytes32 internal constant DELEGATE_REGISTRY_V2_OVERRIDE_SLOT = - 0x04ecb0522ab37ca0b278a89c6884dfdbcde83c177150fc939ab02e069068bdef; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DELEGATE CHECKING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: - // - `to` is the delegate. Typically called the "hot wallet". - // - `from` is the grantor of the delegate rights. Typically called the "cold vault". - - /// @dev Returns if `to` is a delegate of `from`. - /// ``` - /// v2.checkDelegateForAll(to, from, "") - /// ``` - function checkDelegateForAll(address to, address from) internal view returns (bool isValid) { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - // `0x60` is already 0. - mstore(0x40, from) - mstore(0x2c, shl(96, to)) - mstore(0x0c, 0xe839bd53000000000000000000000000) // `checkDelegateForAll(address,address,bytes32)`. - isValid := eq(mload(staticcall(gas(), v2, 0x1c, 0x64, 0x01, 0x20)), 1) - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /// @dev Returns if `to` is a delegate of `from`. - /// ``` - /// v2.checkDelegateForAll(to, from, rights) - /// ``` - function checkDelegateForAll(address to, address from, bytes32 rights) - internal - view - returns (bool isValid) - { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(0x60, rights) - mstore(0x40, from) - mstore(0x2c, shl(96, to)) - mstore(0x0c, 0xe839bd53000000000000000000000000) // `checkDelegateForAll(address,address,bytes32)`. - isValid := eq(mload(staticcall(gas(), v2, 0x1c, 0x64, 0x01, 0x20)), 1) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_`. - /// ``` - /// v2.checkDelegateForContract(to, from, contract_, "") - /// ``` - /// Returns true if `checkDelegateForAll(to, from)` returns true. - function checkDelegateForContract(address to, address from, address contract_) - internal - view - returns (bool isValid) - { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0x80, m), 0) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForContract(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0x8988eea9000000000000000000000000) - isValid := staticcall(gas(), v2, add(m, 0x1c), 0x84, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_`. - /// ``` - /// v2.checkDelegateForContract(to, from, contract_, rights) - /// ``` - /// Returns true if `checkDelegateForAll(to, from, rights)` returns true. - function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) - internal - view - returns (bool isValid) - { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0x80, m), rights) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForContract(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0x8988eea9000000000000000000000000) - isValid := staticcall(gas(), v2, add(m, 0x1c), 0x84, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_` and token `id`. - /// ``` - /// v2.checkDelegateForERC721(to, from, contract_, id, "") - /// ``` - /// Returns true if `checkDelegateForContract(to, from, contract_)` returns true. - function checkDelegateForERC721(address to, address from, address contract_, uint256 id) - internal - view - returns (bool isValid) - { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0xa0, m), 0) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC721(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb9f36874000000000000000000000000) - isValid := staticcall(gas(), v2, add(m, 0x1c), 0xa4, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - - /// @dev Returns if `to` is a delegate of `from` for the specified `contract_` and token `id`. - /// ``` - /// v2.checkDelegateForERC721(to, from, contract_, id, rights) - /// ``` - /// Returns true if `checkDelegateForContract(to, from, contract_, rights)` returns true. - function checkDelegateForERC721( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal view returns (bool isValid) { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(0xa0, m), rights) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC721(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb9f36874000000000000000000000000) - isValid := staticcall(gas(), v2, add(m, 0x1c), 0xa4, m, 0x20) - isValid := and(eq(mload(m), 1), isValid) - } - } - - /// @dev Returns the amount of an ERC20 token for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// v2.checkDelegateForERC20(to, from, contract_, "") - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_)` returns true. - function checkDelegateForERC20(address to, address from, address contract_) - internal - view - returns (uint256 amount) - { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let o := add(0x80, m) - mstore(o, 0) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC20(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0xba63c817000000000000000000000000) - amount := staticcall(gas(), v2, add(m, 0x1c), 0x84, o, 0x20) - amount := mul(mload(o), amount) - } - } - - /// @dev Returns the amount of an ERC20 token for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// v2.checkDelegateForERC20(to, from, contract_, rights) - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_, rights)` returns true. - function checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) - internal - view - returns (uint256 amount) - { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(0x00, 0) - mstore(add(0x80, m), rights) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC20(address,address,address,bytes32)`. - mstore(add(0x0c, m), 0xba63c817000000000000000000000000) - amount := staticcall(gas(), v2, add(m, 0x1c), 0x84, 0x00, 0x20) - amount := mul(mload(0x00), amount) - } - } - - /// @dev Returns the amount of an ERC1155 token `id` for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// v2.checkDelegateForERC1155(to, from, contract_, id, "") - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_)` returns true. - function checkDelegateForERC1155(address to, address from, address contract_, uint256 id) - internal - view - returns (uint256 amount) - { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let o := add(0xa0, m) - mstore(o, 0) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC1155(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb8705875000000000000000000000000) - amount := staticcall(gas(), v2, add(m, 0x1c), 0xa4, o, 0x20) - amount := mul(mload(o), amount) - } - } - - /// @dev Returns the amount of an ERC1155 token `id` for `contract_` - /// that `to` is granted rights to act on the behalf of `from`. - /// ``` - /// v2.checkDelegateForERC1155(to, from, contract_, id, rights) - /// ``` - /// Returns `type(uint256).max` if `checkDelegateForContract(to, from, contract_, rights)` returns true. - function checkDelegateForERC1155( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal view returns (uint256 amount) { - address v2 = _delegateRegistryV2(); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(0x00, 0) - mstore(add(0xa0, m), rights) - mstore(add(0x80, m), id) - mstore(add(0x60, m), contract_) - mstore(add(0x4c, m), shl(96, from)) - mstore(add(0x2c, m), shl(96, to)) - // `checkDelegateForERC1155(address,address,address,uint256,bytes32)`. - mstore(add(0x0c, m), 0xb8705875000000000000000000000000) - amount := staticcall(gas(), v2, add(m, 0x1c), 0xa4, 0x00, 0x20) - amount := mul(mload(0x00), amount) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the address of the delegate registry V2. - function _delegateRegistryV2() private view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - // Don't worry about it, storage read is cheap on ZKsync VM. - result := shr(96, shl(96, sload(DELEGATE_REGISTRY_V2_OVERRIDE_SLOT))) - result := or(mul(DELEGATE_REGISTRY_V2, iszero(result)), result) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/DynamicArrayLib.sol b/grouperBot/lib/solady/src/utils/g/DynamicArrayLib.sol deleted file mode 100644 index 61cbd51..0000000 --- a/grouperBot/lib/solady/src/utils/g/DynamicArrayLib.sol +++ /dev/null @@ -1,1024 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev Type to represent a dynamic array in memory. -/// You can directly assign to `data`, and the `p` function will -/// take care of the memory allocation. -struct DynamicArray { - uint256[] data; -} - -using DynamicArrayLib for DynamicArray global; - -/// @notice Library for memory arrays with automatic capacity resizing. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/DynamicArrayLib.sol) -library DynamicArrayLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when the element is not found in the array. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UINT256 ARRAY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Low level minimalist uint256 array operations. - // If you don't need syntax sugar, it's recommended to use these. - // Some of these functions return the same array for function chaining. - // e.g. `array.set(0, 1).set(1, 2)`. - - /// @dev Returns a uint256 array with `n` elements. The elements are not zeroized. - function malloc(uint256 n) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := or(sub(0, shr(32, n)), mload(0x40)) - mstore(result, n) - mstore(0x40, add(add(result, 0x20), shl(5, n))) - } - } - - /// @dev Zeroizes all the elements of `a`. - function zeroize(uint256[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - calldatacopy(add(result, 0x20), calldatasize(), shl(5, mload(result))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function get(uint256[] memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getUint256(uint256[] memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getAddress(uint256[] memory a, uint256 i) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getBool(uint256[] memory a, uint256 i) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a[i]`, without bounds checking. - function getBytes32(uint256[] memory a, uint256 i) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), shl(5, i))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, uint256 data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), data) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, address data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), shr(96, shl(96, data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, bool data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), iszero(iszero(data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(uint256[] memory a, uint256 i, bytes32 data) - internal - pure - returns (uint256[] memory result) - { - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(result, 0x20), shl(5, i)), data) - } - } - - /// @dev Casts `a` to `address[]`. - function asAddressArray(uint256[] memory a) internal pure returns (address[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `bool[]`. - function asBoolArray(uint256[] memory a) internal pure returns (bool[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `bytes32[]`. - function asBytes32Array(uint256[] memory a) internal pure returns (bytes32[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `uint256[]`. - function toUint256Array(address[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `uint256[]`. - function toUint256Array(bool[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Casts `a` to `uint256[]`. - function toUint256Array(bytes32[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Reduces the size of `a` to `n`. - /// If `n` is greater than the size of `a`, this will be a no-op. - function truncate(uint256[] memory a, uint256 n) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := a - mstore(mul(lt(n, mload(result)), result), n) - } - } - - /// @dev Clears the array and attempts to free the memory if possible. - function free(uint256[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - let n := mload(result) - mstore(shl(6, lt(iszero(n), eq(add(shl(5, add(1, n)), result), mload(0x40)))), result) - mstore(result, 0) - } - } - - /// @dev Equivalent to `keccak256(abi.encodePacked(a))`. - function hash(uint256[] memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(add(a, 0x20), shl(5, mload(a))) - } - } - - /// @dev Returns a copy of `a` sliced from `start` to `end` (exclusive). - function slice(uint256[] memory a, uint256 start, uint256 end) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - let arrayLen := mload(a) - if iszero(gt(arrayLen, end)) { end := arrayLen } - if iszero(gt(arrayLen, start)) { start := arrayLen } - if lt(start, end) { - result := mload(0x40) - let resultLen := sub(end, start) - mstore(result, resultLen) - a := add(a, shl(5, start)) - // Copy the `a` one word at a time, backwards. - let o := shl(5, resultLen) - mstore(0x40, add(add(result, o), 0x20)) // Allocate memory. - for {} 1 {} { - mstore(add(result, o), mload(add(a, o))) - o := sub(o, 0x20) - if iszero(o) { break } - } - } - } - } - - /// @dev Returns a copy of `a` sliced from `start` to the end of the array. - function slice(uint256[] memory a, uint256 start) - internal - pure - returns (uint256[] memory result) - { - result = slice(a, start, type(uint256).max); - } - - /// @dev Returns a copy of the array. - function copy(uint256[] memory a) internal pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let end := add(add(result, 0x20), shl(5, mload(a))) - let o := result - for { let d := sub(a, result) } 1 {} { - mstore(o, mload(add(o, d))) - o := add(0x20, o) - if eq(o, end) { break } - } - mstore(0x40, o) - } - } - - /// @dev Returns if `needle` is in `a`. - function contains(uint256[] memory a, uint256 needle) internal pure returns (bool) { - return ~indexOf(a, needle, 0) != 0; - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(uint256[] memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) - if lt(from, mload(a)) { - let o := add(a, shl(5, from)) - let end := add(shl(5, add(1, mload(a))), a) - let c := mload(end) // Cache the word after the array. - for { mstore(end, needle) } 1 {} { - o := add(o, 0x20) - if eq(mload(o), needle) { break } - } - mstore(end, c) // Restore the word after the array. - if iszero(eq(o, end)) { result := shr(5, sub(o, add(0x20, a))) } - } - } - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(uint256[] memory a, uint256 needle) internal pure returns (uint256 result) { - result = indexOf(a, needle, 0); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(uint256[] memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) - let n := mload(a) - if n { - if iszero(lt(from, n)) { from := sub(n, 1) } - let o := add(shl(5, add(2, from)), a) - for { mstore(a, needle) } 1 {} { - o := sub(o, 0x20) - if eq(mload(o), needle) { break } - } - mstore(a, n) // Restore the length. - if iszero(eq(o, a)) { result := shr(5, sub(o, add(0x20, a))) } - } - } - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(uint256[] memory a, uint256 needle) - internal - pure - returns (uint256 result) - { - result = lastIndexOf(a, needle, NOT_FOUND); - } - - /// @dev Directly returns `a` without copying. - function directReturn(uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let retStart := sub(a, 0x20) - mstore(retStart, 0x20) - return(retStart, add(0x40, shl(5, mload(a)))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DYNAMIC ARRAY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Some of these functions return the same array for function chaining. - // e.g. `a.p("1").p("2")`. - - /// @dev Shorthand for `a.data.length`. - function length(DynamicArray memory a) internal pure returns (uint256) { - return a.data.length; - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(uint256[] memory a) internal pure returns (DynamicArray memory result) { - result.data = a; - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(address[] memory a) internal pure returns (DynamicArray memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, a) - } - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(bool[] memory a) internal pure returns (DynamicArray memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, a) - } - } - - /// @dev Wraps `a` in a dynamic array struct. - function wrap(bytes32[] memory a) internal pure returns (DynamicArray memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, a) - } - } - - /// @dev Clears the array without deallocating the memory. - function clear(DynamicArray memory a) internal pure returns (DynamicArray memory result) { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(mload(result), 0) - } - } - - /// @dev Clears the array and attempts to free the memory if possible. - function free(DynamicArray memory a) internal pure returns (DynamicArray memory result) { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(result) - if iszero(eq(arrData, 0x60)) { - let prime := 8188386068317523 - let cap := mload(sub(arrData, 0x20)) - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - // If `cap` is non-zero and the memory is contiguous, we can free it. - if lt(iszero(cap), eq(mload(0x40), add(arrData, add(0x20, cap)))) { - mstore(0x40, sub(arrData, 0x20)) - } - mstore(result, 0x60) - } - } - } - - /// @dev Resizes the array to contain `n` elements. New elements will be zeroized. - function resize(DynamicArray memory a, uint256 n) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - reserve(result, n); - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(result) - let arrLen := mload(arrData) - if iszero(lt(n, arrLen)) { - calldatacopy( - add(arrData, shl(5, add(1, arrLen))), calldatasize(), shl(5, sub(n, arrLen)) - ) - } - mstore(arrData, n) - } - } - - /// @dev Increases the size of `a` to `n`. - /// If `n` is less than the size of `a`, this will be a no-op. - /// This method does not zeroize any newly created elements. - function expand(DynamicArray memory a, uint256 n) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - if (n >= a.data.length) { - reserve(result, n); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(result), n) - } - } - } - - /// @dev Reduces the size of `a` to `n`. - /// If `n` is greater than the size of `a`, this will be a no-op. - function truncate(DynamicArray memory a, uint256 n) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(mul(lt(n, mload(mload(result))), mload(result)), n) - } - } - - /// @dev Reserves at least `minimum` amount of contiguous memory. - function reserve(DynamicArray memory a, uint256 minimum) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(minimum, 0xffffffff)) { invalid() } // For extra safety. - for { let arrData := mload(a) } 1 {} { - // Some random prime number to multiply `cap`, so that - // we know that the `cap` is for a dynamic array. - // Selected to be larger than any memory pointer realistically. - let prime := 8188386068317523 - // Special case for `arrData` pointing to zero pointer. - if eq(arrData, 0x60) { - let newCap := shl(5, add(1, minimum)) - let capSlot := mload(0x40) - mstore(capSlot, mul(prime, newCap)) // Store the capacity. - let newArrData := add(0x20, capSlot) - mstore(newArrData, 0) // Store the length. - mstore(0x40, add(newArrData, add(0x20, newCap))) // Allocate memory. - mstore(a, newArrData) - break - } - let w := not(0x1f) - let cap := mload(add(arrData, w)) // `mload(sub(arrData, w))`. - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - let newCap := shl(5, minimum) - // If we don't need to grow the memory. - if iszero(and(gt(minimum, mload(arrData)), gt(newCap, cap))) { break } - // If the memory is contiguous, we can simply expand it. - if eq(mload(0x40), add(arrData, add(0x20, cap))) { - mstore(add(arrData, w), mul(prime, newCap)) // Store the capacity. - mstore(0x40, add(arrData, add(0x20, newCap))) // Expand the memory allocation. - break - } - let capSlot := mload(0x40) - let newArrData := add(capSlot, 0x20) - mstore(0x40, add(newArrData, add(0x20, newCap))) // Reallocate the memory. - mstore(a, newArrData) // Store the `newArrData`. - // Copy `arrData` one word at a time, backwards. - for { let o := add(0x20, shl(5, mload(arrData))) } 1 {} { - mstore(add(newArrData, o), mload(add(arrData, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(capSlot, mul(prime, newCap)) // Store the capacity. - mstore(newArrData, mload(arrData)) // Store the length. - break - } - } - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, uint256 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(a) - let newArrLen := add(mload(arrData), 1) - let newArrBytesLen := shl(5, newArrLen) - // Some random prime number to multiply `cap`, so that - // we know that the `cap` is for a dynamic array. - // Selected to be larger than any memory pointer realistically. - let prime := 8188386068317523 - let cap := mload(sub(arrData, 0x20)) - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - - // Expand / Reallocate memory if required. - // Note that we need to allocate an extra word for the length. - for {} iszero(lt(newArrBytesLen, cap)) {} { - // Approximately more than double the capacity to ensure more than enough space. - let newCap := add(cap, or(cap, newArrBytesLen)) - // If the memory is contiguous, we can simply expand it. - if iszero(or(xor(mload(0x40), add(arrData, add(0x20, cap))), iszero(cap))) { - mstore(sub(arrData, 0x20), mul(prime, newCap)) // Store the capacity. - mstore(0x40, add(arrData, add(0x20, newCap))) // Expand the memory allocation. - break - } - // Set the `newArrData` to point to the word after `cap`. - let newArrData := add(mload(0x40), 0x20) - mstore(0x40, add(newArrData, add(0x20, newCap))) // Reallocate the memory. - mstore(a, newArrData) // Store the `newArrData`. - let w := not(0x1f) - // Copy `arrData` one word at a time, backwards. - for { let o := newArrBytesLen } 1 {} { - mstore(add(newArrData, o), mload(add(arrData, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(add(newArrData, w), mul(prime, newCap)) // Store the memory. - arrData := newArrData // Assign `newArrData` to `arrData`. - break - } - mstore(add(arrData, newArrBytesLen), data) // Append `data`. - mstore(arrData, newArrLen) // Store the length. - } - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, address data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = p(a, uint256(uint160(data))); - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, bool data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = p(a, _toUint(data)); - } - - /// @dev Appends `data` to `a`. - function p(DynamicArray memory a, bytes32 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = p(a, uint256(data)); - } - - /// @dev Shorthand for returning an empty array. - function p() internal pure returns (DynamicArray memory result) {} - - /// @dev Shorthand for `p(p(), data)`. - function p(uint256 data) internal pure returns (DynamicArray memory result) { - p(result, uint256(data)); - } - - /// @dev Shorthand for `p(p(), data)`. - function p(address data) internal pure returns (DynamicArray memory result) { - p(result, uint256(uint160(data))); - } - - /// @dev Shorthand for `p(p(), data)`. - function p(bool data) internal pure returns (DynamicArray memory result) { - p(result, _toUint(data)); - } - - /// @dev Shorthand for `p(p(), data)`. - function p(bytes32 data) internal pure returns (DynamicArray memory result) { - p(result, uint256(data)); - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function pop(DynamicArray memory a) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popUint256(DynamicArray memory a) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popAddress(DynamicArray memory a) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popBool(DynamicArray memory a) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Removes and returns the last element of `a`. - /// Returns 0 and does not pop anything if the array is empty. - function popBytes32(DynamicArray memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let o := mload(a) - let n := mload(o) - result := mload(add(o, shl(5, n))) - mstore(o, sub(n, iszero(iszero(n)))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function get(DynamicArray memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getUint256(DynamicArray memory a, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getAddress(DynamicArray memory a, uint256 i) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getBool(DynamicArray memory a, uint256 i) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Returns the element at `a.data[i]`, without bounds checking. - function getBytes32(DynamicArray memory a, uint256 i) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(mload(a), 0x20), shl(5, i))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, uint256 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), data) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, address data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), shr(96, shl(96, data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, bool data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), iszero(iszero(data))) - } - } - - /// @dev Sets `a.data[i]` to `data`, without bounds checking. - function set(DynamicArray memory a, uint256 i, bytes32 data) - internal - pure - returns (DynamicArray memory result) - { - _deallocate(result); - result = a; - /// @solidity memory-safe-assembly - assembly { - mstore(add(add(mload(result), 0x20), shl(5, i)), data) - } - } - - /// @dev Returns the underlying array as a `uint256[]`. - function asUint256Array(DynamicArray memory a) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns the underlying array as a `address[]`. - function asAddressArray(DynamicArray memory a) - internal - pure - returns (address[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns the underlying array as a `bool[]`. - function asBoolArray(DynamicArray memory a) internal pure returns (bool[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns the underlying array as a `bytes32[]`. - function asBytes32Array(DynamicArray memory a) - internal - pure - returns (bytes32[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(a) - } - } - - /// @dev Returns a copy of `a` sliced from `start` to `end` (exclusive). - function slice(DynamicArray memory a, uint256 start, uint256 end) - internal - pure - returns (DynamicArray memory result) - { - result.data = slice(a.data, start, end); - } - - /// @dev Returns a copy of `a` sliced from `start` to the end of the array. - function slice(DynamicArray memory a, uint256 start) - internal - pure - returns (DynamicArray memory result) - { - result.data = slice(a.data, start, type(uint256).max); - } - - /// @dev Returns a copy of `a`. - function copy(DynamicArray memory a) internal pure returns (DynamicArray memory result) { - result.data = copy(a.data); - } - - /// @dev Returns if `needle` is in `a`. - function contains(DynamicArray memory a, uint256 needle) internal pure returns (bool) { - return ~indexOf(a.data, needle, 0) != 0; - } - - /// @dev Returns if `needle` is in `a`. - function contains(DynamicArray memory a, address needle) internal pure returns (bool) { - return ~indexOf(a.data, uint160(needle), 0) != 0; - } - - /// @dev Returns if `needle` is in `a`. - function contains(DynamicArray memory a, bytes32 needle) internal pure returns (bool) { - return ~indexOf(a.data, uint256(needle), 0) != 0; - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256) - { - return indexOf(a.data, needle, from); - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, address needle, uint256 from) - internal - pure - returns (uint256) - { - return indexOf(a.data, uint160(needle), from); - } - - /// @dev Returns the first index of `needle`, scanning forward from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, bytes32 needle, uint256 from) - internal - pure - returns (uint256) - { - return indexOf(a.data, uint256(needle), from); - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, uint256 needle) internal pure returns (uint256) { - return indexOf(a.data, needle, 0); - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, address needle) internal pure returns (uint256) { - return indexOf(a.data, uint160(needle), 0); - } - - /// @dev Returns the first index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function indexOf(DynamicArray memory a, bytes32 needle) internal pure returns (uint256) { - return indexOf(a.data, uint256(needle), 0); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, uint256 needle, uint256 from) - internal - pure - returns (uint256) - { - return lastIndexOf(a.data, needle, from); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, address needle, uint256 from) - internal - pure - returns (uint256) - { - return lastIndexOf(a.data, uint160(needle), from); - } - - /// @dev Returns the last index of `needle`, scanning backwards from `from`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, bytes32 needle, uint256 from) - internal - pure - returns (uint256) - { - return lastIndexOf(a.data, uint256(needle), from); - } - - /// @dev Returns the last index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, uint256 needle) internal pure returns (uint256) { - return lastIndexOf(a.data, needle, NOT_FOUND); - } - - /// @dev Returns the last index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, address needle) internal pure returns (uint256) { - return lastIndexOf(a.data, uint160(needle), NOT_FOUND); - } - - /// @dev Returns the last index of `needle`. - /// If `needle` is not in `a`, returns `NOT_FOUND`. - function lastIndexOf(DynamicArray memory a, bytes32 needle) internal pure returns (uint256) { - return lastIndexOf(a.data, uint256(needle), NOT_FOUND); - } - - /// @dev Equivalent to `keccak256(abi.encodePacked(a.data))`. - function hash(DynamicArray memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(add(mload(a), 0x20), shl(5, mload(mload(a)))) - } - } - - /// @dev Directly returns `a` without copying. - function directReturn(DynamicArray memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let arrData := mload(a) - let retStart := sub(arrData, 0x20) - mstore(retStart, 0x20) - return(retStart, add(0x40, shl(5, mload(arrData)))) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper for deallocating an automatically allocated array pointer. - function _deallocate(DynamicArray memory result) private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Deallocate, as we have already allocated. - } - } - - /// @dev Casts the bool into a uint256. - function _toUint(bool b) private pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := iszero(iszero(b)) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/DynamicBufferLib.sol b/grouperBot/lib/solady/src/utils/g/DynamicBufferLib.sol deleted file mode 100644 index 0e9c3ee..0000000 --- a/grouperBot/lib/solady/src/utils/g/DynamicBufferLib.sol +++ /dev/null @@ -1,1317 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev Type to represent a dynamic buffer in memory. -/// You can directly assign to `data`, and the `p` function will -/// take care of the memory allocation. -struct DynamicBuffer { - bytes data; -} - -using DynamicBufferLib for DynamicBuffer global; - -/// @notice Library for buffers with automatic capacity resizing. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/DynamicBufferLib.sol) -/// @author Modified from cozyco (https://github.com/samkingco/cozyco/blob/main/contracts/utils/DynamicBuffer.sol) -library DynamicBufferLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Some of these functions return the same buffer for function chaining. - // e.g. `buffer.p("1").p("2")`. - - /// @dev Shorthand for `buffer.data.length`. - function length(DynamicBuffer memory buffer) internal pure returns (uint256) { - return buffer.data.length; - } - - /// @dev Reserves at least `minimum` amount of contiguous memory. - function reserve(DynamicBuffer memory buffer, uint256 minimum) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = buffer; - uint256 n = buffer.data.length; - if (minimum > n) { - uint256 i = 0x40; - do {} while ((i <<= 1) < minimum); - bytes memory data; - /// @solidity memory-safe-assembly - assembly { - data := 0x01 - mstore(data, sub(i, n)) - } - result = p(result, data); - } - } - - /// @dev Clears the buffer without deallocating the memory. - function clear(DynamicBuffer memory buffer) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(buffer), 0) - } - result = buffer; - } - - /// @dev Returns a string pointing to the underlying bytes data. - /// Note: The string WILL change if the buffer is updated. - function s(DynamicBuffer memory buffer) internal pure returns (string memory) { - return string(buffer.data); - } - - /// @dev Appends `data` to `buffer`. - function p(DynamicBuffer memory buffer, bytes memory data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = buffer; - if (data.length == uint256(0)) return result; - /// @solidity memory-safe-assembly - assembly { - let w := not(0x1f) - let bufData := mload(buffer) - let bufDataLen := mload(bufData) - let newBufDataLen := add(mload(data), bufDataLen) - // Some random prime number to multiply `cap`, so that - // we know that the `cap` is for a dynamic buffer. - // Selected to be larger than any memory pointer realistically. - let prime := 1621250193422201 - let cap := mload(add(bufData, w)) // `mload(sub(bufData, 0x20))`. - // Extract `cap`, initializing it to zero if it is not a multiple of `prime`. - cap := mul(div(cap, prime), iszero(mod(cap, prime))) - - // Expand / Reallocate memory if required. - // Note that we need to allocate an extra word for the length, and - // and another extra word as a safety word (giving a total of 0x40 bytes). - // Without the safety word, the backwards copying can cause a buffer overflow. - for {} iszero(lt(newBufDataLen, cap)) {} { - // Approximately more than double the capacity to ensure more than enough space. - let newCap := and(add(cap, add(or(cap, newBufDataLen), 0x20)), w) - // If the memory is contiguous, we can simply expand it. - if iszero(or(xor(mload(0x40), add(bufData, add(0x40, cap))), iszero(cap))) { - // Store `cap * prime` in the word before the length. - mstore(add(bufData, w), mul(prime, newCap)) - mstore(0x40, add(bufData, add(0x40, newCap))) // Expand the memory allocation. - break - } - // Set the `newBufData` to point to the word after `cap`. - let newBufData := add(mload(0x40), 0x20) - mstore(0x40, add(newBufData, add(0x40, newCap))) // Reallocate the memory. - mstore(buffer, newBufData) // Store the `newBufData`. - // Copy `bufData` one word at a time, backwards. - for { let o := and(add(bufDataLen, 0x20), w) } 1 {} { - mstore(add(newBufData, o), mload(add(bufData, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - // Store `cap * prime` in the word before the length. - mstore(add(newBufData, w), mul(prime, newCap)) - bufData := newBufData // Assign `newBufData` to `bufData`. - break - } - // If it's a reserve operation, set the variables to skip the appending. - if eq(data, 0x01) { - mstore(data, 0x00) - newBufDataLen := bufDataLen - } - // Copy `data` one word at a time, backwards. - for { let o := and(add(mload(data), 0x20), w) } 1 {} { - mstore(add(add(bufData, bufDataLen), o), mload(add(data, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(add(add(bufData, 0x20), newBufDataLen), 0) // Zeroize the word after the buffer. - mstore(bufData, newBufDataLen) // Store the length. - } - } - - /// @dev Appends `data0`, `data1` to `buffer`. - function p(DynamicBuffer memory buffer, bytes memory data0, bytes memory data1) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(p(buffer, data0), data1); - } - - /// @dev Appends `data0` .. `data2` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(buffer, data0), data1), data2); - } - - /// @dev Appends `data0` .. `data3` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(buffer, data0), data1), data2), data3); - } - - /// @dev Appends `data0` .. `data4` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(p(buffer, data0), data1), data2), data3), data4); - } - - /// @dev Appends `data0` .. `data5` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(p(p(buffer, data0), data1), data2), data3), data4), data5); - } - - /// @dev Appends `data0` .. `data6` to `buffer`. - function p( - DynamicBuffer memory buffer, - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5, - bytes memory data6 - ) internal pure returns (DynamicBuffer memory result) { - _deallocate(result); - result = p(p(p(p(p(p(p(buffer, data0), data1), data2), data3), data4), data5), data6); - } - - /// @dev Appends `abi.encodePacked(bool(data))` to buffer. - function pBool(DynamicBuffer memory buffer, bool data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - uint256 casted; - /// @solidity memory-safe-assembly - assembly { - casted := iszero(iszero(data)) - } - result = p(buffer, _single(casted, 1)); - } - - /// @dev Appends `abi.encodePacked(address(data))` to buffer. - function pAddress(DynamicBuffer memory buffer, address data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(uint256(uint160(data)), 20)); - } - - /// @dev Appends `abi.encodePacked(uint8(data))` to buffer. - function pUint8(DynamicBuffer memory buffer, uint8 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 1)); - } - - /// @dev Appends `abi.encodePacked(uint16(data))` to buffer. - function pUint16(DynamicBuffer memory buffer, uint16 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 2)); - } - - /// @dev Appends `abi.encodePacked(uint24(data))` to buffer. - function pUint24(DynamicBuffer memory buffer, uint24 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 3)); - } - - /// @dev Appends `abi.encodePacked(uint32(data))` to buffer. - function pUint32(DynamicBuffer memory buffer, uint32 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 4)); - } - - /// @dev Appends `abi.encodePacked(uint40(data))` to buffer. - function pUint40(DynamicBuffer memory buffer, uint40 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 5)); - } - - /// @dev Appends `abi.encodePacked(uint48(data))` to buffer. - function pUint48(DynamicBuffer memory buffer, uint48 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 6)); - } - - /// @dev Appends `abi.encodePacked(uint56(data))` to buffer. - function pUint56(DynamicBuffer memory buffer, uint56 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 7)); - } - - /// @dev Appends `abi.encodePacked(uint64(data))` to buffer. - function pUint64(DynamicBuffer memory buffer, uint64 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 8)); - } - - /// @dev Appends `abi.encodePacked(uint72(data))` to buffer. - function pUint72(DynamicBuffer memory buffer, uint72 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 9)); - } - - /// @dev Appends `abi.encodePacked(uint80(data))` to buffer. - function pUint80(DynamicBuffer memory buffer, uint80 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 10)); - } - - /// @dev Appends `abi.encodePacked(uint88(data))` to buffer. - function pUint88(DynamicBuffer memory buffer, uint88 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 11)); - } - - /// @dev Appends `abi.encodePacked(uint96(data))` to buffer. - function pUint96(DynamicBuffer memory buffer, uint96 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 12)); - } - - /// @dev Appends `abi.encodePacked(uint104(data))` to buffer. - function pUint104(DynamicBuffer memory buffer, uint104 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 13)); - } - - /// @dev Appends `abi.encodePacked(uint112(data))` to buffer. - function pUint112(DynamicBuffer memory buffer, uint112 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 14)); - } - - /// @dev Appends `abi.encodePacked(uint120(data))` to buffer. - function pUint120(DynamicBuffer memory buffer, uint120 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 15)); - } - - /// @dev Appends `abi.encodePacked(uint128(data))` to buffer. - function pUint128(DynamicBuffer memory buffer, uint128 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 16)); - } - - /// @dev Appends `abi.encodePacked(uint136(data))` to buffer. - function pUint136(DynamicBuffer memory buffer, uint136 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 17)); - } - - /// @dev Appends `abi.encodePacked(uint144(data))` to buffer. - function pUint144(DynamicBuffer memory buffer, uint144 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 18)); - } - - /// @dev Appends `abi.encodePacked(uint152(data))` to buffer. - function pUint152(DynamicBuffer memory buffer, uint152 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 19)); - } - - /// @dev Appends `abi.encodePacked(uint160(data))` to buffer. - function pUint160(DynamicBuffer memory buffer, uint160 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 20)); - } - - /// @dev Appends `abi.encodePacked(uint168(data))` to buffer. - function pUint168(DynamicBuffer memory buffer, uint168 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 21)); - } - - /// @dev Appends `abi.encodePacked(uint176(data))` to buffer. - function pUint176(DynamicBuffer memory buffer, uint176 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 22)); - } - - /// @dev Appends `abi.encodePacked(uint184(data))` to buffer. - function pUint184(DynamicBuffer memory buffer, uint184 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 23)); - } - - /// @dev Appends `abi.encodePacked(uint192(data))` to buffer. - function pUint192(DynamicBuffer memory buffer, uint192 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 24)); - } - - /// @dev Appends `abi.encodePacked(uint200(data))` to buffer. - function pUint200(DynamicBuffer memory buffer, uint200 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 25)); - } - - /// @dev Appends `abi.encodePacked(uint208(data))` to buffer. - function pUint208(DynamicBuffer memory buffer, uint208 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 26)); - } - - /// @dev Appends `abi.encodePacked(uint216(data))` to buffer. - function pUint216(DynamicBuffer memory buffer, uint216 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 27)); - } - - /// @dev Appends `abi.encodePacked(uint224(data))` to buffer. - function pUint224(DynamicBuffer memory buffer, uint224 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 28)); - } - - /// @dev Appends `abi.encodePacked(uint232(data))` to buffer. - function pUint232(DynamicBuffer memory buffer, uint232 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 29)); - } - - /// @dev Appends `abi.encodePacked(uint240(data))` to buffer. - function pUint240(DynamicBuffer memory buffer, uint240 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 30)); - } - - /// @dev Appends `abi.encodePacked(uint248(data))` to buffer. - function pUint248(DynamicBuffer memory buffer, uint248 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 31)); - } - - /// @dev Appends `abi.encodePacked(uint256(data))` to buffer. - function pUint256(DynamicBuffer memory buffer, uint256 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(data, 32)); - } - - /// @dev Appends `abi.encodePacked(bytes1(data))` to buffer. - function pBytes1(DynamicBuffer memory buffer, bytes1 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 1)); - } - - /// @dev Appends `abi.encodePacked(bytes2(data))` to buffer. - function pBytes2(DynamicBuffer memory buffer, bytes2 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 2)); - } - - /// @dev Appends `abi.encodePacked(bytes3(data))` to buffer. - function pBytes3(DynamicBuffer memory buffer, bytes3 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 3)); - } - - /// @dev Appends `abi.encodePacked(bytes4(data))` to buffer. - function pBytes4(DynamicBuffer memory buffer, bytes4 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 4)); - } - - /// @dev Appends `abi.encodePacked(bytes5(data))` to buffer. - function pBytes5(DynamicBuffer memory buffer, bytes5 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 5)); - } - - /// @dev Appends `abi.encodePacked(bytes6(data))` to buffer. - function pBytes6(DynamicBuffer memory buffer, bytes6 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 6)); - } - - /// @dev Appends `abi.encodePacked(bytes7(data))` to buffer. - function pBytes7(DynamicBuffer memory buffer, bytes7 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 7)); - } - - /// @dev Appends `abi.encodePacked(bytes8(data))` to buffer. - function pBytes8(DynamicBuffer memory buffer, bytes8 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 8)); - } - - /// @dev Appends `abi.encodePacked(bytes9(data))` to buffer. - function pBytes9(DynamicBuffer memory buffer, bytes9 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 9)); - } - - /// @dev Appends `abi.encodePacked(bytes10(data))` to buffer. - function pBytes10(DynamicBuffer memory buffer, bytes10 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 10)); - } - - /// @dev Appends `abi.encodePacked(bytes11(data))` to buffer. - function pBytes11(DynamicBuffer memory buffer, bytes11 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 11)); - } - - /// @dev Appends `abi.encodePacked(bytes12(data))` to buffer. - function pBytes12(DynamicBuffer memory buffer, bytes12 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 12)); - } - - /// @dev Appends `abi.encodePacked(bytes13(data))` to buffer. - function pBytes13(DynamicBuffer memory buffer, bytes13 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 13)); - } - - /// @dev Appends `abi.encodePacked(bytes14(data))` to buffer. - function pBytes14(DynamicBuffer memory buffer, bytes14 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 14)); - } - - /// @dev Appends `abi.encodePacked(bytes15(data))` to buffer. - function pBytes15(DynamicBuffer memory buffer, bytes15 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 15)); - } - - /// @dev Appends `abi.encodePacked(bytes16(data))` to buffer. - function pBytes16(DynamicBuffer memory buffer, bytes16 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 16)); - } - - /// @dev Appends `abi.encodePacked(bytes17(data))` to buffer. - function pBytes17(DynamicBuffer memory buffer, bytes17 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 17)); - } - - /// @dev Appends `abi.encodePacked(bytes18(data))` to buffer. - function pBytes18(DynamicBuffer memory buffer, bytes18 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 18)); - } - - /// @dev Appends `abi.encodePacked(bytes19(data))` to buffer. - function pBytes19(DynamicBuffer memory buffer, bytes19 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 19)); - } - - /// @dev Appends `abi.encodePacked(bytes20(data))` to buffer. - function pBytes20(DynamicBuffer memory buffer, bytes20 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 20)); - } - - /// @dev Appends `abi.encodePacked(bytes21(data))` to buffer. - function pBytes21(DynamicBuffer memory buffer, bytes21 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 21)); - } - - /// @dev Appends `abi.encodePacked(bytes22(data))` to buffer. - function pBytes22(DynamicBuffer memory buffer, bytes22 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 22)); - } - - /// @dev Appends `abi.encodePacked(bytes23(data))` to buffer. - function pBytes23(DynamicBuffer memory buffer, bytes23 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 23)); - } - - /// @dev Appends `abi.encodePacked(bytes24(data))` to buffer. - function pBytes24(DynamicBuffer memory buffer, bytes24 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 24)); - } - - /// @dev Appends `abi.encodePacked(bytes25(data))` to buffer. - function pBytes25(DynamicBuffer memory buffer, bytes25 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 25)); - } - - /// @dev Appends `abi.encodePacked(bytes26(data))` to buffer. - function pBytes26(DynamicBuffer memory buffer, bytes26 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 26)); - } - - /// @dev Appends `abi.encodePacked(bytes27(data))` to buffer. - function pBytes27(DynamicBuffer memory buffer, bytes27 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 27)); - } - - /// @dev Appends `abi.encodePacked(bytes28(data))` to buffer. - function pBytes28(DynamicBuffer memory buffer, bytes28 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 28)); - } - - /// @dev Appends `abi.encodePacked(bytes29(data))` to buffer. - function pBytes29(DynamicBuffer memory buffer, bytes29 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 29)); - } - - /// @dev Appends `abi.encodePacked(bytes30(data))` to buffer. - function pBytes30(DynamicBuffer memory buffer, bytes30 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 30)); - } - - /// @dev Appends `abi.encodePacked(bytes31(data))` to buffer. - function pBytes31(DynamicBuffer memory buffer, bytes31 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 31)); - } - - /// @dev Appends `abi.encodePacked(bytes32(data))` to buffer. - function pBytes32(DynamicBuffer memory buffer, bytes32 data) - internal - pure - returns (DynamicBuffer memory result) - { - _deallocate(result); - result = p(buffer, _single(bytes32(data), 32)); - } - - /// @dev Shorthand for returning a new buffer. - function p() internal pure returns (DynamicBuffer memory result) {} - - /// @dev Shorthand for `p(p(), data)`. - function p(bytes memory data) internal pure returns (DynamicBuffer memory result) { - p(result, data); - } - - /// @dev Shorthand for `p(p(), data0, data1)`. - function p(bytes memory data0, bytes memory data1) - internal - pure - returns (DynamicBuffer memory result) - { - p(p(result, data0), data1); - } - - /// @dev Shorthand for `p(p(), data0, .., data2)`. - function p(bytes memory data0, bytes memory data1, bytes memory data2) - internal - pure - returns (DynamicBuffer memory result) - { - p(p(p(result, data0), data1), data2); - } - - /// @dev Shorthand for `p(p(), data0, .., data3)`. - function p(bytes memory data0, bytes memory data1, bytes memory data2, bytes memory data3) - internal - pure - returns (DynamicBuffer memory result) - { - p(p(p(p(result, data0), data1), data2), data3); - } - - /// @dev Shorthand for `p(p(), data0, .., data4)`. - function p( - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4 - ) internal pure returns (DynamicBuffer memory result) { - p(p(p(p(p(result, data0), data1), data2), data3), data4); - } - - /// @dev Shorthand for `p(p(), data0, .., data5)`. - function p( - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5 - ) internal pure returns (DynamicBuffer memory result) { - p(p(p(p(p(p(result, data0), data1), data2), data3), data4), data5); - } - - /// @dev Shorthand for `p(p(), data0, .., data6)`. - function p( - bytes memory data0, - bytes memory data1, - bytes memory data2, - bytes memory data3, - bytes memory data4, - bytes memory data5, - bytes memory data6 - ) internal pure returns (DynamicBuffer memory result) { - p(p(p(p(p(p(p(result, data0), data1), data2), data3), data4), data5), data6); - } - - /// @dev Shorthand for `pBool(p(), data)`. - function pBool(bool data) internal pure returns (DynamicBuffer memory result) { - pBool(result, data); - } - - /// @dev Shorthand for `pAddress(p(), data)`. - function pAddress(address data) internal pure returns (DynamicBuffer memory result) { - pAddress(result, data); - } - - /// @dev Shorthand for `pUint8(p(), data)`. - function pUint8(uint8 data) internal pure returns (DynamicBuffer memory result) { - pUint8(result, data); - } - - /// @dev Shorthand for `pUint16(p(), data)`. - function pUint16(uint16 data) internal pure returns (DynamicBuffer memory result) { - pUint16(result, data); - } - - /// @dev Shorthand for `pUint24(p(), data)`. - function pUint24(uint24 data) internal pure returns (DynamicBuffer memory result) { - pUint24(result, data); - } - - /// @dev Shorthand for `pUint32(p(), data)`. - function pUint32(uint32 data) internal pure returns (DynamicBuffer memory result) { - pUint32(result, data); - } - - /// @dev Shorthand for `pUint40(p(), data)`. - function pUint40(uint40 data) internal pure returns (DynamicBuffer memory result) { - pUint40(result, data); - } - - /// @dev Shorthand for `pUint48(p(), data)`. - function pUint48(uint48 data) internal pure returns (DynamicBuffer memory result) { - pUint48(result, data); - } - - /// @dev Shorthand for `pUint56(p(), data)`. - function pUint56(uint56 data) internal pure returns (DynamicBuffer memory result) { - pUint56(result, data); - } - - /// @dev Shorthand for `pUint64(p(), data)`. - function pUint64(uint64 data) internal pure returns (DynamicBuffer memory result) { - pUint64(result, data); - } - - /// @dev Shorthand for `pUint72(p(), data)`. - function pUint72(uint72 data) internal pure returns (DynamicBuffer memory result) { - pUint72(result, data); - } - - /// @dev Shorthand for `pUint80(p(), data)`. - function pUint80(uint80 data) internal pure returns (DynamicBuffer memory result) { - pUint80(result, data); - } - - /// @dev Shorthand for `pUint88(p(), data)`. - function pUint88(uint88 data) internal pure returns (DynamicBuffer memory result) { - pUint88(result, data); - } - - /// @dev Shorthand for `pUint96(p(), data)`. - function pUint96(uint96 data) internal pure returns (DynamicBuffer memory result) { - pUint96(result, data); - } - - /// @dev Shorthand for `pUint104(p(), data)`. - function pUint104(uint104 data) internal pure returns (DynamicBuffer memory result) { - pUint104(result, data); - } - - /// @dev Shorthand for `pUint112(p(), data)`. - function pUint112(uint112 data) internal pure returns (DynamicBuffer memory result) { - pUint112(result, data); - } - - /// @dev Shorthand for `pUint120(p(), data)`. - function pUint120(uint120 data) internal pure returns (DynamicBuffer memory result) { - pUint120(result, data); - } - - /// @dev Shorthand for `pUint128(p(), data)`. - function pUint128(uint128 data) internal pure returns (DynamicBuffer memory result) { - pUint128(result, data); - } - - /// @dev Shorthand for `pUint136(p(), data)`. - function pUint136(uint136 data) internal pure returns (DynamicBuffer memory result) { - pUint136(result, data); - } - - /// @dev Shorthand for `pUint144(p(), data)`. - function pUint144(uint144 data) internal pure returns (DynamicBuffer memory result) { - pUint144(result, data); - } - - /// @dev Shorthand for `pUint152(p(), data)`. - function pUint152(uint152 data) internal pure returns (DynamicBuffer memory result) { - pUint152(result, data); - } - - /// @dev Shorthand for `pUint160(p(), data)`. - function pUint160(uint160 data) internal pure returns (DynamicBuffer memory result) { - pUint160(result, data); - } - - /// @dev Shorthand for `pUint168(p(), data)`. - function pUint168(uint168 data) internal pure returns (DynamicBuffer memory result) { - pUint168(result, data); - } - - /// @dev Shorthand for `pUint176(p(), data)`. - function pUint176(uint176 data) internal pure returns (DynamicBuffer memory result) { - pUint176(result, data); - } - - /// @dev Shorthand for `pUint184(p(), data)`. - function pUint184(uint184 data) internal pure returns (DynamicBuffer memory result) { - pUint184(result, data); - } - - /// @dev Shorthand for `pUint192(p(), data)`. - function pUint192(uint192 data) internal pure returns (DynamicBuffer memory result) { - pUint192(result, data); - } - - /// @dev Shorthand for `pUint200(p(), data)`. - function pUint200(uint200 data) internal pure returns (DynamicBuffer memory result) { - pUint200(result, data); - } - - /// @dev Shorthand for `pUint208(p(), data)`. - function pUint208(uint208 data) internal pure returns (DynamicBuffer memory result) { - pUint208(result, data); - } - - /// @dev Shorthand for `pUint216(p(), data)`. - function pUint216(uint216 data) internal pure returns (DynamicBuffer memory result) { - pUint216(result, data); - } - - /// @dev Shorthand for `pUint224(p(), data)`. - function pUint224(uint224 data) internal pure returns (DynamicBuffer memory result) { - pUint224(result, data); - } - - /// @dev Shorthand for `pUint232(p(), data)`. - function pUint232(uint232 data) internal pure returns (DynamicBuffer memory result) { - pUint232(result, data); - } - - /// @dev Shorthand for `pUint240(p(), data)`. - function pUint240(uint240 data) internal pure returns (DynamicBuffer memory result) { - pUint240(result, data); - } - - /// @dev Shorthand for `pUint248(p(), data)`. - function pUint248(uint248 data) internal pure returns (DynamicBuffer memory result) { - pUint248(result, data); - } - - /// @dev Shorthand for `pUint256(p(), data)`. - function pUint256(uint256 data) internal pure returns (DynamicBuffer memory result) { - pUint256(result, data); - } - - /// @dev Shorthand for `pBytes1(p(), data)`. - function pBytes1(bytes1 data) internal pure returns (DynamicBuffer memory result) { - pBytes1(result, data); - } - - /// @dev Shorthand for `pBytes2(p(), data)`. - function pBytes2(bytes2 data) internal pure returns (DynamicBuffer memory result) { - pBytes2(result, data); - } - - /// @dev Shorthand for `pBytes3(p(), data)`. - function pBytes3(bytes3 data) internal pure returns (DynamicBuffer memory result) { - pBytes3(result, data); - } - - /// @dev Shorthand for `pBytes4(p(), data)`. - function pBytes4(bytes4 data) internal pure returns (DynamicBuffer memory result) { - pBytes4(result, data); - } - - /// @dev Shorthand for `pBytes5(p(), data)`. - function pBytes5(bytes5 data) internal pure returns (DynamicBuffer memory result) { - pBytes5(result, data); - } - - /// @dev Shorthand for `pBytes6(p(), data)`. - function pBytes6(bytes6 data) internal pure returns (DynamicBuffer memory result) { - pBytes6(result, data); - } - - /// @dev Shorthand for `pBytes7(p(), data)`. - function pBytes7(bytes7 data) internal pure returns (DynamicBuffer memory result) { - pBytes7(result, data); - } - - /// @dev Shorthand for `pBytes8(p(), data)`. - function pBytes8(bytes8 data) internal pure returns (DynamicBuffer memory result) { - pBytes8(result, data); - } - - /// @dev Shorthand for `pBytes9(p(), data)`. - function pBytes9(bytes9 data) internal pure returns (DynamicBuffer memory result) { - pBytes9(result, data); - } - - /// @dev Shorthand for `pBytes10(p(), data)`. - function pBytes10(bytes10 data) internal pure returns (DynamicBuffer memory result) { - pBytes10(result, data); - } - - /// @dev Shorthand for `pBytes11(p(), data)`. - function pBytes11(bytes11 data) internal pure returns (DynamicBuffer memory result) { - pBytes11(result, data); - } - - /// @dev Shorthand for `pBytes12(p(), data)`. - function pBytes12(bytes12 data) internal pure returns (DynamicBuffer memory result) { - pBytes12(result, data); - } - - /// @dev Shorthand for `pBytes13(p(), data)`. - function pBytes13(bytes13 data) internal pure returns (DynamicBuffer memory result) { - pBytes13(result, data); - } - - /// @dev Shorthand for `pBytes14(p(), data)`. - function pBytes14(bytes14 data) internal pure returns (DynamicBuffer memory result) { - pBytes14(result, data); - } - - /// @dev Shorthand for `pBytes15(p(), data)`. - function pBytes15(bytes15 data) internal pure returns (DynamicBuffer memory result) { - pBytes15(result, data); - } - - /// @dev Shorthand for `pBytes16(p(), data)`. - function pBytes16(bytes16 data) internal pure returns (DynamicBuffer memory result) { - pBytes16(result, data); - } - - /// @dev Shorthand for `pBytes17(p(), data)`. - function pBytes17(bytes17 data) internal pure returns (DynamicBuffer memory result) { - pBytes17(result, data); - } - - /// @dev Shorthand for `pBytes18(p(), data)`. - function pBytes18(bytes18 data) internal pure returns (DynamicBuffer memory result) { - pBytes18(result, data); - } - - /// @dev Shorthand for `pBytes19(p(), data)`. - function pBytes19(bytes19 data) internal pure returns (DynamicBuffer memory result) { - pBytes19(result, data); - } - - /// @dev Shorthand for `pBytes20(p(), data)`. - function pBytes20(bytes20 data) internal pure returns (DynamicBuffer memory result) { - pBytes20(result, data); - } - - /// @dev Shorthand for `pBytes21(p(), data)`. - function pBytes21(bytes21 data) internal pure returns (DynamicBuffer memory result) { - pBytes21(result, data); - } - - /// @dev Shorthand for `pBytes22(p(), data)`. - function pBytes22(bytes22 data) internal pure returns (DynamicBuffer memory result) { - pBytes22(result, data); - } - - /// @dev Shorthand for `pBytes23(p(), data)`. - function pBytes23(bytes23 data) internal pure returns (DynamicBuffer memory result) { - pBytes23(result, data); - } - - /// @dev Shorthand for `pBytes24(p(), data)`. - function pBytes24(bytes24 data) internal pure returns (DynamicBuffer memory result) { - pBytes24(result, data); - } - - /// @dev Shorthand for `pBytes25(p(), data)`. - function pBytes25(bytes25 data) internal pure returns (DynamicBuffer memory result) { - pBytes25(result, data); - } - - /// @dev Shorthand for `pBytes26(p(), data)`. - function pBytes26(bytes26 data) internal pure returns (DynamicBuffer memory result) { - pBytes26(result, data); - } - - /// @dev Shorthand for `pBytes27(p(), data)`. - function pBytes27(bytes27 data) internal pure returns (DynamicBuffer memory result) { - pBytes27(result, data); - } - - /// @dev Shorthand for `pBytes28(p(), data)`. - function pBytes28(bytes28 data) internal pure returns (DynamicBuffer memory result) { - pBytes28(result, data); - } - - /// @dev Shorthand for `pBytes29(p(), data)`. - function pBytes29(bytes29 data) internal pure returns (DynamicBuffer memory result) { - pBytes29(result, data); - } - - /// @dev Shorthand for `pBytes30(p(), data)`. - function pBytes30(bytes30 data) internal pure returns (DynamicBuffer memory result) { - pBytes30(result, data); - } - - /// @dev Shorthand for `pBytes31(p(), data)`. - function pBytes31(bytes31 data) internal pure returns (DynamicBuffer memory result) { - pBytes31(result, data); - } - - /// @dev Shorthand for `pBytes32(p(), data)`. - function pBytes32(bytes32 data) internal pure returns (DynamicBuffer memory result) { - pBytes32(result, data); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper for deallocating an automatically allocated `buffer` pointer. - function _deallocate(DynamicBuffer memory result) private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Deallocate, as we have already allocated. - } - } - - /// @dev Returns a temporary bytes string of length `n` for `data`. - function _single(uint256 data, uint256 n) private pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := 0x00 - mstore(n, data) - mstore(result, n) - } - } - - /// @dev Returns a temporary bytes string of length `n` for `data`. - function _single(bytes32 data, uint256 n) private pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := 0x00 - mstore(0x20, data) - mstore(result, n) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/EnumerableMapLib.sol b/grouperBot/lib/solady/src/utils/g/EnumerableMapLib.sol deleted file mode 100644 index 8a7f961..0000000 --- a/grouperBot/lib/solady/src/utils/g/EnumerableMapLib.sol +++ /dev/null @@ -1,832 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev An enumerable map of `bytes32` to `bytes32`. -struct Bytes32ToBytes32Map { - EnumerableSetLib.Bytes32Set _keys; - mapping(bytes32 => bytes32) _values; -} - -/// @dev An enumerable map of `bytes32` to `uint256`. -struct Bytes32ToUint256Map { - EnumerableSetLib.Bytes32Set _keys; - mapping(bytes32 => uint256) _values; -} - -/// @dev An enumerable map of `bytes32` to `address`. -struct Bytes32ToAddressMap { - EnumerableSetLib.Bytes32Set _keys; - mapping(bytes32 => address) _values; -} - -/// @dev An enumerable map of `uint256` to `bytes32`. -struct Uint256ToBytes32Map { - EnumerableSetLib.Uint256Set _keys; - mapping(uint256 => bytes32) _values; -} - -/// @dev An enumerable map of `uint256` to `uint256`. -struct Uint256ToUint256Map { - EnumerableSetLib.Uint256Set _keys; - mapping(uint256 => uint256) _values; -} - -/// @dev An enumerable map of `uint256` to `address`. -struct Uint256ToAddressMap { - EnumerableSetLib.Uint256Set _keys; - mapping(uint256 => address) _values; -} - -/// @dev An enumerable map of `address` to `bytes32`. -struct AddressToBytes32Map { - EnumerableSetLib.AddressSet _keys; - mapping(address => bytes32) _values; -} - -/// @dev An enumerable map of `address` to `uint256`. -struct AddressToUint256Map { - EnumerableSetLib.AddressSet _keys; - mapping(address => uint256) _values; -} - -/// @dev An enumerable map of `address` to `address`. -struct AddressToAddressMap { - EnumerableSetLib.AddressSet _keys; - mapping(address => address) _values; -} - -using EnumerableMapLib for Bytes32ToBytes32Map global; -using EnumerableMapLib for Bytes32ToUint256Map global; -using EnumerableMapLib for Bytes32ToAddressMap global; -using EnumerableMapLib for Uint256ToBytes32Map global; -using EnumerableMapLib for Uint256ToUint256Map global; -using EnumerableMapLib for Uint256ToAddressMap global; -using EnumerableMapLib for AddressToBytes32Map global; -using EnumerableMapLib for AddressToUint256Map global; -using EnumerableMapLib for AddressToAddressMap global; - -import {EnumerableSetLib} from "../EnumerableSetLib.sol"; - -/// @notice Library for managing enumerable maps in storage. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/EnumerableMapLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableMap.sol) -library EnumerableMapLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The key does not exist in the enumerable map. - error EnumerableMapKeyNotFound(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* GETTERS / SETTERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Bytes32ToBytes32Map storage map, - bytes32 key, - bytes32 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Bytes32ToBytes32Map storage map, uint256 i) - internal - view - returns (bytes32 key, bytes32 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) - internal - view - returns (bool exists, bytes32 value) - { - exists = (value = map._values[key]) != bytes32(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Bytes32ToBytes32Map storage map, bytes32 key) - internal - view - returns (bytes32 value) - { - if ((value = map._values[key]) == bytes32(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Bytes32ToUint256Map storage map, bytes32 key, uint256 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Bytes32ToUint256Map storage map, bytes32 key, uint256 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Bytes32ToUint256Map storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Bytes32ToUint256Map storage map, - bytes32 key, - uint256 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Bytes32ToUint256Map storage map, bytes32 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Bytes32ToUint256Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Bytes32ToUint256Map storage map, uint256 i) - internal - view - returns (bytes32 key, uint256 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Bytes32ToUint256Map storage map, bytes32 key) - internal - view - returns (bool exists, uint256 value) - { - exists = (value = map._values[key]) != uint256(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Bytes32ToUint256Map storage map, bytes32 key) - internal - view - returns (uint256 value) - { - if ((value = map._values[key]) == uint256(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Bytes32ToUint256Map storage map) internal view returns (bytes32[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Bytes32ToAddressMap storage map, bytes32 key, address value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Bytes32ToAddressMap storage map, bytes32 key, address value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Bytes32ToAddressMap storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Bytes32ToAddressMap storage map, - bytes32 key, - address value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Bytes32ToAddressMap storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Bytes32ToAddressMap storage map, uint256 i) - internal - view - returns (bytes32 key, address value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Bytes32ToAddressMap storage map, bytes32 key) - internal - view - returns (bool exists, address value) - { - exists = (value = map._values[key]) != address(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Bytes32ToAddressMap storage map, bytes32 key) - internal - view - returns (address value) - { - if ((value = map._values[key]) == address(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Uint256ToBytes32Map storage map, uint256 key, bytes32 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Uint256ToBytes32Map storage map, uint256 key, bytes32 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Uint256ToBytes32Map storage map, uint256 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Uint256ToBytes32Map storage map, - uint256 key, - bytes32 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Uint256ToBytes32Map storage map, uint256 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Uint256ToBytes32Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Uint256ToBytes32Map storage map, uint256 i) - internal - view - returns (uint256 key, bytes32 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Uint256ToBytes32Map storage map, uint256 key) - internal - view - returns (bool exists, bytes32 value) - { - exists = (value = map._values[key]) != bytes32(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Uint256ToBytes32Map storage map, uint256 key) - internal - view - returns (bytes32 value) - { - if ((value = map._values[key]) == bytes32(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Uint256ToBytes32Map storage map) internal view returns (uint256[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Uint256ToUint256Map storage map, uint256 key, uint256 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Uint256ToUint256Map storage map, uint256 key, uint256 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Uint256ToUint256Map storage map, uint256 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Uint256ToUint256Map storage map, - uint256 key, - uint256 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Uint256ToUint256Map storage map, uint256 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Uint256ToUint256Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Uint256ToUint256Map storage map, uint256 i) - internal - view - returns (uint256 key, uint256 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Uint256ToUint256Map storage map, uint256 key) - internal - view - returns (bool exists, uint256 value) - { - exists = (value = map._values[key]) != uint256(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Uint256ToUint256Map storage map, uint256 key) - internal - view - returns (uint256 value) - { - if ((value = map._values[key]) == uint256(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Uint256ToUint256Map storage map) internal view returns (uint256[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(Uint256ToAddressMap storage map, uint256 key, address value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(Uint256ToAddressMap storage map, uint256 key, address value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(Uint256ToAddressMap storage map, uint256 key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - Uint256ToAddressMap storage map, - uint256 key, - address value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(Uint256ToAddressMap storage map, uint256 key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(Uint256ToAddressMap storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(Uint256ToAddressMap storage map, uint256 i) - internal - view - returns (uint256 key, address value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(Uint256ToAddressMap storage map, uint256 key) - internal - view - returns (bool exists, address value) - { - exists = (value = map._values[key]) != address(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(Uint256ToAddressMap storage map, uint256 key) - internal - view - returns (address value) - { - if ((value = map._values[key]) == address(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(Uint256ToAddressMap storage map) internal view returns (uint256[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(AddressToBytes32Map storage map, address key, bytes32 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(AddressToBytes32Map storage map, address key, bytes32 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(AddressToBytes32Map storage map, address key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - AddressToBytes32Map storage map, - address key, - bytes32 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(AddressToBytes32Map storage map, address key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(AddressToBytes32Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(AddressToBytes32Map storage map, uint256 i) - internal - view - returns (address key, bytes32 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(AddressToBytes32Map storage map, address key) - internal - view - returns (bool exists, bytes32 value) - { - exists = (value = map._values[key]) != bytes32(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(AddressToBytes32Map storage map, address key) - internal - view - returns (bytes32 value) - { - if ((value = map._values[key]) == bytes32(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(AddressToUint256Map storage map, address key, uint256 value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(AddressToUint256Map storage map, address key, uint256 value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(AddressToUint256Map storage map, address key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - AddressToUint256Map storage map, - address key, - uint256 value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(AddressToUint256Map storage map, address key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(AddressToUint256Map storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(AddressToUint256Map storage map, uint256 i) - internal - view - returns (address key, uint256 value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(AddressToUint256Map storage map, address key) - internal - view - returns (bool exists, uint256 value) - { - exists = (value = map._values[key]) != uint256(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(AddressToUint256Map storage map, address key) - internal - view - returns (uint256 value) - { - if ((value = map._values[key]) == uint256(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(AddressToUint256Map storage map) internal view returns (address[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - function set(AddressToAddressMap storage map, address key, address value) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key); - } - - /// @dev Adds a key-value pair to the map, or updates the value for an existing key. - /// Returns true if `key` was added to the map, that is if it was not already present. - /// Reverts if the map grows bigger than the custom on-the-fly capacity `cap`. - function set(AddressToAddressMap storage map, address key, address value, uint256 cap) - internal - returns (bool) - { - map._values[key] = value; - return EnumerableSetLib.add(map._keys, key, cap); - } - - /// @dev Removes a key-value pair from the map. - /// Returns true if `key` was removed from the map, that is if it was present. - function remove(AddressToAddressMap storage map, address key) internal returns (bool) { - delete map._values[key]; - return EnumerableSetLib.remove(map._keys, key); - } - - /// @dev Shorthand for `isAdd ? map.set(key, value, cap) : map.remove(key)`. - function update( - AddressToAddressMap storage map, - address key, - address value, - bool isAdd, - uint256 cap - ) internal returns (bool) { - return isAdd ? set(map, key, value, cap) : remove(map, key); - } - - /// @dev Returns true if the key is in the map. - function contains(AddressToAddressMap storage map, address key) internal view returns (bool) { - return EnumerableSetLib.contains(map._keys, key); - } - - /// @dev Returns the number of key-value pairs in the map. - function length(AddressToAddressMap storage map) internal view returns (uint256) { - return EnumerableSetLib.length(map._keys); - } - - /// @dev Returns the key-value pair at index `i`. Reverts if `i` is out-of-bounds. - function at(AddressToAddressMap storage map, uint256 i) - internal - view - returns (address key, address value) - { - value = map._values[key = EnumerableSetLib.at(map._keys, i)]; - } - - /// @dev Tries to return the value associated with the key. - function tryGet(AddressToAddressMap storage map, address key) - internal - view - returns (bool exists, address value) - { - exists = (value = map._values[key]) != address(0) || contains(map, key); - } - - /// @dev Returns the value for the key. Reverts if the key is not found. - function get(AddressToAddressMap storage map, address key) - internal - view - returns (address value) - { - if ((value = map._values[key]) == address(0)) if (!contains(map, key)) _revertNotFound(); - } - - /// @dev Returns the keys. May run out-of-gas if the map is too big. - function keys(AddressToAddressMap storage map) internal view returns (address[] memory) { - return EnumerableSetLib.values(map._keys); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Reverts with `EnumerableMapKeyNotFound()`. - function _revertNotFound() private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x88682bf3) // `EnumerableMapKeyNotFound()`. - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/EnumerableSetLib.sol b/grouperBot/lib/solady/src/utils/g/EnumerableSetLib.sol deleted file mode 100644 index dc879f1..0000000 --- a/grouperBot/lib/solady/src/utils/g/EnumerableSetLib.sol +++ /dev/null @@ -1,926 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev An enumerable address set in storage. -struct AddressSet { - uint256 _spacer; -} - -/// @dev An enumerable bytes32 set in storage. -struct Bytes32Set { - uint256 _spacer; -} - -/// @dev An enumerable uint256 set in storage. -struct Uint256Set { - uint256 _spacer; -} - -/// @dev An enumerable int256 set in storage. -struct Int256Set { - uint256 _spacer; -} - -/// @dev An enumerable uint8 set in storage. Useful for enums. -struct Uint8Set { - uint256 data; -} - -using EnumerableSetLib for AddressSet global; -using EnumerableSetLib for Bytes32Set global; -using EnumerableSetLib for Uint256Set global; -using EnumerableSetLib for Int256Set global; -using EnumerableSetLib for Uint8Set global; - -/// @notice Library for managing enumerable sets in storage. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/EnumerableSetLib.sol) -/// -/// @dev Note: -/// In many applications, the number of elements in an enumerable set is small. -/// This enumerable set implementation avoids storing the length and indices -/// for up to 3 elements. Once the length exceeds 3 for the first time, the length -/// and indices will be initialized. The amortized cost of adding elements is O(1). -/// -/// The AddressSet implementation packs the length with the 0th entry. -/// -/// All enumerable sets except Uint8Set use a pop and swap mechanism to remove elements. -/// This means that the iteration order of elements can change between element removals. -library EnumerableSetLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The index must be less than the length. - error IndexOutOfBounds(); - - /// @dev The value cannot be the zero sentinel. - error ValueIsZeroSentinel(); - - /// @dev Cannot accommodate a new unique value with the capacity. - error ExceedsCapacity(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The index to represent a value that does not exist. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /// @dev A sentinel value to denote the zero value in storage. - /// No elements can be equal to this value. - /// `uint72(bytes9(keccak256(bytes("_ZERO_SENTINEL"))))`. - uint256 private constant _ZERO_SENTINEL = 0xfbb67fda52d4bfb8bf; - - /// @dev The storage layout is given by: - /// ``` - /// mstore(0x04, _ENUMERABLE_ADDRESS_SET_SLOT_SEED) - /// mstore(0x00, set.slot) - /// let rootSlot := keccak256(0x00, 0x24) - /// mstore(0x20, rootSlot) - /// mstore(0x00, shr(96, shl(96, value))) - /// let positionSlot := keccak256(0x00, 0x40) - /// let valueSlot := add(rootSlot, sload(positionSlot)) - /// let valueInStorage := shr(96, sload(valueSlot)) - /// let lazyLength := shr(160, shl(160, sload(rootSlot))) - /// ``` - uint256 private constant _ENUMERABLE_ADDRESS_SET_SLOT_SEED = 0x978aab92; - - /// @dev The storage layout is given by: - /// ``` - /// mstore(0x04, _ENUMERABLE_WORD_SET_SLOT_SEED) - /// mstore(0x00, set.slot) - /// let rootSlot := keccak256(0x00, 0x24) - /// mstore(0x20, rootSlot) - /// mstore(0x00, value) - /// let positionSlot := keccak256(0x00, 0x40) - /// let valueSlot := add(rootSlot, sload(positionSlot)) - /// let valueInStorage := sload(valueSlot) - /// let lazyLength := sload(not(rootSlot)) - /// ``` - uint256 private constant _ENUMERABLE_WORD_SET_SLOT_SEED = 0x18fb5864; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* GETTERS / SETTERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of elements in the set. - function length(AddressSet storage set) internal view returns (uint256 result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let rootPacked := sload(rootSlot) - let n := shr(160, shl(160, rootPacked)) - result := shr(1, n) - for {} iszero(or(iszero(shr(96, rootPacked)), n)) {} { - result := 1 - if iszero(sload(add(rootSlot, result))) { break } - result := 2 - if iszero(sload(add(rootSlot, result))) { break } - result := 3 - break - } - } - } - - /// @dev Returns the number of elements in the set. - function length(Bytes32Set storage set) internal view returns (uint256 result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let n := sload(not(rootSlot)) - result := shr(1, n) - for {} iszero(n) {} { - result := 0 - if iszero(sload(add(rootSlot, result))) { break } - result := 1 - if iszero(sload(add(rootSlot, result))) { break } - result := 2 - if iszero(sload(add(rootSlot, result))) { break } - result := 3 - break - } - } - } - - /// @dev Returns the number of elements in the set. - function length(Uint256Set storage set) internal view returns (uint256 result) { - result = length(_toBytes32Set(set)); - } - - /// @dev Returns the number of elements in the set. - function length(Int256Set storage set) internal view returns (uint256 result) { - result = length(_toBytes32Set(set)); - } - - /// @dev Returns the number of elements in the set. - function length(Uint8Set storage set) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - for { let packed := sload(set.slot) } packed { result := add(1, result) } { - packed := xor(packed, and(packed, add(1, not(packed)))) - } - } - } - - /// @dev Returns whether `value` is in the set. - function contains(AddressSet storage set, address value) internal view returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - value := shr(96, shl(96, value)) - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - let rootPacked := sload(rootSlot) - for {} 1 {} { - if iszero(shr(160, shl(160, rootPacked))) { - result := 1 - if eq(shr(96, rootPacked), value) { break } - if eq(shr(96, sload(add(rootSlot, 1))), value) { break } - if eq(shr(96, sload(add(rootSlot, 2))), value) { break } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := iszero(iszero(sload(keccak256(0x00, 0x40)))) - break - } - } - } - - /// @dev Returns whether `value` is in the set. - function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - for {} 1 {} { - if iszero(sload(not(rootSlot))) { - result := 1 - if eq(sload(rootSlot), value) { break } - if eq(sload(add(rootSlot, 1)), value) { break } - if eq(sload(add(rootSlot, 2)), value) { break } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := iszero(iszero(sload(keccak256(0x00, 0x40)))) - break - } - } - } - - /// @dev Returns whether `value` is in the set. - function contains(Uint256Set storage set, uint256 value) internal view returns (bool result) { - result = contains(_toBytes32Set(set), bytes32(value)); - } - - /// @dev Returns whether `value` is in the set. - function contains(Int256Set storage set, int256 value) internal view returns (bool result) { - result = contains(_toBytes32Set(set), bytes32(uint256(value))); - } - - /// @dev Returns whether `value` is in the set. - function contains(Uint8Set storage set, uint8 value) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := and(1, shr(and(0xff, value), sload(set.slot))) - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(AddressSet storage set, address value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - value := shr(96, shl(96, value)) - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - let rootPacked := sload(rootSlot) - for { let n := shr(160, shl(160, rootPacked)) } 1 {} { - mstore(0x20, rootSlot) - if iszero(n) { - let v0 := shr(96, rootPacked) - if iszero(v0) { - sstore(rootSlot, shl(96, value)) - result := 1 - break - } - if eq(v0, value) { break } - let v1 := shr(96, sload(add(rootSlot, 1))) - if iszero(v1) { - sstore(add(rootSlot, 1), shl(96, value)) - result := 1 - break - } - if eq(v1, value) { break } - let v2 := shr(96, sload(add(rootSlot, 2))) - if iszero(v2) { - sstore(add(rootSlot, 2), shl(96, value)) - result := 1 - break - } - if eq(v2, value) { break } - mstore(0x00, v0) - sstore(keccak256(0x00, 0x40), 1) - mstore(0x00, v1) - sstore(keccak256(0x00, 0x40), 2) - mstore(0x00, v2) - sstore(keccak256(0x00, 0x40), 3) - rootPacked := or(rootPacked, 7) - n := 7 - } - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - if iszero(sload(p)) { - n := shr(1, n) - result := 1 - sstore(p, add(1, n)) - if iszero(n) { - sstore(rootSlot, or(3, shl(96, value))) - break - } - sstore(add(rootSlot, n), shl(96, value)) - sstore(rootSlot, add(2, rootPacked)) - break - } - break - } - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Bytes32Set storage set, bytes32 value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - for { let n := sload(not(rootSlot)) } 1 {} { - mstore(0x20, rootSlot) - if iszero(n) { - let v0 := sload(rootSlot) - if iszero(v0) { - sstore(rootSlot, value) - result := 1 - break - } - if eq(v0, value) { break } - let v1 := sload(add(rootSlot, 1)) - if iszero(v1) { - sstore(add(rootSlot, 1), value) - result := 1 - break - } - if eq(v1, value) { break } - let v2 := sload(add(rootSlot, 2)) - if iszero(v2) { - sstore(add(rootSlot, 2), value) - result := 1 - break - } - if eq(v2, value) { break } - mstore(0x00, v0) - sstore(keccak256(0x00, 0x40), 1) - mstore(0x00, v1) - sstore(keccak256(0x00, 0x40), 2) - mstore(0x00, v2) - sstore(keccak256(0x00, 0x40), 3) - n := 7 - } - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - if iszero(sload(p)) { - n := shr(1, n) - sstore(add(rootSlot, n), value) - sstore(p, add(1, n)) - sstore(not(rootSlot), or(1, shl(1, add(1, n)))) - result := 1 - break - } - break - } - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Uint256Set storage set, uint256 value) internal returns (bool result) { - result = add(_toBytes32Set(set), bytes32(value)); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Int256Set storage set, int256 value) internal returns (bool result) { - result = add(_toBytes32Set(set), bytes32(uint256(value))); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - function add(Uint8Set storage set, uint8 value) internal returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(set.slot) - let mask := shl(and(0xff, value), 1) - sstore(set.slot, or(result, mask)) - result := iszero(and(result, mask)) - } - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(AddressSet storage set, address value, uint256 cap) - internal - returns (bool result) - { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Bytes32Set storage set, bytes32 value, uint256 cap) - internal - returns (bool result) - { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Uint256Set storage set, uint256 value, uint256 cap) - internal - returns (bool result) - { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Int256Set storage set, int256 value, uint256 cap) internal returns (bool result) { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Adds `value` to the set. Returns whether `value` was not in the set. - /// Reverts if the set grows bigger than the custom on-the-fly capacity `cap`. - function add(Uint8Set storage set, uint8 value, uint256 cap) internal returns (bool result) { - if (result = add(set, value)) if (length(set) > cap) revert ExceedsCapacity(); - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(AddressSet storage set, address value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - value := shr(96, shl(96, value)) - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - let rootPacked := sload(rootSlot) - for { let n := shr(160, shl(160, rootPacked)) } 1 {} { - if iszero(n) { - result := 1 - if eq(shr(96, rootPacked), value) { - sstore(rootSlot, sload(add(rootSlot, 1))) - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(shr(96, sload(add(rootSlot, 1))), value) { - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(shr(96, sload(add(rootSlot, 2))), value) { - sstore(add(rootSlot, 2), 0) - break - } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - let position := sload(p) - if iszero(position) { break } - n := sub(shr(1, n), 1) - if iszero(eq(sub(position, 1), n)) { - let lastValue := shr(96, sload(add(rootSlot, n))) - sstore(add(rootSlot, sub(position, 1)), shl(96, lastValue)) - mstore(0x00, lastValue) - sstore(keccak256(0x00, 0x40), position) - } - sstore(rootSlot, or(shl(96, shr(96, sload(rootSlot))), or(shl(1, n), 1))) - sstore(p, 0) - result := 1 - break - } - } - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Bytes32Set storage set, bytes32 value) internal returns (bool result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if eq(value, _ZERO_SENTINEL) { - mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. - revert(0x1c, 0x04) - } - if iszero(value) { value := _ZERO_SENTINEL } - for { let n := sload(not(rootSlot)) } 1 {} { - if iszero(n) { - result := 1 - if eq(sload(rootSlot), value) { - sstore(rootSlot, sload(add(rootSlot, 1))) - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(sload(add(rootSlot, 1)), value) { - sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) - sstore(add(rootSlot, 2), 0) - break - } - if eq(sload(add(rootSlot, 2)), value) { - sstore(add(rootSlot, 2), 0) - break - } - result := 0 - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - let p := keccak256(0x00, 0x40) - let position := sload(p) - if iszero(position) { break } - n := sub(shr(1, n), 1) - if iszero(eq(sub(position, 1), n)) { - let lastValue := sload(add(rootSlot, n)) - sstore(add(rootSlot, sub(position, 1)), lastValue) - mstore(0x00, lastValue) - sstore(keccak256(0x00, 0x40), position) - } - sstore(not(rootSlot), or(shl(1, n), 1)) - sstore(p, 0) - result := 1 - break - } - } - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Uint256Set storage set, uint256 value) internal returns (bool result) { - result = remove(_toBytes32Set(set), bytes32(value)); - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Int256Set storage set, int256 value) internal returns (bool result) { - result = remove(_toBytes32Set(set), bytes32(uint256(value))); - } - - /// @dev Removes `value` from the set. Returns whether `value` was in the set. - function remove(Uint8Set storage set, uint8 value) internal returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := sload(set.slot) - let mask := shl(and(0xff, value), 1) - sstore(set.slot, and(result, not(mask))) - result := iszero(iszero(and(result, mask))) - } - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(AddressSet storage set, address value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Bytes32Set storage set, bytes32 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Uint256Set storage set, uint256 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Int256Set storage set, int256 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Shorthand for `isAdd ? set.add(value, cap) : set.remove(value)`. - function update(Uint8Set storage set, uint8 value, bool isAdd, uint256 cap) - internal - returns (bool) - { - return isAdd ? add(set, value, cap) : remove(set, value); - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(AddressSet storage set) internal view returns (address[] memory result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let zs := _ZERO_SENTINEL - let rootPacked := sload(rootSlot) - let n := shr(160, shl(160, rootPacked)) - result := mload(0x40) - let o := add(0x20, result) - let v := shr(96, rootPacked) - mstore(o, mul(v, iszero(eq(v, zs)))) - for {} 1 {} { - if iszero(n) { - if v { - n := 1 - v := shr(96, sload(add(rootSlot, n))) - if v { - n := 2 - mstore(add(o, 0x20), mul(v, iszero(eq(v, zs)))) - v := shr(96, sload(add(rootSlot, n))) - if v { - n := 3 - mstore(add(o, 0x40), mul(v, iszero(eq(v, zs)))) - } - } - } - break - } - n := shr(1, n) - for { let i := 1 } lt(i, n) { i := add(i, 1) } { - v := shr(96, sload(add(rootSlot, i))) - mstore(add(o, shl(5, i)), mul(v, iszero(eq(v, zs)))) - } - break - } - mstore(result, n) - mstore(0x40, add(o, shl(5, n))) - } - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(Bytes32Set storage set) internal view returns (bytes32[] memory result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - let zs := _ZERO_SENTINEL - let n := sload(not(rootSlot)) - result := mload(0x40) - let o := add(0x20, result) - for {} 1 {} { - if iszero(n) { - let v := sload(rootSlot) - if v { - n := 1 - mstore(o, mul(v, iszero(eq(v, zs)))) - v := sload(add(rootSlot, n)) - if v { - n := 2 - mstore(add(o, 0x20), mul(v, iszero(eq(v, zs)))) - v := sload(add(rootSlot, n)) - if v { - n := 3 - mstore(add(o, 0x40), mul(v, iszero(eq(v, zs)))) - } - } - } - break - } - n := shr(1, n) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - let v := sload(add(rootSlot, i)) - mstore(add(o, shl(5, i)), mul(v, iszero(eq(v, zs)))) - } - break - } - mstore(result, n) - mstore(0x40, add(o, shl(5, n))) - } - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(Uint256Set storage set) internal view returns (uint256[] memory result) { - result = _toUints(values(_toBytes32Set(set))); - } - - /// @dev Returns all of the values in the set. - /// Note: This can consume more gas than the block gas limit for large sets. - function values(Int256Set storage set) internal view returns (int256[] memory result) { - result = _toInts(values(_toBytes32Set(set))); - } - - /// @dev Returns all of the values in the set. - function values(Uint8Set storage set) internal view returns (uint8[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let ptr := add(result, 0x20) - let o := 0 - for { let packed := sload(set.slot) } packed {} { - if iszero(and(packed, 0xffff)) { - o := add(o, 16) - packed := shr(16, packed) - continue - } - mstore(ptr, o) - ptr := add(ptr, shl(5, and(packed, 1))) - o := add(o, 1) - packed := shr(1, packed) - } - mstore(result, shr(5, sub(ptr, add(result, 0x20)))) - mstore(0x40, ptr) - } - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(AddressSet storage set, uint256 i) internal view returns (address result) { - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - result := shr(96, sload(add(rootSlot, i))) - result := mul(result, iszero(eq(result, _ZERO_SENTINEL))) - } - if (i >= length(set)) revert IndexOutOfBounds(); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Bytes32Set storage set, uint256 i) internal view returns (bytes32 result) { - result = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - result := sload(add(result, i)) - result := mul(result, iszero(eq(result, _ZERO_SENTINEL))) - } - if (i >= length(set)) revert IndexOutOfBounds(); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Uint256Set storage set, uint256 i) internal view returns (uint256 result) { - result = uint256(at(_toBytes32Set(set), i)); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Int256Set storage set, uint256 i) internal view returns (int256 result) { - result = int256(uint256(at(_toBytes32Set(set), i))); - } - - /// @dev Returns the element at index `i` in the set. Reverts if `i` is out-of-bounds. - function at(Uint8Set storage set, uint256 i) internal view returns (uint8 result) { - /// @solidity memory-safe-assembly - assembly { - let packed := sload(set.slot) - for {} 1 { - mstore(0x00, 0x4e23d035) // `IndexOutOfBounds()`. - revert(0x1c, 0x04) - } { - if iszero(lt(i, 256)) { continue } - for { let j := 0 } iszero(eq(i, j)) {} { - packed := xor(packed, and(packed, add(1, not(packed)))) - j := add(j, 1) - } - if iszero(packed) { continue } - break - } - // Find first set subroutine, optimized for smaller bytecode size. - let x := and(packed, add(1, not(packed))) - let r := shl(7, iszero(iszero(shr(128, x)))) - r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x)))))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - // For the lower 5 bits of the result, use a De Bruijn lookup. - // forgefmt: disable-next-item - result := or(r, byte(and(div(0xd76453e0, shr(r, x)), 0x1f), - 0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405)) - } - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(AddressSet storage set, address value) - internal - view - returns (uint256 result) - { - result = NOT_FOUND; - if (uint160(value) == _ZERO_SENTINEL) return result; - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if iszero(value) { value := _ZERO_SENTINEL } - result := not(0) - let rootPacked := sload(rootSlot) - for {} 1 {} { - if iszero(shr(160, shl(160, rootPacked))) { - if eq(shr(96, rootPacked), value) { - result := 0 - break - } - if eq(shr(96, sload(add(rootSlot, 1))), value) { - result := 1 - break - } - if eq(shr(96, sload(add(rootSlot, 2))), value) { - result := 2 - break - } - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := sub(sload(keccak256(0x00, 0x40)), 1) - break - } - } - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Bytes32Set storage set, bytes32 value) - internal - view - returns (uint256 result) - { - result = NOT_FOUND; - if (uint256(value) == _ZERO_SENTINEL) return result; - bytes32 rootSlot = _rootSlot(set); - /// @solidity memory-safe-assembly - assembly { - if iszero(value) { value := _ZERO_SENTINEL } - for {} 1 {} { - if iszero(sload(not(rootSlot))) { - if eq(sload(rootSlot), value) { - result := 0 - break - } - if eq(sload(add(rootSlot, 1)), value) { - result := 1 - break - } - if eq(sload(add(rootSlot, 2)), value) { - result := 2 - break - } - break - } - mstore(0x20, rootSlot) - mstore(0x00, value) - result := sub(sload(keccak256(0x00, 0x40)), 1) - break - } - } - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Uint256Set storage set, uint256 i) internal view returns (uint256 result) { - result = indexOf(_toBytes32Set(set), bytes32(i)); - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Int256Set storage set, int256 i) internal view returns (uint256 result) { - result = indexOf(_toBytes32Set(set), bytes32(uint256(i))); - } - - /// @dev Returns the index of `value`. Returns `NOT_FOUND` if the value does not exist. - function indexOf(Uint8Set storage set, uint8 value) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := not(0) - let packed := sload(set.slot) - let m := shl(and(0xff, value), 1) - if and(packed, m) { - result := 0 - for { let p := and(packed, sub(m, 1)) } p {} { - p := xor(p, and(p, add(1, not(p)))) - result := add(result, 1) - } - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the root slot. - function _rootSlot(AddressSet storage s) private pure returns (bytes32 r) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ENUMERABLE_ADDRESS_SET_SLOT_SEED) - mstore(0x00, s.slot) - r := keccak256(0x00, 0x24) - } - } - - /// @dev Returns the root slot. - function _rootSlot(Bytes32Set storage s) private pure returns (bytes32 r) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _ENUMERABLE_WORD_SET_SLOT_SEED) - mstore(0x00, s.slot) - r := keccak256(0x00, 0x24) - } - } - - /// @dev Casts to a Bytes32Set. - function _toBytes32Set(Uint256Set storage s) private pure returns (Bytes32Set storage c) { - /// @solidity memory-safe-assembly - assembly { - c.slot := s.slot - } - } - - /// @dev Casts to a Bytes32Set. - function _toBytes32Set(Int256Set storage s) private pure returns (Bytes32Set storage c) { - /// @solidity memory-safe-assembly - assembly { - c.slot := s.slot - } - } - - /// @dev Casts to a uint256 array. - function _toUints(bytes32[] memory a) private pure returns (uint256[] memory c) { - /// @solidity memory-safe-assembly - assembly { - c := a - } - } - - /// @dev Casts to a int256 array. - function _toInts(bytes32[] memory a) private pure returns (int256[] memory c) { - /// @solidity memory-safe-assembly - assembly { - c := a - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/JSONParserLib.sol b/grouperBot/lib/solady/src/utils/g/JSONParserLib.sol deleted file mode 100644 index 6a3faed..0000000 --- a/grouperBot/lib/solady/src/utils/g/JSONParserLib.sol +++ /dev/null @@ -1,819 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev A pointer to a parsed JSON node. -struct Item { - // Do NOT modify the `_data` directly. - uint256 _data; -} - -using JSONParserLib for Item global; - -/// @notice Library for parsing JSONs. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/JSONParserLib.sol) -library JSONParserLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The input is invalid. - error ParsingFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // There are 6 types of variables in JSON (excluding undefined). - - /// @dev For denoting that an item has not been initialized. - /// A item returned from `parse` will never be of an undefined type. - /// Parsing an invalid JSON string will simply revert. - uint8 internal constant TYPE_UNDEFINED = 0; - - /// @dev Type representing an array (e.g. `[1,2,3]`). - uint8 internal constant TYPE_ARRAY = 1; - - /// @dev Type representing an object (e.g. `{"a":"A","b":"B"}`). - uint8 internal constant TYPE_OBJECT = 2; - - /// @dev Type representing a number (e.g. `-1.23e+21`). - uint8 internal constant TYPE_NUMBER = 3; - - /// @dev Type representing a string (e.g. `"hello"`). - uint8 internal constant TYPE_STRING = 4; - - /// @dev Type representing a boolean (i.e. `true` or `false`). - uint8 internal constant TYPE_BOOLEAN = 5; - - /// @dev Type representing null (i.e. `null`). - uint8 internal constant TYPE_NULL = 6; - - // Private constants for packing `_data`. - - uint256 private constant _BITPOS_STRING = 32 * 7 - 8; - uint256 private constant _BITPOS_KEY_LENGTH = 32 * 6 - 8; - uint256 private constant _BITPOS_KEY = 32 * 5 - 8; - uint256 private constant _BITPOS_VALUE_LENGTH = 32 * 4 - 8; - uint256 private constant _BITPOS_VALUE = 32 * 3 - 8; - uint256 private constant _BITPOS_CHILD = 32 * 2 - 8; - uint256 private constant _BITPOS_SIBLING_OR_PARENT = 32 * 1 - 8; - uint256 private constant _BITMASK_POINTER = 0xffffffff; - uint256 private constant _BITMASK_TYPE = 7; - uint256 private constant _KEY_INITED = 1 << 3; - uint256 private constant _VALUE_INITED = 1 << 4; - uint256 private constant _CHILDREN_INITED = 1 << 5; - uint256 private constant _PARENT_IS_ARRAY = 1 << 6; - uint256 private constant _PARENT_IS_OBJECT = 1 << 7; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* JSON PARSING OPERATION */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Parses the JSON string `s`, and returns the root. - /// Reverts if `s` is not a valid JSON as specified in RFC 8259. - /// Object items WILL simply contain all their children, inclusive of repeated keys, - /// in the same order which they appear in the JSON string. - /// - /// Note: For efficiency, this function WILL NOT make a copy of `s`. - /// The parsed tree WILL contain offsets to `s`. - /// Do NOT pass in a string that WILL be modified later on. - function parse(string memory s) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // We will use our own allocation instead. - } - bytes32 r = _query(_toInput(s), 255); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* JSON ITEM OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: - // - An item is a node in the JSON tree. - // - The value of a string item WILL be double-quoted, JSON encoded. - // - We make a distinction between `index` and `key`. - // - Items in arrays are located by `index` (uint256). - // - Items in objects are located by `key` (string). - // - Keys are always strings, double-quoted, JSON encoded. - // - // These design choices are made to balance between efficiency and ease-of-use. - - /// @dev Returns the string value of the item. - /// This is its exact string representation in the original JSON string. - /// The returned string WILL have leading and trailing whitespace trimmed. - /// All inner whitespace WILL be preserved, exactly as it is in the original JSON string. - /// If the item's type is string, the returned string WILL be double-quoted, JSON encoded. - /// - /// Note: This function lazily instantiates and caches the returned string. - /// Do NOT modify the returned string. - function value(Item memory item) internal pure returns (string memory result) { - bytes32 r = _query(_toInput(item), 0); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the index of the item in the array. - /// It the item's parent is not an array, returns 0. - function index(Item memory item) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - if and(mload(item), _PARENT_IS_ARRAY) { - result := and(_BITMASK_POINTER, shr(_BITPOS_KEY, mload(item))) - } - } - } - - /// @dev Returns the key of the item in the object. - /// It the item's parent is not an object, returns an empty string. - /// The returned string WILL be double-quoted, JSON encoded. - /// - /// Note: This function lazily instantiates and caches the returned string. - /// Do NOT modify the returned string. - function key(Item memory item) internal pure returns (string memory result) { - if (item._data & _PARENT_IS_OBJECT != 0) { - bytes32 r = _query(_toInput(item), 1); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - } - - /// @dev Returns the key of the item in the object. - /// It the item is neither an array nor object, returns an empty array. - /// - /// Note: This function lazily instantiates and caches the returned array. - /// Do NOT modify the returned array. - function children(Item memory item) internal pure returns (Item[] memory result) { - bytes32 r = _query(_toInput(item), 3); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the number of children. - /// It the item is neither an array nor object, returns zero. - function size(Item memory item) internal pure returns (uint256 result) { - bytes32 r = _query(_toInput(item), 3); - /// @solidity memory-safe-assembly - assembly { - result := mload(r) - } - } - - /// @dev Returns the item at index `i` for (array). - /// If `item` is not an array, the result's type WILL be undefined. - /// If there is no item with the index, the result's type WILL be undefined. - function at(Item memory item, uint256 i) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Free the default allocation. We'll allocate manually. - } - bytes32 r = _query(_toInput(item), 3); - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(r, 0x20), shl(5, i))) - if iszero(and(lt(i, mload(r)), eq(and(mload(item), _BITMASK_TYPE), TYPE_ARRAY))) { - result := 0x60 // Reset to the zero pointer. - } - } - } - - /// @dev Returns the item at key `k` for (object). - /// If `item` is not an object, the result's type WILL be undefined. - /// The key MUST be double-quoted, JSON encoded. This is for efficiency reasons. - /// - Correct : `item.at('"k"')`. - /// - Wrong : `item.at("k")`. - /// For duplicated keys, the last item with the key WILL be returned. - /// If there is no item with the key, the result's type WILL be undefined. - function at(Item memory item, string memory k) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Free the default allocation. We'll allocate manually. - result := 0x60 // Initialize to the zero pointer. - } - if (isObject(item)) { - bytes32 kHash = keccak256(bytes(k)); - Item[] memory r = children(item); - // We'll just do a linear search. The alternatives are very bloated. - for (uint256 i = r.length << 5; i != 0;) { - /// @solidity memory-safe-assembly - assembly { - item := mload(add(r, i)) - i := sub(i, 0x20) - } - if (keccak256(bytes(key(item))) != kHash) continue; - result = item; - break; - } - } - } - - /// @dev Returns the item's type. - function getType(Item memory item) internal pure returns (uint8 result) { - result = uint8(item._data & _BITMASK_TYPE); - } - - /// Note: All types are mutually exclusive. - - /// @dev Returns whether the item is of type undefined. - function isUndefined(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_UNDEFINED; - } - - /// @dev Returns whether the item is of type array. - function isArray(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_ARRAY; - } - - /// @dev Returns whether the item is of type object. - function isObject(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_OBJECT; - } - - /// @dev Returns whether the item is of type number. - function isNumber(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_NUMBER; - } - - /// @dev Returns whether the item is of type string. - function isString(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_STRING; - } - - /// @dev Returns whether the item is of type boolean. - function isBoolean(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_BOOLEAN; - } - - /// @dev Returns whether the item is of type null. - function isNull(Item memory item) internal pure returns (bool result) { - result = item._data & _BITMASK_TYPE == TYPE_NULL; - } - - /// @dev Returns the item's parent. - /// If the item does not have a parent, the result's type will be undefined. - function parent(Item memory item) internal pure returns (Item memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, result) // Free the default allocation. We've already allocated. - result := and(shr(_BITPOS_SIBLING_OR_PARENT, mload(item)), _BITMASK_POINTER) - if iszero(result) { result := 0x60 } // Reset to the zero pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UTILITY FUNCTIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Parses an unsigned integer from a string (in decimal, i.e. base 10). - /// Reverts if `s` is not a valid uint256 string matching the RegEx `^[0-9]+$`, - /// or if the parsed number is too big for a uint256. - function parseUint(string memory s) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(s) - let preMulOverflowThres := div(not(0), 10) - for { let i := 0 } 1 {} { - i := add(i, 1) - let digit := sub(and(mload(add(s, i)), 0xff), 48) - let mulOverflowed := gt(result, preMulOverflowThres) - let product := mul(10, result) - result := add(product, digit) - n := mul(n, iszero(or(or(mulOverflowed, lt(result, product)), gt(digit, 9)))) - if iszero(lt(i, n)) { break } - } - if iszero(n) { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Parses a signed integer from a string (in decimal, i.e. base 10). - /// Reverts if `s` is not a valid int256 string matching the RegEx `^[+-]?[0-9]+$`, - /// or if the parsed number cannot fit within `[-2**255 .. 2**255 - 1]`. - function parseInt(string memory s) internal pure returns (int256 result) { - uint256 n = bytes(s).length; - uint256 sign; - uint256 isNegative; - /// @solidity memory-safe-assembly - assembly { - if n { - let c := and(mload(add(s, 1)), 0xff) - isNegative := eq(c, 45) - if or(eq(c, 43), isNegative) { - sign := c - s := add(s, 1) - mstore(s, sub(n, 1)) - } - if iszero(or(sign, lt(sub(c, 48), 10))) { s := 0x60 } - } - } - uint256 x = parseUint(s); - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(x, add(shl(255, 1), isNegative))) { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - if sign { - mstore(s, sign) - s := sub(s, 1) - mstore(s, n) - } - result := xor(x, mul(xor(x, add(not(x), 1)), isNegative)) - } - } - - /// @dev Parses an unsigned integer from a string (in hexadecimal, i.e. base 16). - /// Reverts if `s` is not a valid uint256 hex string matching the RegEx - /// `^(0[xX])?[0-9a-fA-F]+$`, or if the parsed number cannot fit within `[0 .. 2**256 - 1]`. - function parseUintFromHex(string memory s) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(s) - // Skip two if starts with '0x' or '0X'. - let i := shl(1, and(eq(0x3078, or(shr(240, mload(add(s, 0x20))), 0x20)), gt(n, 1))) - for {} 1 {} { - i := add(i, 1) - let c := - byte( - and(0x1f, shr(and(mload(add(s, i)), 0xff), 0x3e4088843e41bac000000000000)), - 0x3010a071000000b0104040208000c05090d060e0f - ) - n := mul(n, iszero(or(iszero(c), shr(252, result)))) - result := add(shl(4, result), sub(c, 1)) - if iszero(lt(i, n)) { break } - } - if iszero(n) { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - } - } - - /// @dev Decodes a JSON encoded string. - /// The string MUST be double-quoted, JSON encoded. - /// Reverts if the string is invalid. - /// As you can see, it's pretty complex for a deceptively simple looking task. - function decodeString(string memory s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - function fail() { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - - function decodeUnicodeEscapeSequence(pIn_, end_) -> _unicode, _pOut { - _pOut := add(pIn_, 4) - let b_ := iszero(gt(_pOut, end_)) - let t_ := mload(pIn_) // Load the whole word. - for { let i_ := 0 } iszero(eq(i_, 4)) { i_ := add(i_, 1) } { - let c_ := sub(byte(i_, t_), 48) - if iszero(and(shr(c_, 0x7e0000007e03ff), b_)) { fail() } // Not hexadecimal. - c_ := sub(c_, add(mul(gt(c_, 16), 7), shl(5, gt(c_, 48)))) - _unicode := add(shl(4, _unicode), c_) - } - } - - function decodeUnicodeCodePoint(pIn_, end_) -> _unicode, _pOut { - _unicode, _pOut := decodeUnicodeEscapeSequence(pIn_, end_) - if iszero(or(lt(_unicode, 0xd800), gt(_unicode, 0xdbff))) { - let t_ := mload(_pOut) // Load the whole word. - end_ := mul(end_, eq(shr(240, t_), 0x5c75)) // Fail if not starting with '\\u'. - t_, _pOut := decodeUnicodeEscapeSequence(add(_pOut, 2), end_) - _unicode := add(0x10000, add(shl(10, and(0x3ff, _unicode)), and(0x3ff, t_))) - } - } - - function appendCodePointAsUTF8(pIn_, c_) -> _pOut { - if iszero(gt(c_, 0x7f)) { - mstore8(pIn_, c_) - _pOut := add(pIn_, 1) - leave - } - mstore8(0x1f, c_) - mstore8(0x1e, shr(6, c_)) - if iszero(gt(c_, 0x7ff)) { - mstore(pIn_, shl(240, or(0xc080, and(0x1f3f, mload(0x00))))) - _pOut := add(pIn_, 2) - leave - } - mstore8(0x1d, shr(12, c_)) - if iszero(gt(c_, 0xffff)) { - mstore(pIn_, shl(232, or(0xe08080, and(0x0f3f3f, mload(0x00))))) - _pOut := add(pIn_, 3) - leave - } - mstore8(0x1c, shr(18, c_)) - mstore(pIn_, shl(224, or(0xf0808080, and(0x073f3f3f, mload(0x00))))) - _pOut := add(pIn_, shl(2, lt(c_, 0x110000))) - } - - function chr(p_) -> _c { - _c := byte(0, mload(p_)) - } - - let n := mload(s) - let end := add(add(s, n), 0x1f) - if iszero(and(gt(n, 1), eq(0x2222, or(and(0xff00, mload(add(s, 2))), chr(end))))) { - fail() // Fail if not double-quoted. - } - let out := add(mload(0x40), 0x20) - for { let curr := add(s, 0x21) } iszero(eq(curr, end)) {} { - let c := chr(curr) - curr := add(curr, 1) - // Not '\\'. - if iszero(eq(c, 92)) { - // Not '"'. - if iszero(eq(c, 34)) { - mstore8(out, c) - out := add(out, 1) - continue - } - curr := end - } - if iszero(eq(curr, end)) { - let escape := chr(curr) - curr := add(curr, 1) - // '"', '/', '\\'. - if and(shr(escape, 0x100000000000800400000000), 1) { - mstore8(out, escape) - out := add(out, 1) - continue - } - // 'u'. - if eq(escape, 117) { - escape, curr := decodeUnicodeCodePoint(curr, end) - out := appendCodePointAsUTF8(out, escape) - continue - } - // `{'b':'\b', 'f':'\f', 'n':'\n', 'r':'\r', 't':'\t'}`. - escape := byte(sub(escape, 85), 0x080000000c000000000000000a0000000d0009) - if escape { - mstore8(out, escape) - out := add(out, 1) - continue - } - } - fail() - break - } - mstore(out, 0) // Zeroize the last slot. - result := mload(0x40) - mstore(result, sub(out, add(result, 0x20))) // Store the length. - mstore(0x40, add(out, 0x20)) // Allocate the memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Performs a query on the input with the given mode. - function _query(bytes32 input, uint256 mode) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - function fail() { - mstore(0x00, 0x10182796) // `ParsingFailed()`. - revert(0x1c, 0x04) - } - - function chr(p_) -> _c { - _c := byte(0, mload(p_)) - } - - function skipWhitespace(pIn_, end_) -> _pOut { - for { _pOut := pIn_ } 1 { _pOut := add(_pOut, 1) } { - if iszero(and(shr(chr(_pOut), 0x100002600), 1)) { leave } // Not in ' \n\r\t'. - } - } - - function setP(packed_, bitpos_, p_) -> _packed { - // Perform an out-of-gas revert if `p_` exceeds `_BITMASK_POINTER`. - returndatacopy(returndatasize(), returndatasize(), gt(p_, _BITMASK_POINTER)) - _packed := or(and(not(shl(bitpos_, _BITMASK_POINTER)), packed_), shl(bitpos_, p_)) - } - - function getP(packed_, bitpos_) -> _p { - _p := and(_BITMASK_POINTER, shr(bitpos_, packed_)) - } - - function mallocItem(s_, packed_, pStart_, pCurr_, type_) -> _item { - _item := mload(0x40) - // forgefmt: disable-next-item - packed_ := setP(setP(packed_, _BITPOS_VALUE, sub(pStart_, add(s_, 0x20))), - _BITPOS_VALUE_LENGTH, sub(pCurr_, pStart_)) - mstore(_item, or(packed_, type_)) - mstore(0x40, add(_item, 0x20)) // Allocate memory. - } - - function parseValue(s_, sibling_, pIn_, end_) -> _item, _pOut { - let packed_ := setP(mload(0x00), _BITPOS_SIBLING_OR_PARENT, sibling_) - _pOut := skipWhitespace(pIn_, end_) - if iszero(lt(_pOut, end_)) { leave } - for { let c_ := chr(_pOut) } 1 {} { - // If starts with '"'. - if eq(c_, 34) { - let pStart_ := _pOut - _pOut := parseStringSub(s_, packed_, _pOut, end_) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_STRING) - break - } - // If starts with '['. - if eq(c_, 91) { - _item, _pOut := parseArray(s_, packed_, _pOut, end_) - break - } - // If starts with '{'. - if eq(c_, 123) { - _item, _pOut := parseObject(s_, packed_, _pOut, end_) - break - } - // If starts with any in '0123456789-'. - if and(shr(c_, shl(45, 0x1ff9)), 1) { - _item, _pOut := parseNumber(s_, packed_, _pOut, end_) - break - } - if iszero(gt(add(_pOut, 4), end_)) { - let pStart_ := _pOut - let w_ := shr(224, mload(_pOut)) - // 'true' in hex format. - if eq(w_, 0x74727565) { - _pOut := add(_pOut, 4) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_BOOLEAN) - break - } - // 'null' in hex format. - if eq(w_, 0x6e756c6c) { - _pOut := add(_pOut, 4) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_NULL) - break - } - } - if iszero(gt(add(_pOut, 5), end_)) { - let pStart_ := _pOut - let w_ := shr(216, mload(_pOut)) - // 'false' in hex format. - if eq(w_, 0x66616c7365) { - _pOut := add(_pOut, 5) - _item := mallocItem(s_, packed_, pStart_, _pOut, TYPE_BOOLEAN) - break - } - } - fail() - break - } - _pOut := skipWhitespace(_pOut, end_) - } - - function parseArray(s_, packed_, pIn_, end_) -> _item, _pOut { - let j_ := 0 - for { _pOut := add(pIn_, 1) } 1 { _pOut := add(_pOut, 1) } { - if iszero(lt(_pOut, end_)) { fail() } - if iszero(_item) { - _pOut := skipWhitespace(_pOut, end_) - if eq(chr(_pOut), 93) { break } // ']'. - } - _item, _pOut := parseValue(s_, _item, _pOut, end_) - if _item { - // forgefmt: disable-next-item - mstore(_item, setP(or(_PARENT_IS_ARRAY, mload(_item)), - _BITPOS_KEY, j_)) - j_ := add(j_, 1) - let c_ := chr(_pOut) - if eq(c_, 93) { break } // ']'. - if eq(c_, 44) { continue } // ','. - } - _pOut := end_ - } - _pOut := add(_pOut, 1) - packed_ := setP(packed_, _BITPOS_CHILD, _item) - _item := mallocItem(s_, packed_, pIn_, _pOut, TYPE_ARRAY) - } - - function parseObject(s_, packed_, pIn_, end_) -> _item, _pOut { - for { _pOut := add(pIn_, 1) } 1 { _pOut := add(_pOut, 1) } { - if iszero(lt(_pOut, end_)) { fail() } - if iszero(_item) { - _pOut := skipWhitespace(_pOut, end_) - if eq(chr(_pOut), 125) { break } // '}'. - } - _pOut := skipWhitespace(_pOut, end_) - let pKeyStart_ := _pOut - let pKeyEnd_ := parseStringSub(s_, _item, _pOut, end_) - _pOut := skipWhitespace(pKeyEnd_, end_) - // If ':'. - if eq(chr(_pOut), 58) { - _item, _pOut := parseValue(s_, _item, add(_pOut, 1), end_) - if _item { - // forgefmt: disable-next-item - mstore(_item, setP(setP(or(_PARENT_IS_OBJECT, mload(_item)), - _BITPOS_KEY_LENGTH, sub(pKeyEnd_, pKeyStart_)), - _BITPOS_KEY, sub(pKeyStart_, add(s_, 0x20)))) - let c_ := chr(_pOut) - if eq(c_, 125) { break } // '}'. - if eq(c_, 44) { continue } // ','. - } - } - _pOut := end_ - } - _pOut := add(_pOut, 1) - packed_ := setP(packed_, _BITPOS_CHILD, _item) - _item := mallocItem(s_, packed_, pIn_, _pOut, TYPE_OBJECT) - } - - function checkStringU(p_, o_) { - // If not in '0123456789abcdefABCDEF', revert. - if iszero(and(shr(sub(chr(add(p_, o_)), 48), 0x7e0000007e03ff), 1)) { fail() } - if iszero(eq(o_, 5)) { checkStringU(p_, add(o_, 1)) } - } - - function parseStringSub(s_, packed_, pIn_, end_) -> _pOut { - if iszero(lt(pIn_, end_)) { fail() } - for { _pOut := add(pIn_, 1) } 1 {} { - let c_ := chr(_pOut) - if eq(c_, 34) { break } // '"'. - // Not '\'. - if iszero(eq(c_, 92)) { - _pOut := add(_pOut, 1) - continue - } - c_ := chr(add(_pOut, 1)) - // '"', '\', '//', 'b', 'f', 'n', 'r', 't'. - if and(shr(sub(c_, 34), 0x510110400000000002001), 1) { - _pOut := add(_pOut, 2) - continue - } - // 'u'. - if eq(c_, 117) { - checkStringU(_pOut, 2) - _pOut := add(_pOut, 6) - continue - } - _pOut := end_ - break - } - if iszero(lt(_pOut, end_)) { fail() } - _pOut := add(_pOut, 1) - } - - function skip0To9s(pIn_, end_, atLeastOne_) -> _pOut { - for { _pOut := pIn_ } 1 { _pOut := add(_pOut, 1) } { - if iszero(lt(sub(chr(_pOut), 48), 10)) { break } // Not '0'..'9'. - } - if and(atLeastOne_, eq(pIn_, _pOut)) { fail() } - } - - function parseNumber(s_, packed_, pIn_, end_) -> _item, _pOut { - _pOut := pIn_ - if eq(chr(_pOut), 45) { _pOut := add(_pOut, 1) } // '-'. - if iszero(lt(sub(chr(_pOut), 48), 10)) { fail() } // Not '0'..'9'. - let c_ := chr(_pOut) - _pOut := add(_pOut, 1) - if iszero(eq(c_, 48)) { _pOut := skip0To9s(_pOut, end_, 0) } // Not '0'. - if eq(chr(_pOut), 46) { _pOut := skip0To9s(add(_pOut, 1), end_, 1) } // '.'. - let t_ := mload(_pOut) - // 'E', 'e'. - if eq(or(0x20, byte(0, t_)), 101) { - // forgefmt: disable-next-item - _pOut := skip0To9s(add(byte(sub(byte(1, t_), 14), 0x010001), // '+', '-'. - add(_pOut, 1)), end_, 1) - } - _item := mallocItem(s_, packed_, pIn_, _pOut, TYPE_NUMBER) - } - - function copyStr(s_, offset_, len_) -> _sCopy { - _sCopy := mload(0x40) - s_ := add(s_, offset_) - let w_ := not(0x1f) - for { let i_ := and(add(len_, 0x1f), w_) } 1 {} { - mstore(add(_sCopy, i_), mload(add(s_, i_))) - i_ := add(i_, w_) // `sub(i_, 0x20)`. - if iszero(i_) { break } - } - mstore(_sCopy, len_) // Copy the length. - mstore(add(add(_sCopy, 0x20), len_), 0) // Zeroize the last slot. - mstore(0x40, add(add(_sCopy, 0x40), len_)) // Allocate memory. - } - - function value(item_) -> _value { - let packed_ := mload(item_) - _value := getP(packed_, _BITPOS_VALUE) // The offset in the string. - if iszero(and(_VALUE_INITED, packed_)) { - let s_ := getP(packed_, _BITPOS_STRING) - _value := copyStr(s_, _value, getP(packed_, _BITPOS_VALUE_LENGTH)) - packed_ := setP(packed_, _BITPOS_VALUE, _value) - mstore(s_, or(_VALUE_INITED, packed_)) - } - } - - function children(item_) -> _arr { - _arr := 0x60 // Initialize to the zero pointer. - let packed_ := mload(item_) - for {} iszero(gt(and(_BITMASK_TYPE, packed_), TYPE_OBJECT)) {} { - if or(iszero(packed_), iszero(item_)) { break } - if and(packed_, _CHILDREN_INITED) { - _arr := getP(packed_, _BITPOS_CHILD) - break - } - _arr := mload(0x40) - let o_ := add(_arr, 0x20) - for { let h_ := getP(packed_, _BITPOS_CHILD) } h_ {} { - mstore(o_, h_) - let q_ := mload(h_) - let y_ := getP(q_, _BITPOS_SIBLING_OR_PARENT) - mstore(h_, setP(q_, _BITPOS_SIBLING_OR_PARENT, item_)) - h_ := y_ - o_ := add(o_, 0x20) - } - let w_ := not(0x1f) - let n_ := add(w_, sub(o_, _arr)) - mstore(_arr, shr(5, n_)) - mstore(0x40, o_) // Allocate memory. - packed_ := setP(packed_, _BITPOS_CHILD, _arr) - mstore(item_, or(_CHILDREN_INITED, packed_)) - // Reverse the array. - if iszero(lt(n_, 0x40)) { - let lo_ := add(_arr, 0x20) - let hi_ := add(_arr, n_) - for {} 1 {} { - let temp_ := mload(lo_) - mstore(lo_, mload(hi_)) - mstore(hi_, temp_) - hi_ := add(hi_, w_) - lo_ := add(lo_, 0x20) - if iszero(lt(lo_, hi_)) { break } - } - } - break - } - } - - function getStr(item_, bitpos_, bitposLength_, bitmaskInited_) -> _result { - _result := 0x60 // Initialize to the zero pointer. - let packed_ := mload(item_) - if or(iszero(item_), iszero(packed_)) { leave } - _result := getP(packed_, bitpos_) - if iszero(and(bitmaskInited_, packed_)) { - let s_ := getP(packed_, _BITPOS_STRING) - _result := copyStr(s_, _result, getP(packed_, bitposLength_)) - mstore(item_, or(bitmaskInited_, setP(packed_, bitpos_, _result))) - } - } - - switch mode - // Get value. - case 0 { result := getStr(input, _BITPOS_VALUE, _BITPOS_VALUE_LENGTH, _VALUE_INITED) } - // Get key. - case 1 { result := getStr(input, _BITPOS_KEY, _BITPOS_KEY_LENGTH, _KEY_INITED) } - // Get children. - case 3 { result := children(input) } - // Parse. - default { - let p := add(input, 0x20) - let e := add(p, mload(input)) - if iszero(eq(p, e)) { - let c := chr(e) - mstore8(e, 34) // Place a '"' at the end to speed up parsing. - // The `34 << 248` makes `mallocItem` preserve '"' at the end. - mstore(0x00, setP(shl(248, 34), _BITPOS_STRING, input)) - result, p := parseValue(input, 0, p, e) - mstore8(e, c) // Restore the original char at the end. - } - if or(lt(p, e), iszero(result)) { fail() } - } - } - } - - /// @dev Casts the input to a bytes32. - function _toInput(string memory input) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := input - } - } - - /// @dev Casts the input to a bytes32. - function _toInput(Item memory input) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := input - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibBitmap.sol b/grouperBot/lib/solady/src/utils/g/LibBitmap.sol deleted file mode 100644 index 91af771..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibBitmap.sol +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev A bitmap in storage. -struct Bitmap { - mapping(uint256 => uint256) map; -} - -using LibBitmap for Bitmap global; - -import {LibBit} from "../LibBit.sol"; - -/// @notice Library for storage of packed unsigned booleans. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibBitmap.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol) -/// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol) -library LibBitmap { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when a bitmap scan does not find a result. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the boolean value of the bit at `index` in `bitmap`. - function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) { - // It is better to set `isSet` to either 0 or 1, than zero vs non-zero. - // Both cost the same amount of gas, but the former allows the returned value - // to be reused without cleaning the upper bits. - uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1; - /// @solidity memory-safe-assembly - assembly { - isSet := b - } - } - - /// @dev Updates the bit at `index` in `bitmap` to true. - function set(Bitmap storage bitmap, uint256 index) internal { - bitmap.map[index >> 8] |= (1 << (index & 0xff)); - } - - /// @dev Updates the bit at `index` in `bitmap` to false. - function unset(Bitmap storage bitmap, uint256 index) internal { - bitmap.map[index >> 8] &= ~(1 << (index & 0xff)); - } - - /// @dev Flips the bit at `index` in `bitmap`. - /// Returns the boolean result of the flipped bit. - function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, index)) - let storageSlot := keccak256(0x00, 0x40) - let shift := and(index, 0xff) - let storageValue := xor(sload(storageSlot), shl(shift, 1)) - // It makes sense to return the `newIsSet`, - // as it allow us to skip an additional warm `sload`, - // and it costs minimal gas (about 15), - // which may be optimized away if the returned value is unused. - newIsSet := and(1, shr(shift, storageValue)) - sstore(storageSlot, storageValue) - } - } - - /// @dev Updates the bit at `index` in `bitmap` to `shouldSet`. - function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, index)) - let storageSlot := keccak256(0x00, 0x40) - let storageValue := sload(storageSlot) - let shift := and(index, 0xff) - sstore( - storageSlot, - // Unsets the bit at `shift` via `and`, then sets its new value via `or`. - or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet)))) - ) - } - } - - /// @dev Consecutively sets `amount` of bits starting from the bit at `start`. - function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - let max := not(0) - let shift := and(start, 0xff) - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, start)) - if iszero(lt(add(shift, amount), 257)) { - let storageSlot := keccak256(0x00, 0x40) - sstore(storageSlot, or(sload(storageSlot), shl(shift, max))) - let bucket := add(mload(0x00), 1) - let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) - amount := and(add(amount, shift), 0xff) - shift := 0 - for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { - mstore(0x00, bucket) - sstore(keccak256(0x00, 0x40), max) - } - mstore(0x00, bucket) - } - let storageSlot := keccak256(0x00, 0x40) - sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max)))) - } - } - - /// @dev Consecutively unsets `amount` of bits starting from the bit at `start`. - function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { - /// @solidity memory-safe-assembly - assembly { - let shift := and(start, 0xff) - mstore(0x20, bitmap.slot) - mstore(0x00, shr(8, start)) - if iszero(lt(add(shift, amount), 257)) { - let storageSlot := keccak256(0x00, 0x40) - sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0))))) - let bucket := add(mload(0x00), 1) - let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) - amount := and(add(amount, shift), 0xff) - shift := 0 - for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { - mstore(0x00, bucket) - sstore(keccak256(0x00, 0x40), 0) - } - mstore(0x00, bucket) - } - let storageSlot := keccak256(0x00, 0x40) - sstore( - storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0))))) - ) - } - } - - /// @dev Returns number of set bits within a range by - /// scanning `amount` of bits starting from the bit at `start`. - function popCount(Bitmap storage bitmap, uint256 start, uint256 amount) - internal - view - returns (uint256 count) - { - unchecked { - uint256 bucket = start >> 8; - uint256 shift = start & 0xff; - if (!(amount + shift < 257)) { - count = LibBit.popCount(bitmap.map[bucket] >> shift); - uint256 bucketEnd = bucket + ((amount + shift) >> 8); - amount = (amount + shift) & 0xff; - shift = 0; - for (++bucket; bucket != bucketEnd; ++bucket) { - count += LibBit.popCount(bitmap.map[bucket]); - } - } - count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount)); - } - } - - /// @dev Returns the index of the most significant set bit in `[0..upTo]`. - /// If no set bit is found, returns `NOT_FOUND`. - function findLastSet(Bitmap storage bitmap, uint256 upTo) - internal - view - returns (uint256 setBitIndex) - { - setBitIndex = NOT_FOUND; - uint256 bucket = upTo >> 8; - uint256 bits; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, bucket) - mstore(0x20, bitmap.slot) - let offset := and(0xff, not(upTo)) // `256 - (255 & upTo) - 1`. - bits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40)))) - if iszero(or(bits, iszero(bucket))) { - for {} 1 {} { - bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`. - mstore(0x00, bucket) - bits := sload(keccak256(0x00, 0x40)) - if or(bits, iszero(bucket)) { break } - } - } - } - if (bits != 0) { - setBitIndex = (bucket << 8) | LibBit.fls(bits); - /// @solidity memory-safe-assembly - assembly { - setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, upTo))) - } - } - } - - /// @dev Returns the index of the least significant unset bit in `[begin..upTo]`. - /// If no unset bit is found, returns `NOT_FOUND`. - function findFirstUnset(Bitmap storage bitmap, uint256 begin, uint256 upTo) - internal - view - returns (uint256 unsetBitIndex) - { - unsetBitIndex = NOT_FOUND; - uint256 bucket = begin >> 8; - uint256 negBits; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, bucket) - mstore(0x20, bitmap.slot) - let offset := and(0xff, begin) - negBits := shl(offset, shr(offset, not(sload(keccak256(0x00, 0x40))))) - if iszero(negBits) { - let lastBucket := shr(8, upTo) - for {} 1 {} { - bucket := add(bucket, 1) - mstore(0x00, bucket) - negBits := not(sload(keccak256(0x00, 0x40))) - if or(negBits, gt(bucket, lastBucket)) { break } - } - if gt(bucket, lastBucket) { - negBits := shl(and(0xff, not(upTo)), shr(and(0xff, not(upTo)), negBits)) - } - } - } - if (negBits != 0) { - uint256 r = (bucket << 8) | LibBit.ffs(negBits); - /// @solidity memory-safe-assembly - assembly { - unsetBitIndex := or(r, sub(0, or(gt(r, upTo), lt(r, begin)))) - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibBytes.sol b/grouperBot/lib/solady/src/utils/g/LibBytes.sol deleted file mode 100644 index a536ad4..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibBytes.sol +++ /dev/null @@ -1,892 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev Goated bytes storage struct that totally MOGs, no cap, fr. -/// Uses less gas and bytecode than Solidity's native bytes storage. It's meta af. -/// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight. -struct BytesStorage { - bytes32 _spacer; -} - -using LibBytes for BytesStorage global; - -/// @notice Library for byte related operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibBytes.sol) -library LibBytes { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when the `search` is not found in the bytes. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTE STORAGE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the value of the bytes storage `$` to `s`. - function set(BytesStorage storage $, bytes memory s) internal { - /// @solidity memory-safe-assembly - assembly { - let n := mload(s) - let packed := or(0xff, shl(8, n)) - for { let i := 0 } 1 {} { - if iszero(gt(n, 0xfe)) { - i := 0x1f - packed := or(n, shl(8, mload(add(s, i)))) - if iszero(gt(n, i)) { break } - } - let o := add(s, 0x20) - mstore(0x00, $.slot) - for { let p := keccak256(0x00, 0x20) } 1 {} { - sstore(add(p, shr(5, i)), mload(add(o, i))) - i := add(i, 0x20) - if iszero(lt(i, n)) { break } - } - break - } - sstore($.slot, packed) - } - } - - /// @dev Sets the value of the bytes storage `$` to `s`. - function setCalldata(BytesStorage storage $, bytes calldata s) internal { - /// @solidity memory-safe-assembly - assembly { - let packed := or(0xff, shl(8, s.length)) - for { let i := 0 } 1 {} { - if iszero(gt(s.length, 0xfe)) { - i := 0x1f - packed := or(s.length, shl(8, shr(8, calldataload(s.offset)))) - if iszero(gt(s.length, i)) { break } - } - mstore(0x00, $.slot) - for { let p := keccak256(0x00, 0x20) } 1 {} { - sstore(add(p, shr(5, i)), calldataload(add(s.offset, i))) - i := add(i, 0x20) - if iszero(lt(i, s.length)) { break } - } - break - } - sstore($.slot, packed) - } - } - - /// @dev Sets the value of the bytes storage `$` to the empty bytes. - function clear(BytesStorage storage $) internal { - delete $._spacer; - } - - /// @dev Returns whether the value stored is `$` is the empty bytes "". - function isEmpty(BytesStorage storage $) internal view returns (bool) { - return uint256($._spacer) & 0xff == uint256(0); - } - - /// @dev Returns the length of the value stored in `$`. - function length(BytesStorage storage $) internal view returns (uint256 result) { - result = uint256($._spacer); - /// @solidity memory-safe-assembly - assembly { - let n := and(0xff, result) - result := or(mul(shr(8, result), eq(0xff, n)), mul(n, iszero(eq(0xff, n)))) - } - } - - /// @dev Returns the value stored in `$`. - function get(BytesStorage storage $) internal view returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let o := add(result, 0x20) - let packed := sload($.slot) - let n := shr(8, packed) - for { let i := 0 } 1 {} { - if iszero(eq(or(packed, 0xff), packed)) { - mstore(o, packed) - n := and(0xff, packed) - i := 0x1f - if iszero(gt(n, i)) { break } - } - mstore(0x00, $.slot) - for { let p := keccak256(0x00, 0x20) } 1 {} { - mstore(add(o, i), sload(add(p, shr(5, i)))) - i := add(i, 0x20) - if iszero(lt(i, n)) { break } - } - break - } - mstore(result, n) // Store the length of the memory. - mstore(add(o, n), 0) // Zeroize the slot after the bytes. - mstore(0x40, add(add(o, n), 0x20)) // Allocate memory. - } - } - - /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0. - function uint8At(BytesStorage storage $, uint256 i) internal view returns (uint8 result) { - /// @solidity memory-safe-assembly - assembly { - for { let packed := sload($.slot) } 1 {} { - if iszero(eq(or(packed, 0xff), packed)) { - if iszero(gt(i, 0x1e)) { - result := byte(i, packed) - break - } - if iszero(gt(i, and(0xff, packed))) { - mstore(0x00, $.slot) - let j := sub(i, 0x1f) - result := byte(and(j, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, j)))) - } - break - } - if iszero(gt(i, shr(8, packed))) { - mstore(0x00, $.slot) - result := byte(and(i, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, i)))) - } - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTES OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`. - function replace(bytes memory subject, bytes memory needle, bytes memory replacement) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let needleLen := mload(needle) - let replacementLen := mload(replacement) - let d := sub(result, subject) // Memory difference. - let i := add(subject, 0x20) // Subject bytes pointer. - mstore(0x00, add(i, mload(subject))) // End of subject. - if iszero(gt(needleLen, mload(subject))) { - let subjectSearchEnd := add(sub(mload(0x00), needleLen), 1) - let h := 0 // The hash of `needle`. - if iszero(lt(needleLen, 0x20)) { h := keccak256(add(needle, 0x20), needleLen) } - let s := mload(add(needle, 0x20)) - for { let m := shl(3, sub(0x20, and(needleLen, 0x1f))) } 1 {} { - let t := mload(i) - // Whether the first `needleLen % 32` bytes of `subject` and `needle` matches. - if iszero(shr(m, xor(t, s))) { - if h { - if iszero(eq(keccak256(i, needleLen), h)) { - mstore(add(i, d), t) - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - // Copy the `replacement` one word at a time. - for { let j := 0 } 1 {} { - mstore(add(add(i, d), j), mload(add(add(replacement, 0x20), j))) - j := add(j, 0x20) - if iszero(lt(j, replacementLen)) { break } - } - d := sub(add(d, replacementLen), needleLen) - if needleLen { - i := add(i, needleLen) - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - mstore(add(i, d), t) - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - } - } - let end := mload(0x00) - let n := add(sub(d, add(result, 0x20)), end) - // Copy the rest of the bytes one word at a time. - for {} lt(i, end) { i := add(i, 0x20) } { mstore(add(i, d), mload(i)) } - let o := add(i, d) - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate memory. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(bytes memory subject, bytes memory needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) // Initialize to `NOT_FOUND`. - for { let subjectLen := mload(subject) } 1 {} { - if iszero(mload(needle)) { - result := from - if iszero(gt(from, subjectLen)) { break } - result := subjectLen - break - } - let needleLen := mload(needle) - let subjectStart := add(subject, 0x20) - - subject := add(subjectStart, from) - let end := add(sub(add(subjectStart, subjectLen), needleLen), 1) - let m := shl(3, sub(0x20, and(needleLen, 0x1f))) - let s := mload(add(needle, 0x20)) - - if iszero(and(lt(subject, end), lt(from, subjectLen))) { break } - - if iszero(lt(needleLen, 0x20)) { - for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} { - if iszero(shr(m, xor(mload(subject), s))) { - if eq(keccak256(subject, needleLen), h) { - result := sub(subject, subjectStart) - break - } - } - subject := add(subject, 1) - if iszero(lt(subject, end)) { break } - } - break - } - for {} 1 {} { - if iszero(shr(m, xor(mload(subject), s))) { - result := sub(subject, subjectStart) - break - } - subject := add(subject, 1) - if iszero(lt(subject, end)) { break } - } - break - } - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right, starting from `from`. Optimized for byte needles. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOfByte(bytes memory subject, bytes1 needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := not(0) // Initialize to `NOT_FOUND`. - if gt(mload(subject), from) { - let start := add(subject, 0x20) - let end := add(start, mload(subject)) - let m := div(not(0), 255) // `0x0101 ... `. - let h := mul(byte(0, needle), m) // Replicating needle mask. - m := not(shl(7, m)) // `0x7f7f ... `. - for { let i := add(start, from) } 1 {} { - let c := xor(mload(i), h) // Load 32-byte chunk and xor with mask. - c := not(or(or(add(and(c, m), m), c), m)) // Each needle byte will be `0x80`. - if c { - c := and(not(shr(shl(3, sub(end, i)), not(0))), c) // Truncate bytes past the end. - if c { - let r := shl(7, lt(0x8421084210842108cc6318c6db6d54be, c)) // Save bytecode. - r := or(shl(6, lt(0xffffffffffffffff, shr(r, c))), r) - // forgefmt: disable-next-item - result := add(sub(i, start), shr(3, xor(byte(and(0x1f, shr(byte(24, - mul(0x02040810204081, shr(r, c))), 0x8421084210842108cc6318c6db6d54be)), - 0xc0c8c8d0c8e8d0d8c8e8e0e8d0d8e0f0c8d0e8d0e0e0d8f0d0d0e0d8f8f8f8f8), r))) - break - } - } - i := add(i, 0x20) - if iszero(lt(i, end)) { break } - } - } - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right. Optimized for byte needles. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOfByte(bytes memory subject, bytes1 needle) - internal - pure - returns (uint256 result) - { - return indexOfByte(subject, needle, 0); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(bytes memory subject, bytes memory needle) internal pure returns (uint256) { - return indexOf(subject, needle, 0); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(bytes memory subject, bytes memory needle, uint256 from) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - result := not(0) // Initialize to `NOT_FOUND`. - let needleLen := mload(needle) - if gt(needleLen, mload(subject)) { break } - let w := result - - let fromMax := sub(mload(subject), needleLen) - if iszero(gt(fromMax, from)) { from := fromMax } - - let end := add(add(subject, 0x20), w) - subject := add(add(subject, 0x20), from) - if iszero(gt(subject, end)) { break } - // As this function is not too often used, - // we shall simply use keccak256 for smaller bytecode size. - for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} { - if eq(keccak256(subject, needleLen), h) { - result := sub(subject, add(end, 1)) - break - } - subject := add(subject, w) // `sub(subject, 1)`. - if iszero(gt(subject, end)) { break } - } - break - } - } - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(bytes memory subject, bytes memory needle) - internal - pure - returns (uint256) - { - return lastIndexOf(subject, needle, type(uint256).max); - } - - /// @dev Returns true if `needle` is found in `subject`, false otherwise. - function contains(bytes memory subject, bytes memory needle) internal pure returns (bool) { - return indexOf(subject, needle) != NOT_FOUND; - } - - /// @dev Returns whether `subject` starts with `needle`. - function startsWith(bytes memory subject, bytes memory needle) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(needle) - // Just using keccak256 directly is actually cheaper. - let t := eq(keccak256(add(subject, 0x20), n), keccak256(add(needle, 0x20), n)) - result := lt(gt(n, mload(subject)), t) - } - } - - /// @dev Returns whether `subject` ends with `needle`. - function endsWith(bytes memory subject, bytes memory needle) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(needle) - let notInRange := gt(n, mload(subject)) - // `subject + 0x20 + max(subject.length - needle.length, 0)`. - let t := add(add(subject, 0x20), mul(iszero(notInRange), sub(mload(subject), n))) - // Just using keccak256 directly is actually cheaper. - result := gt(eq(keccak256(t, n), keccak256(add(needle, 0x20), n)), notInRange) - } - } - - /// @dev Returns `subject` repeated `times`. - function repeat(bytes memory subject, uint256 times) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - let l := mload(subject) // Subject length. - if iszero(or(iszero(times), iszero(l))) { - result := mload(0x40) - subject := add(subject, 0x20) - let o := add(result, 0x20) - for {} 1 {} { - // Copy the `subject` one word at a time. - for { let j := 0 } 1 {} { - mstore(add(o, j), mload(add(subject, j))) - j := add(j, 0x20) - if iszero(lt(j, l)) { break } - } - o := add(o, l) - times := sub(times, 1) - if iszero(times) { break } - } - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate memory. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - } - } - } - - /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function slice(bytes memory subject, uint256 start, uint256 end) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - let l := mload(subject) // Subject length. - if iszero(gt(l, end)) { end := l } - if iszero(gt(l, start)) { start := l } - if lt(start, end) { - result := mload(0x40) - let n := sub(end, start) - let i := add(subject, start) - let w := not(0x1f) - // Copy the `subject` one word at a time, backwards. - for { let j := and(add(n, 0x1f), w) } 1 {} { - mstore(add(result, j), mload(add(i, j))) - j := add(j, w) // `sub(j, 0x20)`. - if iszero(j) { break } - } - let o := add(add(result, 0x20), n) - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate memory. - mstore(result, n) // Store the length. - } - } - } - - /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes. - /// `start` is a byte offset. - function slice(bytes memory subject, uint256 start) - internal - pure - returns (bytes memory result) - { - result = slice(subject, start, type(uint256).max); - } - - /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. Faster than Solidity's native slicing. - function sliceCalldata(bytes calldata subject, uint256 start, uint256 end) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - end := xor(end, mul(xor(end, subject.length), lt(subject.length, end))) - start := xor(start, mul(xor(start, subject.length), lt(subject.length, start))) - result.offset := add(subject.offset, start) - result.length := mul(lt(start, end), sub(end, start)) - } - } - - /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes. - /// `start` is a byte offset. Faster than Solidity's native slicing. - function sliceCalldata(bytes calldata subject, uint256 start) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - start := xor(start, mul(xor(start, subject.length), lt(subject.length, start))) - result.offset := add(subject.offset, start) - result.length := mul(lt(start, subject.length), sub(subject.length, start)) - } - } - - /// @dev Reduces the size of `subject` to `n`. - /// If `n` is greater than the size of `subject`, this will be a no-op. - function truncate(bytes memory subject, uint256 n) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := subject - mstore(mul(lt(n, mload(result)), result), n) - } - } - - /// @dev Returns a copy of `subject`, with the length reduced to `n`. - /// If `n` is greater than the size of `subject`, this will be a no-op. - function truncatedCalldata(bytes calldata subject, uint256 n) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - result.offset := subject.offset - result.length := xor(n, mul(xor(n, subject.length), lt(subject.length, n))) - } - } - - /// @dev Returns all the indices of `needle` in `subject`. - /// The indices are byte offsets. - function indicesOf(bytes memory subject, bytes memory needle) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - let searchLen := mload(needle) - if iszero(gt(searchLen, mload(subject))) { - result := mload(0x40) - let i := add(subject, 0x20) - let o := add(result, 0x20) - let subjectSearchEnd := add(sub(add(i, mload(subject)), searchLen), 1) - let h := 0 // The hash of `needle`. - if iszero(lt(searchLen, 0x20)) { h := keccak256(add(needle, 0x20), searchLen) } - let s := mload(add(needle, 0x20)) - for { let m := shl(3, sub(0x20, and(searchLen, 0x1f))) } 1 {} { - let t := mload(i) - // Whether the first `searchLen % 32` bytes of `subject` and `needle` matches. - if iszero(shr(m, xor(t, s))) { - if h { - if iszero(eq(keccak256(i, searchLen), h)) { - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - mstore(o, sub(i, add(subject, 0x20))) // Append to `result`. - o := add(o, 0x20) - i := add(i, searchLen) // Advance `i` by `searchLen`. - if searchLen { - if iszero(lt(i, subjectSearchEnd)) { break } - continue - } - } - i := add(i, 1) - if iszero(lt(i, subjectSearchEnd)) { break } - } - mstore(result, shr(5, sub(o, add(result, 0x20)))) // Store the length of `result`. - // Allocate memory for result. - // We allocate one more word, so this array can be recycled for {split}. - mstore(0x40, add(o, 0x20)) - } - } - } - - /// @dev Returns an arrays of bytess based on the `delimiter` inside of the `subject` bytes. - function split(bytes memory subject, bytes memory delimiter) - internal - pure - returns (bytes[] memory result) - { - uint256[] memory indices = indicesOf(subject, delimiter); - /// @solidity memory-safe-assembly - assembly { - let w := not(0x1f) - let indexPtr := add(indices, 0x20) - let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1))) - mstore(add(indicesEnd, w), mload(subject)) - mstore(indices, add(mload(indices), 1)) - for { let prevIndex := 0 } 1 {} { - let index := mload(indexPtr) - mstore(indexPtr, 0x60) - if iszero(eq(index, prevIndex)) { - let element := mload(0x40) - let l := sub(index, prevIndex) - mstore(element, l) // Store the length of the element. - // Copy the `subject` one word at a time, backwards. - for { let o := and(add(l, 0x1f), w) } 1 {} { - mstore(add(element, o), mload(add(add(subject, prevIndex), o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - mstore(add(add(element, 0x20), l), 0) // Zeroize the slot after the bytes. - // Allocate memory for the length and the bytes, rounded up to a multiple of 32. - mstore(0x40, add(element, and(add(l, 0x3f), w))) - mstore(indexPtr, element) // Store the `element` into the array. - } - prevIndex := add(index, mload(delimiter)) - indexPtr := add(indexPtr, 0x20) - if iszero(lt(indexPtr, indicesEnd)) { break } - } - result := indices - if iszero(mload(delimiter)) { - result := add(indices, 0x20) - mstore(result, sub(mload(indices), 2)) - } - } - } - - /// @dev Returns a concatenated bytes of `a` and `b`. - /// Cheaper than `bytes.concat()` and does not de-align the free memory pointer. - function concat(bytes memory a, bytes memory b) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let w := not(0x1f) - let aLen := mload(a) - // Copy `a` one word at a time, backwards. - for { let o := and(add(aLen, 0x20), w) } 1 {} { - mstore(add(result, o), mload(add(a, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - let bLen := mload(b) - let output := add(result, aLen) - // Copy `b` one word at a time, backwards. - for { let o := and(add(bLen, 0x20), w) } 1 {} { - mstore(add(output, o), mload(add(b, o))) - o := add(o, w) // `sub(o, 0x20)`. - if iszero(o) { break } - } - let totalLen := add(aLen, bLen) - let last := add(add(result, 0x20), totalLen) - mstore(last, 0) // Zeroize the slot after the bytes. - mstore(result, totalLen) // Store the length. - mstore(0x40, add(last, 0x20)) // Allocate memory. - } - } - - /// @dev Returns whether `a` equals `b`. - function eq(bytes memory a, bytes memory b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b))) - } - } - - /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small bytes. - function eqs(bytes memory a, bytes32 b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - // These should be evaluated on compile time, as far as possible. - let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`. - let x := not(or(m, or(b, add(m, and(b, m))))) - let r := shl(7, iszero(iszero(shr(128, x)))) - r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x)))))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // forgefmt: disable-next-item - result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))), - xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20))))) - } - } - - /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`. - /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1. - function cmp(bytes memory a, bytes memory b) internal pure returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - let aLen := mload(a) - let bLen := mload(b) - let n := and(xor(aLen, mul(xor(aLen, bLen), lt(bLen, aLen))), not(0x1f)) - if n { - for { let i := 0x20 } 1 {} { - let x := mload(add(a, i)) - let y := mload(add(b, i)) - if iszero(or(xor(x, y), eq(i, n))) { - i := add(i, 0x20) - continue - } - result := sub(gt(x, y), lt(x, y)) - break - } - } - // forgefmt: disable-next-item - if iszero(result) { - let l := 0x201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201 - let x := and(mload(add(add(a, 0x20), n)), shl(shl(3, byte(sub(aLen, n), l)), not(0))) - let y := and(mload(add(add(b, 0x20), n)), shl(shl(3, byte(sub(bLen, n), l)), not(0))) - result := sub(gt(x, y), lt(x, y)) - if iszero(result) { result := sub(gt(aLen, bLen), lt(aLen, bLen)) } - } - } - } - - /// @dev Directly returns `a` without copying. - function directReturn(bytes memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - // Assumes that the bytes does not start from the scratch space. - let retStart := sub(a, 0x20) - let retUnpaddedSize := add(mload(a), 0x40) - // Right pad with zeroes. Just in case the bytes is produced - // by a method that doesn't zero right pad. - mstore(add(retStart, retUnpaddedSize), 0) - mstore(retStart, 0x20) // Store the return offset. - // End the transaction, returning the bytes. - return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize))) - } - } - - /// @dev Directly returns `a` with minimal copying. - function directReturn(bytes[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) // `a.length`. - let o := add(a, 0x20) // Start of elements in `a`. - let u := a // Highest memory slot. - let w := not(0x1f) - for { let i := 0 } iszero(eq(i, n)) { i := add(i, 1) } { - let c := add(o, shl(5, i)) // Location of pointer to `a[i]`. - let s := mload(c) // `a[i]`. - let l := mload(s) // `a[i].length`. - let r := and(l, 0x1f) // `a[i].length % 32`. - let z := add(0x20, and(l, w)) // Offset of last word in `a[i]` from `s`. - // If `s` comes before `o`, or `s` is not zero right padded. - if iszero(lt(lt(s, o), or(iszero(r), iszero(shl(shl(3, r), mload(add(s, z))))))) { - let m := mload(0x40) - mstore(m, l) // Copy `a[i].length`. - for {} 1 {} { - mstore(add(m, z), mload(add(s, z))) // Copy `a[i]`, backwards. - z := add(z, w) // `sub(z, 0x20)`. - if iszero(z) { break } - } - let e := add(add(m, 0x20), l) - mstore(e, 0) // Zeroize the slot after the copied bytes. - mstore(0x40, add(e, 0x20)) // Allocate memory. - s := m - } - mstore(c, sub(s, o)) // Convert to calldata offset. - let t := add(l, add(s, 0x20)) - if iszero(lt(t, u)) { u := t } - } - let retStart := add(a, w) // Assumes `a` doesn't start from scratch space. - mstore(retStart, 0x20) // Store the return offset. - return(retStart, add(0x40, sub(u, retStart))) // End the transaction. - } - } - - /// @dev Returns the word at `offset`, without any bounds checks. - function load(bytes memory a, uint256 offset) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(add(add(a, 0x20), offset)) - } - } - - /// @dev Returns the word at `offset`, without any bounds checks. - function loadCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes32 result) - { - /// @solidity memory-safe-assembly - assembly { - result := calldataload(add(a.offset, offset)) - } - } - - /// @dev Returns a slice representing a static struct in the calldata. Performs bounds checks. - function staticStructInCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - let l := sub(a.length, 0x20) - result.offset := add(a.offset, offset) - result.length := sub(a.length, offset) - if or(shr(64, or(l, a.offset)), gt(offset, l)) { revert(l, 0x00) } - } - } - - /// @dev Returns a slice representing a dynamic struct in the calldata. Performs bounds checks. - function dynamicStructInCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - let l := sub(a.length, 0x20) - let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`. - result.offset := add(a.offset, s) - result.length := sub(a.length, s) - if or(shr(64, or(s, or(l, a.offset))), gt(offset, l)) { revert(l, 0x00) } - } - } - - /// @dev Returns bytes in calldata. Performs bounds checks. - function bytesInCalldata(bytes calldata a, uint256 offset) - internal - pure - returns (bytes calldata result) - { - /// @solidity memory-safe-assembly - assembly { - let l := sub(a.length, 0x20) - let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`. - result.offset := add(add(a.offset, s), 0x20) - result.length := calldataload(add(a.offset, s)) - // forgefmt: disable-next-item - if or(shr(64, or(result.length, or(s, or(l, a.offset)))), - or(gt(add(s, result.length), l), gt(offset, l))) { revert(l, 0x00) } - } - } - - /// @dev Checks if `x` is in `a`. Assumes `a` has been checked. - function checkInCalldata(bytes calldata x, bytes calldata a) internal pure { - /// @solidity memory-safe-assembly - assembly { - if or( - or(lt(x.offset, a.offset), gt(add(x.offset, x.length), add(a.length, a.offset))), - shr(64, or(x.length, x.offset)) - ) { revert(0x00, 0x00) } - } - } - - /// @dev Checks if `x` is in `a`. Assumes `a` has been checked. - function checkInCalldata(bytes[] calldata x, bytes calldata a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let e := sub(add(a.length, a.offset), 0x20) - if or(lt(x.offset, a.offset), shr(64, x.offset)) { revert(0x00, 0x00) } - for { let i := 0 } iszero(eq(x.length, i)) { i := add(i, 1) } { - let o := calldataload(add(x.offset, shl(5, i))) - let t := add(o, x.offset) - let l := calldataload(t) - if or(shr(64, or(l, o)), gt(add(t, l), e)) { revert(0x00, 0x00) } - } - } - } - - /// @dev Returns empty calldata bytes. For silencing the compiler. - function emptyCalldata() internal pure returns (bytes calldata result) { - /// @solidity memory-safe-assembly - assembly { - result.length := 0 - } - } - - /// @dev Returns the most significant 20 bytes as an address. - function msbToAddress(bytes32 x) internal pure returns (address) { - return address(bytes20(x)); - } - - /// @dev Returns the least significant 20 bytes as an address. - function lsbToAddress(bytes32 x) internal pure returns (address) { - return address(uint160(uint256(x))); - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibMap.sol b/grouperBot/lib/solady/src/utils/g/LibMap.sol deleted file mode 100644 index cea3d28..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibMap.sol +++ /dev/null @@ -1,318 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev A uint8 map in storage. -struct Uint8Map { - mapping(uint256 => uint256) map; -} - -/// @dev A uint16 map in storage. -struct Uint16Map { - mapping(uint256 => uint256) map; -} - -/// @dev A uint32 map in storage. -struct Uint32Map { - mapping(uint256 => uint256) map; -} - -/// @dev A uint40 map in storage. Useful for storing timestamps up to 34841 A.D. -struct Uint40Map { - mapping(uint256 => uint256) map; -} - -/// @dev A uint64 map in storage. -struct Uint64Map { - mapping(uint256 => uint256) map; -} - -/// @dev A uint128 map in storage. -struct Uint128Map { - mapping(uint256 => uint256) map; -} - -using LibMap for Uint8Map global; -using LibMap for Uint16Map global; -using LibMap for Uint32Map global; -using LibMap for Uint40Map global; -using LibMap for Uint64Map global; -using LibMap for Uint128Map global; - -/// @notice Library for storage of packed unsigned integers. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibMap.sol) -library LibMap { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* GETTERS / SETTERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the uint8 value at `index` in `map`. - function get(Uint8Map storage map, uint256 index) internal view returns (uint8 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(5, index)) - result := byte(and(31, not(index)), sload(keccak256(0x00, 0x40))) - } - } - - /// @dev Updates the uint8 value at `index` in `map`. - function set(Uint8Map storage map, uint256 index, uint8 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(5, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - mstore(0x00, sload(s)) - mstore8(and(31, not(index)), value) - sstore(s, mload(0x00)) - } - } - - /// @dev Returns the uint16 value at `index` in `map`. - function get(Uint16Map storage map, uint256 index) internal view returns (uint16 result) { - result = uint16(map.map[index >> 4] >> ((index & 15) << 4)); - } - - /// @dev Updates the uint16 value at `index` in `map`. - function set(Uint16Map storage map, uint256 index, uint16 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(4, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(4, and(index, 15)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint32 value at `index` in `map`. - function get(Uint32Map storage map, uint256 index) internal view returns (uint32 result) { - result = uint32(map.map[index >> 3] >> ((index & 7) << 5)); - } - - /// @dev Updates the uint32 value at `index` in `map`. - function set(Uint32Map storage map, uint256 index, uint32 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(3, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(5, and(index, 7)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint40 value at `index` in `map`. - function get(Uint40Map storage map, uint256 index) internal view returns (uint40 result) { - unchecked { - result = uint40(map.map[index / 6] >> ((index % 6) * 40)); - } - } - - /// @dev Updates the uint40 value at `index` in `map`. - function set(Uint40Map storage map, uint256 index, uint40 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, div(index, 6)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := mul(40, mod(index, 6)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint64 value at `index` in `map`. - function get(Uint64Map storage map, uint256 index) internal view returns (uint64 result) { - result = uint64(map.map[index >> 2] >> ((index & 3) << 6)); - } - - /// @dev Updates the uint64 value at `index` in `map`. - function set(Uint64Map storage map, uint256 index, uint64 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(2, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(6, and(index, 3)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffffffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the uint128 value at `index` in `map`. - function get(Uint128Map storage map, uint256 index) internal view returns (uint128 result) { - result = uint128(map.map[index >> 1] >> ((index & 1) << 7)); - } - - /// @dev Updates the uint128 value at `index` in `map`. - function set(Uint128Map storage map, uint256 index, uint128 value) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, map.slot) - mstore(0x00, shr(1, index)) - let s := keccak256(0x00, 0x40) // Storage slot. - let o := shl(7, and(index, 1)) // Storage slot offset (bits). - let v := sload(s) // Storage slot value. - let m := 0xffffffffffffffffffffffffffffffff // Value mask. - sstore(s, xor(v, shl(o, and(m, xor(shr(o, v), value))))) - } - } - - /// @dev Returns the value at `index` in `map`. - function get(mapping(uint256 => uint256) storage map, uint256 index, uint256 bitWidth) - internal - view - returns (uint256 result) - { - unchecked { - uint256 d = _rawDiv(256, bitWidth); // Bucket size. - uint256 m = (1 << bitWidth) - 1; // Value mask. - result = (map[_rawDiv(index, d)] >> (_rawMod(index, d) * bitWidth)) & m; - } - } - - /// @dev Updates the value at `index` in `map`. - function set( - mapping(uint256 => uint256) storage map, - uint256 index, - uint256 value, - uint256 bitWidth - ) internal { - unchecked { - uint256 d = _rawDiv(256, bitWidth); // Bucket size. - uint256 m = (1 << bitWidth) - 1; // Value mask. - uint256 o = _rawMod(index, d) * bitWidth; // Storage slot offset (bits). - map[_rawDiv(index, d)] ^= (((map[_rawDiv(index, d)] >> o) ^ value) & m) << o; - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BINARY SEARCH */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // The following functions search in the range of [`start`, `end`) - // (i.e. `start <= index < end`). - // The range must be sorted in ascending order. - // `index` precedence: equal to > nearest before > nearest after. - // An invalid search range will simply return `(found = false, index = start)`. - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint8Map storage map, uint8 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 8); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint16Map storage map, uint16 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 16); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint32Map storage map, uint32 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 32); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint40Map storage map, uint40 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 40); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint64Map storage map, uint64 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 64); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted(Uint128Map storage map, uint128 needle, uint256 start, uint256 end) - internal - view - returns (bool found, uint256 index) - { - return searchSorted(map.map, needle, start, end, 128); - } - - /// @dev Returns whether `map` contains `needle`, and the index of `needle`. - function searchSorted( - mapping(uint256 => uint256) storage map, - uint256 needle, - uint256 start, - uint256 end, - uint256 bitWidth - ) internal view returns (bool found, uint256 index) { - unchecked { - if (start >= end) end = start; - uint256 t; - uint256 o = start - 1; // Offset to derive the actual index. - uint256 l = 1; // Low. - uint256 d = _rawDiv(256, bitWidth); // Bucket size. - uint256 m = (1 << bitWidth) - 1; // Value mask. - uint256 h = end - start; // High. - while (true) { - index = (l & h) + ((l ^ h) >> 1); - if (l > h) break; - t = (map[_rawDiv(index + o, d)] >> (_rawMod(index + o, d) * bitWidth)) & m; - if (t == needle) break; - if (needle <= t) h = index - 1; - else l = index + 1; - } - /// @solidity memory-safe-assembly - assembly { - m := or(iszero(index), iszero(bitWidth)) - found := iszero(or(xor(t, needle), m)) - index := add(o, xor(index, mul(xor(index, 1), m))) - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `x / y`, returning 0 if `y` is zero. - function _rawDiv(uint256 x, uint256 y) private pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := div(x, y) - } - } - - /// @dev Returns `x % y`, returning 0 if `y` is zero. - function _rawMod(uint256 x, uint256 y) private pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - z := mod(x, y) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibPRNG.sol b/grouperBot/lib/solady/src/utils/g/LibPRNG.sol deleted file mode 100644 index 9f21886..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibPRNG.sol +++ /dev/null @@ -1,505 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev A pseudorandom number state in memory. -struct PRNG { - uint256 state; -} - -/// @dev A lazy Fisher-Yates shuffler for a range `[0..n)` in storage. -struct LazyShuffler { - // Bits Layout: - // - [0..31] `numShuffled` - // - [32..223] `permutationSlot` - // - [224..255] `length` - uint256 _state; -} - -using LibPRNG for PRNG global; -using LibPRNG for LazyShuffler global; - -/// @notice Library for generating pseudorandom numbers. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibPRNG.sol) -/// @author LazyShuffler based on NextShuffler by aschlosberg (divergencearran) -/// (https://github.com/divergencetech/ethier/blob/main/contracts/random/NextShuffler.sol) -library LibPRNG { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The initial length must be greater than zero and less than `2**32 - 1`. - error InvalidInitialLazyShufflerLength(); - - /// @dev The new length must not be less than the current length. - error InvalidNewLazyShufflerLength(); - - /// @dev The lazy shuffler has not been initialized. - error LazyShufflerNotInitialized(); - - /// @dev Cannot double initialize the lazy shuffler. - error LazyShufflerAlreadyInitialized(); - - /// @dev The lazy shuffle has finished. - error LazyShuffleFinished(); - - /// @dev The queried index is out of bounds. - error LazyShufflerGetOutOfBounds(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The scalar of ETH and most ERC20s. - uint256 internal constant WAD = 1e18; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Seeds the `prng` with `state`. - function seed(PRNG memory prng, uint256 state) internal pure { - /// @solidity memory-safe-assembly - assembly { - mstore(prng, state) - } - } - - /// @dev Returns the next pseudorandom uint256. - /// All bits of the returned uint256 pass the NIST Statistical Test Suite. - function next(PRNG memory prng) internal pure returns (uint256 result) { - // We simply use `keccak256` for a great balance between - // runtime gas costs, bytecode size, and statistical properties. - // - // A high-quality LCG with a 32-byte state - // is only about 30% more gas efficient during runtime, - // but requires a 32-byte multiplier, which can cause bytecode bloat - // when this function is inlined. - // - // Using this method is about 2x more efficient than - // `nextRandomness = uint256(keccak256(abi.encode(randomness)))`. - /// @solidity memory-safe-assembly - assembly { - result := keccak256(prng, 0x20) - mstore(prng, result) - } - } - - /// @dev Returns a pseudorandom uint256, uniformly distributed - /// between 0 (inclusive) and `upper` (exclusive). - /// If your modulus is big, this method is recommended - /// for uniform sampling to avoid modulo bias. - /// For uniform sampling across all uint256 values, - /// or for small enough moduli such that the bias is negligible, - /// use {next} instead. - function uniform(PRNG memory prng, uint256 upper) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - result := keccak256(prng, 0x20) - mstore(prng, result) - if iszero(lt(result, mod(sub(0, upper), upper))) { break } - } - result := mod(result, upper) - } - } - - /// @dev Returns a sample from the standard normal distribution denominated in `WAD`. - function standardNormalWad(PRNG memory prng) internal pure returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - // Technically, this is the Irwin-Hall distribution with 20 samples. - // The chance of drawing a sample outside 10 σ from the standard normal distribution - // is ≈ 0.000000000000000000000015, which is insignificant for most practical purposes. - // Passes the Kolmogorov-Smirnov test for 200k samples. Uses about 322 gas. - result := keccak256(prng, 0x20) - mstore(prng, result) - let n := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43 // Prime. - let a := 0x100000000000000000000000000000051 // Prime and a primitive root of `n`. - let m := 0x1fffffffffffffff1fffffffffffffff1fffffffffffffff1fffffffffffffff - let s := 0x1000000000000000100000000000000010000000000000001 - let r1 := mulmod(result, a, n) - let r2 := mulmod(r1, a, n) - let r3 := mulmod(r2, a, n) - // forgefmt: disable-next-item - result := sub(sar(96, mul(26614938895861601847173011183, - add(add(shr(192, mul(s, add(and(m, result), and(m, r1)))), - shr(192, mul(s, add(and(m, r2), and(m, r3))))), - shr(192, mul(s, and(m, mulmod(r3, a, n))))))), 7745966692414833770) - } - } - - /// @dev Returns a sample from the unit exponential distribution denominated in `WAD`. - function exponentialWad(PRNG memory prng) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - // Passes the Kolmogorov-Smirnov test for 200k samples. - // Gas usage varies, starting from about 172+ gas. - let r := keccak256(prng, 0x20) - mstore(prng, r) - let p := shl(129, r) - let w := shl(1, r) - if iszero(gt(w, p)) { - let n := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43 // Prime. - let a := 0x100000000000000000000000000000051 // Prime and a primitive root of `n`. - for {} 1 {} { - r := mulmod(r, a, n) - if iszero(lt(shl(129, r), w)) { - r := mulmod(r, a, n) - result := add(1000000000000000000, result) - w := shl(1, r) - p := shl(129, r) - if iszero(lt(w, p)) { break } - continue - } - w := shl(1, r) - if iszero(lt(w, shl(129, r))) { break } - } - } - result := add(div(p, shl(129, 170141183460469231732)), result) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* MEMORY ARRAY SHUFFLING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Shuffles the array in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, uint256[] memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - let w := not(0) - let mask := shr(128, w) - if n { - for { a := add(a, 0x20) } 1 {} { - // We can just directly use `keccak256`, cuz - // the other approaches don't save much. - let r := keccak256(prng, 0x20) - mstore(prng, r) - - // Note that there will be a very tiny modulo bias - // if the length of the array is not a power of 2. - // For all practical purposes, it is negligible - // and will not be a fairness or security concern. - { - let j := add(a, shl(5, mod(shr(128, r), n))) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let i := add(a, shl(5, n)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - } - - { - let j := add(a, shl(5, mod(and(r, mask), n))) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let i := add(a, shl(5, n)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - } - } - } - } - } - - /// @dev Shuffles the array in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, int256[] memory a) internal pure { - shuffle(prng, _toUints(a)); - } - - /// @dev Shuffles the array in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, address[] memory a) internal pure { - shuffle(prng, _toUints(a)); - } - - /// @dev Partially shuffles the array in-place with Fisher-Yates shuffle. - /// The first `k` elements will be uniformly sampled without replacement. - function shuffle(PRNG memory prng, uint256[] memory a, uint256 k) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - k := xor(k, mul(xor(k, n), lt(n, k))) // `min(n, k)`. - if k { - let mask := shr(128, not(0)) - let b := 0 - for { a := add(a, 0x20) } 1 {} { - // We can just directly use `keccak256`, cuz - // the other approaches don't save much. - let r := keccak256(prng, 0x20) - mstore(prng, r) - - // Note that there will be a very tiny modulo bias - // if the length of the array is not a power of 2. - // For all practical purposes, it is negligible - // and will not be a fairness or security concern. - { - let j := add(a, shl(5, add(b, mod(shr(128, r), sub(n, b))))) - let i := add(a, shl(5, b)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - b := add(b, 1) - if eq(b, k) { break } - } - - { - let j := add(a, shl(5, add(b, mod(and(r, mask), sub(n, b))))) - let i := add(a, shl(5, b)) - let t := mload(i) - mstore(i, mload(j)) - mstore(j, t) - b := add(b, 1) - if eq(b, k) { break } - } - } - } - } - } - - /// @dev Partially shuffles the array in-place with Fisher-Yates shuffle. - /// The first `k` elements will be uniformly sampled without replacement. - function shuffle(PRNG memory prng, int256[] memory a, uint256 k) internal pure { - shuffle(prng, _toUints(a), k); - } - - /// @dev Partially shuffles the array in-place with Fisher-Yates shuffle. - /// The first `k` elements will be uniformly sampled without replacement. - function shuffle(PRNG memory prng, address[] memory a, uint256 k) internal pure { - shuffle(prng, _toUints(a), k); - } - - /// @dev Shuffles the bytes in-place with Fisher-Yates shuffle. - function shuffle(PRNG memory prng, bytes memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - let w := not(0) - let mask := shr(128, w) - if n { - let b := add(a, 0x01) - for { a := add(a, 0x20) } 1 {} { - // We can just directly use `keccak256`, cuz - // the other approaches don't save much. - let r := keccak256(prng, 0x20) - mstore(prng, r) - - // Note that there will be a very tiny modulo bias - // if the length of the array is not a power of 2. - // For all practical purposes, it is negligible - // and will not be a fairness or security concern. - { - let o := mod(shr(128, r), n) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let t := mload(add(b, n)) - mstore8(add(a, n), mload(add(b, o))) - mstore8(add(a, o), t) - } - - { - let o := mod(and(r, mask), n) - n := add(n, w) // `sub(n, 1)`. - if iszero(n) { break } - - let t := mload(add(b, n)) - mstore8(add(a, n), mload(add(b, o))) - mstore8(add(a, o), t) - } - } - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STORAGE-BASED RANGE LAZY SHUFFLING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Initializes the state for lazy-shuffling the range `[0..n)`. - /// Reverts if `n == 0 || n >= 2**32 - 1`. - /// Reverts if `$` has already been initialized. - /// If you need to reduce the length after initialization, just use a fresh new `$`. - function initialize(LazyShuffler storage $, uint256 n) internal { - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(sub(n, 1), 0xfffffffe)) { - mstore(0x00, 0x83b53941) // `InvalidInitialLazyShufflerLength()`. - revert(0x1c, 0x04) - } - if sload($.slot) { - mstore(0x00, 0x0c9f11f2) // `LazyShufflerAlreadyInitialized()`. - revert(0x1c, 0x04) - } - mstore(0x00, $.slot) - sstore($.slot, or(shl(224, n), shl(32, shr(64, keccak256(0x00, 0x20))))) - } - } - - /// @dev Increases the length of `$`. - /// Reverts if `$` has not been initialized. - function grow(LazyShuffler storage $, uint256 n) internal { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) // The packed value at `$`. - // If the new length is smaller than the old length, revert. - if lt(n, shr(224, state)) { - mstore(0x00, 0xbed37c6e) // `InvalidNewLazyShufflerLength()`. - revert(0x1c, 0x04) - } - if iszero(state) { - mstore(0x00, 0x1ead2566) // `LazyShufflerNotInitialized()`. - revert(0x1c, 0x04) - } - sstore($.slot, or(shl(224, n), shr(32, shl(32, state)))) - } - } - - /// @dev Restarts the shuffler by setting `numShuffled` to zero, - /// such that all elements can be drawn again. - /// Restarting does NOT clear the internal permutation, nor changes the length. - /// Even with the same sequence of randomness, reshuffling can yield different results. - function restart(LazyShuffler storage $) internal { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) - if iszero(state) { - mstore(0x00, 0x1ead2566) // `LazyShufflerNotInitialized()`. - revert(0x1c, 0x04) - } - sstore($.slot, shl(32, shr(32, state))) - } - } - - /// @dev Returns the number of elements that have been shuffled. - function numShuffled(LazyShuffler storage $) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := and(0xffffffff, sload($.slot)) - } - } - - /// @dev Returns the length of `$`. - /// Returns zero if `$` is not initialized, else a non-zero value less than `2**32 - 1`. - function length(LazyShuffler storage $) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(224, sload($.slot)) - } - } - - /// @dev Returns if `$` has been initialized. - function initialized(LazyShuffler storage $) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := iszero(iszero(sload($.slot))) - } - } - - /// @dev Returns if there are any more elements left to shuffle. - /// Reverts if `$` is not initialized. - function finished(LazyShuffler storage $) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) // The packed value at `$`. - if iszero(state) { - mstore(0x00, 0x1ead2566) // `LazyShufflerNotInitialized()`. - revert(0x1c, 0x04) - } - result := eq(shr(224, state), and(0xffffffff, state)) - } - } - - /// @dev Returns the current value stored at `index`, accounting for all historical shuffling. - /// Reverts if `index` is greater than or equal to the `length` of `$`. - function get(LazyShuffler storage $, uint256 index) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - let state := sload($.slot) // The packed value at `$`. - let n := shr(224, state) // Length of `$`. - if iszero(lt(index, n)) { - mstore(0x00, 0x61367cc4) // `LazyShufflerGetOutOfBounds()`. - revert(0x1c, 0x04) - } - let u32 := gt(n, 0xfffe) - let s := add(shr(sub(4, u32), index), shr(64, shl(32, state))) // Bucket slot. - let o := shl(add(4, u32), and(index, shr(u32, 15))) // Bucket slot offset (bits). - let m := sub(shl(shl(u32, 16), 1), 1) // Value mask. - result := and(m, shr(o, sload(s))) - result := xor(index, mul(xor(index, sub(result, 1)), iszero(iszero(result)))) - } - } - - /// @dev Does a single Fisher-Yates shuffle step, increments the `numShuffled` in `$`, - /// and returns the next value in the shuffled range. - /// `randomness` can be taken from a good-enough source, or a higher quality source like VRF. - /// Reverts if there are no more values to shuffle, which includes the case if `$` is not initialized. - function next(LazyShuffler storage $, uint256 randomness) internal returns (uint256 chosen) { - /// @solidity memory-safe-assembly - assembly { - function _get(u32_, state_, i_) -> _value { - let s_ := add(shr(sub(4, u32_), i_), shr(64, shl(32, state_))) // Bucket slot. - let o_ := shl(add(4, u32_), and(i_, shr(u32_, 15))) // Bucket slot offset (bits). - let m_ := sub(shl(shl(u32_, 16), 1), 1) // Value mask. - _value := and(m_, shr(o_, sload(s_))) - _value := xor(i_, mul(xor(i_, sub(_value, 1)), iszero(iszero(_value)))) - } - function _set(u32_, state_, i_, value_) { - let s_ := add(shr(sub(4, u32_), i_), shr(64, shl(32, state_))) // Bucket slot. - let o_ := shl(add(4, u32_), and(i_, shr(u32_, 15))) // Bucket slot offset (bits). - let m_ := sub(shl(shl(u32_, 16), 1), 1) // Value mask. - let v_ := sload(s_) // Bucket slot value. - value_ := mul(iszero(eq(i_, value_)), add(value_, 1)) - sstore(s_, xor(v_, shl(o_, and(m_, xor(shr(o_, v_), value_))))) - } - let state := sload($.slot) // The packed value at `$`. - let shuffled := and(0xffffffff, state) // Number of elements shuffled. - let n := shr(224, state) // Length of `$`. - let remainder := sub(n, shuffled) // Number of elements left to shuffle. - if iszero(remainder) { - mstore(0x00, 0x51065f79) // `LazyShuffleFinished()`. - revert(0x1c, 0x04) - } - mstore(0x00, randomness) // (Re)hash the randomness so that we don't - mstore(0x20, shuffled) // need to expect guarantees on its distribution. - let index := add(mod(keccak256(0x00, 0x40), remainder), shuffled) - chosen := _get(gt(n, 0xfffe), state, index) - _set(gt(n, 0xfffe), state, index, _get(gt(n, 0xfffe), state, shuffled)) - _set(gt(n, 0xfffe), state, shuffled, chosen) - sstore($.slot, add(1, state)) // Increment the `numShuffled` by 1, and store it. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(int256[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - casted := a - } - } - - /// @dev Reinterpret cast to an uint256 array. - function _toUints(address[] memory a) private pure returns (uint256[] memory casted) { - /// @solidity memory-safe-assembly - assembly { - // As any address written to memory will have the upper 96 bits - // of the word zeroized (as per Solidity spec), we can directly - // compare these addresses as if they are whole uint256 words. - casted := a - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibRLP.sol b/grouperBot/lib/solady/src/utils/g/LibRLP.sol deleted file mode 100644 index f13e82e..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibRLP.sol +++ /dev/null @@ -1,395 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev A pointer to a RLP item list in memory. -struct List { - // Do NOT modify the `_data` directly. - uint256 _data; -} - -using LibRLP for List global; - -/// @notice Library for RLP encoding and CREATE address computation. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibRLP.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibRLP.sol) -library LibRLP { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CREATE ADDRESS PREDICTION */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the address where a contract will be stored if deployed via - /// `deployer` with `nonce` using the `CREATE` opcode. - /// For the specification of the Recursive Length Prefix (RLP) - /// encoding scheme, please refer to p. 19 of the Ethereum Yellow Paper - /// (https://ethereum.github.io/yellowpaper/paper.pdf) - /// and the Ethereum Wiki (https://eth.wiki/fundamentals/rlp). - /// - /// Based on the EIP-161 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md) - /// specification, all contract accounts on the Ethereum mainnet are initiated with - /// `nonce = 1`. Thus, the first contract address created by another contract - /// is calculated with a non-zero nonce. - /// - /// The theoretical allowed limit, based on EIP-2681 - /// (https://eips.ethereum.org/EIPS/eip-2681), for an account nonce is 2**64-2. - /// - /// Caution! This function will NOT check that the nonce is within the theoretical range. - /// This is for performance, as exceeding the range is extremely impractical. - /// It is the user's responsibility to ensure that the nonce is valid - /// (e.g. no dirty bits after packing / unpacking). - /// - /// This is equivalent to: - /// `address(uint160(uint256(keccak256(LibRLP.p(deployer).p(nonce).encode()))))`. - /// - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function computeAddress(address deployer, uint256 nonce) - internal - pure - returns (address deployed) - { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - // The integer zero is treated as an empty byte string, - // and as a result it only has a length prefix, 0x80, - // computed via `0x80 + 0`. - - // A one-byte integer in the [0x00, 0x7f] range uses its - // own value as a length prefix, - // there is no additional `0x80 + length` prefix that precedes it. - if iszero(gt(nonce, 0x7f)) { - mstore(0x00, deployer) - // Using `mstore8` instead of `or` naturally cleans - // any dirty upper bits of `deployer`. - mstore8(0x0b, 0x94) - mstore8(0x0a, 0xd6) - // `shl` 7 is equivalent to multiplying by 0x80. - mstore8(0x20, or(shl(7, iszero(nonce)), nonce)) - deployed := keccak256(0x0a, 0x17) - break - } - let i := 8 - // Just use a loop to generalize all the way with minimal bytecode size. - for {} shr(i, nonce) { i := add(i, 8) } {} - // `shr` 3 is equivalent to dividing by 8. - i := shr(3, i) - // Store in descending slot sequence to overlap the values correctly. - mstore(i, nonce) - mstore(0x00, shl(8, deployer)) - mstore8(0x1f, add(0x80, i)) - mstore8(0x0a, 0x94) - mstore8(0x09, add(0xd6, i)) - deployed := keccak256(0x09, add(0x17, i)) - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RLP ENCODING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: - // - addresses are treated like byte strings of length 20, agnostic of leading zero bytes. - // - uint256s are converted to byte strings, stripped of leading zero bytes, and encoded. - // - bools are converted to uint256s (`b ? 1 : 0`), then encoded with the uint256. - // - For bytes1 to bytes32, you must manually convert them to bytes memory - // with `abi.encodePacked(x)` before encoding. - - /// @dev Returns a new empty list. - function p() internal pure returns (List memory result) {} - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(uint256 x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(address x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(bool x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(bytes memory x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Returns a new list with `x` as the only element. Equivalent to `LibRLP.p().p(x)`. - function p(List memory x) internal pure returns (List memory result) { - p(result, x); - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, uint256 x) internal pure returns (List memory result) { - result._data = x << 48; - _updateTail(list, result); - /// @solidity memory-safe-assembly - assembly { - // If `x` is too big, we cannot pack it inline with the node. - // We'll have to allocate a new slot for `x` and store the pointer to it in the node. - if shr(208, x) { - let m := mload(0x40) - mstore(m, x) - mstore(0x40, add(m, 0x20)) - mstore(result, shl(40, or(1, shl(8, m)))) - } - } - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, address x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(40, or(4, shl(8, x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, bool x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(48, iszero(iszero(x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, bytes memory x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(40, or(2, shl(8, x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Appends `x` to `list`. Returns `list` for function chaining. - function p(List memory list, List memory x) internal pure returns (List memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(result, shl(40, or(3, shl(8, x)))) - } - _updateTail(list, result); - result = list; - } - - /// @dev Returns the RLP encoding of `list`. - function encode(List memory list) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function encodeUint(x_, o_) -> _o { - _o := add(o_, 1) - if iszero(gt(x_, 0x7f)) { - mstore8(o_, or(shl(7, iszero(x_)), x_)) // Copy `x_`. - leave - } - let r_ := shl(7, lt(0xffffffffffffffffffffffffffffffff, x_)) - r_ := or(r_, shl(6, lt(0xffffffffffffffff, shr(r_, x_)))) - r_ := or(r_, shl(5, lt(0xffffffff, shr(r_, x_)))) - r_ := or(r_, shl(4, lt(0xffff, shr(r_, x_)))) - r_ := or(shr(3, r_), lt(0xff, shr(r_, x_))) - mstore8(o_, add(r_, 0x81)) // Store the prefix. - mstore(0x00, x_) - mstore(_o, mload(xor(31, r_))) // Copy `x_`. - _o := add(add(1, r_), _o) - } - function encodeAddress(x_, o_) -> _o { - _o := add(o_, 0x15) - mstore(o_, shl(88, x_)) - mstore8(o_, 0x94) - } - function encodeBytes(x_, o_, c_) -> _o { - _o := add(o_, 1) - let n_ := mload(x_) - if iszero(gt(n_, 55)) { - let f_ := mload(add(0x20, x_)) - if iszero(and(eq(1, n_), lt(byte(0, f_), 0x80))) { - mstore8(o_, add(n_, c_)) // Store the prefix. - mstore(add(0x21, o_), mload(add(0x40, x_))) - mstore(_o, f_) - _o := add(n_, _o) - leave - } - mstore(o_, f_) // Copy `x_`. - leave - } - returndatacopy(returndatasize(), returndatasize(), shr(32, n_)) - let r_ := add(1, add(lt(0xff, n_), add(lt(0xffff, n_), lt(0xffffff, n_)))) - mstore(o_, shl(248, add(r_, add(c_, 55)))) // Store the prefix. - // Copy `x`. - let i_ := add(r_, _o) - _o := add(i_, n_) - for { let d_ := sub(add(0x20, x_), i_) } 1 {} { - mstore(i_, mload(add(d_, i_))) - i_ := add(i_, 0x20) - if iszero(lt(i_, _o)) { break } - } - mstore(o_, or(mload(o_), shl(sub(248, shl(3, r_)), n_))) // Store the prefix. - } - function encodeList(l_, o_) -> _o { - if iszero(mload(l_)) { - mstore8(o_, 0xc0) - _o := add(o_, 1) - leave - } - let j_ := add(o_, 0x20) - for { let h_ := l_ } 1 {} { - h_ := and(mload(h_), 0xffffffffff) - if iszero(h_) { break } - let t_ := byte(26, mload(h_)) - if iszero(gt(t_, 1)) { - if iszero(t_) { - j_ := encodeUint(shr(48, mload(h_)), j_) - continue - } - j_ := encodeUint(mload(shr(48, mload(h_))), j_) - continue - } - if eq(t_, 2) { - j_ := encodeBytes(shr(48, mload(h_)), j_, 0x80) - continue - } - if eq(t_, 3) { - j_ := encodeList(shr(48, mload(h_)), j_) - continue - } - j_ := encodeAddress(shr(48, mload(h_)), j_) - } - let n_ := sub(j_, add(o_, 0x20)) - if iszero(gt(n_, 55)) { - mstore8(o_, add(n_, 0xc0)) // Store the prefix. - mstore(add(0x01, o_), mload(add(0x20, o_))) - mstore(add(0x21, o_), mload(add(0x40, o_))) - _o := add(n_, add(0x01, o_)) - leave - } - mstore(o_, n_) - _o := encodeBytes(o_, o_, 0xc0) - } - result := mload(0x40) - let begin := add(result, 0x20) - let end := encodeList(list, begin) - mstore(result, sub(end, begin)) // Store the length of `result`. - mstore(end, 0) // Zeroize the slot after `result`. - mstore(0x40, add(end, 0x20)) // Allocate memory for `result`. - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(uint256 x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - result := mload(0x40) - if iszero(gt(x, 0x7f)) { - mstore(result, 1) // Store the length of `result`. - mstore(add(result, 0x20), shl(248, or(shl(7, iszero(x)), x))) // Copy `x`. - mstore(0x40, add(result, 0x40)) // Allocate memory for `result`. - break - } - let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := add(2, or(shr(3, r), lt(0xff, shr(r, x)))) - mstore(add(r, result), x) // Copy `x`. - mstore(add(result, 1), add(r, 0x7f)) // Store the prefix. - mstore(result, r) // Store the length of `result`. - mstore(add(r, add(result, 0x20)), 0) // Zeroize the slot after `result`. - mstore(0x40, add(result, 0x60)) // Allocate memory for `result`. - break - } - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(address x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 0x15) - let o := add(0x20, result) - mstore(o, shl(88, x)) - mstore8(o, 0x94) - mstore(0x40, add(0x20, o)) - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(bool x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 1) - mstore(add(0x20, result), shl(add(0xf8, mul(7, iszero(x))), 0x01)) - mstore(0x40, add(0x40, result)) - } - } - - /// @dev Returns the RLP encoding of `x`. - function encode(bytes memory x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := x - - for {} iszero(and(eq(1, mload(x)), lt(byte(0, mload(add(x, 0x20))), 0x80))) {} { - result := mload(0x40) - let n := mload(x) // Length of `x`. - if iszero(gt(n, 55)) { - mstore(0x40, add(result, 0x60)) - mstore(add(0x41, result), mload(add(0x40, x))) - mstore(add(0x21, result), mload(add(0x20, x))) - mstore(add(1, result), add(n, 0x80)) // Store the prefix. - mstore(result, add(1, n)) // Store the length of `result`. - mstore(add(add(result, 0x21), n), 0) // Zeroize the slot after `result`. - break - } - returndatacopy(returndatasize(), returndatasize(), shr(32, n)) - let r := add(2, add(lt(0xff, n), add(lt(0xffff, n), lt(0xffffff, n)))) - // Copy `x`. - let i := add(r, add(0x20, result)) - let end := add(i, n) - for { let d := sub(add(0x20, x), i) } 1 {} { - mstore(i, mload(add(d, i))) - i := add(i, 0x20) - if iszero(lt(i, end)) { break } - } - mstore(add(r, result), n) // Store the prefix. - mstore(add(1, result), add(r, 0xb6)) // Store the prefix. - mstore(result, add(r, n)) // Store the length of `result`. - mstore(end, 0) // Zeroize the slot after `result`. - mstore(0x40, add(end, 0x20)) // Allocate memory. - break - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Updates the tail in `list`. - function _updateTail(List memory list, List memory result) private pure { - /// @solidity memory-safe-assembly - assembly { - let v := or(shr(mload(list), result), mload(list)) - let tail := shr(40, v) - mstore(list, xor(shl(40, xor(tail, result)), v)) // Update the tail. - mstore(tail, or(mload(tail), result)) // Make the previous tail point to `result`. - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibStorage.sol b/grouperBot/lib/solady/src/utils/g/LibStorage.sol deleted file mode 100644 index 746f6ac..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibStorage.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev Generates a storage slot that can be invalidated. -struct Bump { - uint256 _current; -} - -/// @dev Pointer struct to a `uint256` in storage. -/// We have opted for a `uint256` as the inner type, -/// as it requires less casting to get / set specific bits. -struct Ref { - uint256 value; -} - -using LibStorage for Bump global; -using LibStorage for Ref global; - -/// @notice Library for basic storage operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibStorage.sol) -library LibStorage { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage slot seed for calculating a bumped storage slot. - /// `bytes4(keccak256("_BUMPED_STORAGE_REF_SLOT_SEED"))`. - uint256 private constant _BUMPED_STORAGE_REF_SLOT_SEED = 0xd4203f8b; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the current storage slot pointed by the bump. - /// Use inline-assembly to cast the result to a desired custom data type storage pointer. - function slot(Bump storage b) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x1f, sload(b.slot)) - mstore(0x04, _BUMPED_STORAGE_REF_SLOT_SEED) - mstore(0x00, b.slot) - result := keccak256(0x00, 0x3f) - } - } - - /// @dev Makes the bump point to a whole new storage slot. - function invalidate(Bump storage b) internal { - unchecked { - ++b._current; - } - } - - /// @dev Returns a bump at the storage slot. - function bump(bytes32 sSlot) internal pure returns (Bump storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } - - /// @dev Returns a bump at the storage slot. - function bump(uint256 sSlot) internal pure returns (Bump storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } - - /// @dev Returns a pointer to a `uint256` in storage. - function ref(bytes32 sSlot) internal pure returns (Ref storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } - - /// @dev Returns a pointer to a `uint256` in storage. - function ref(uint256 sSlot) internal pure returns (Ref storage $) { - /// @solidity memory-safe-assembly - assembly { - $.slot := sSlot - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibString.sol b/grouperBot/lib/solady/src/utils/g/LibString.sol deleted file mode 100644 index 8dd862b..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibString.sol +++ /dev/null @@ -1,981 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev Goated string storage struct that totally MOGs, no cap, fr. -/// Uses less gas and bytecode than Solidity's native string storage. It's meta af. -/// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight. -struct StringStorage { - bytes32 _spacer; -} - -using LibString for StringStorage global; - -import {LibBytes} from "../LibBytes.sol"; - -/// @notice Library for converting numbers into strings and other string operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibString.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) -/// -/// @dev Note: -/// For performance and bytecode compactness, most of the string operations are restricted to -/// byte strings (7-bit ASCII), except where otherwise specified. -/// Usage of byte string operations on charsets with runes spanning two or more bytes -/// can lead to undefined behavior. -library LibString { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The length of the output is too small to contain all the hex digits. - error HexLengthInsufficient(); - - /// @dev The length of the string is more than 32 bytes. - error TooBigForSmallString(); - - /// @dev The input string must be a 7-bit ASCII. - error StringNot7BitASCII(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The constant returned when the `search` is not found in the string. - uint256 internal constant NOT_FOUND = type(uint256).max; - - /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'. - uint128 internal constant ALPHANUMERIC_7_BIT_ASCII = 0x7fffffe07fffffe03ff000000000000; - - /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'. - uint128 internal constant LETTERS_7_BIT_ASCII = 0x7fffffe07fffffe0000000000000000; - - /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyz'. - uint128 internal constant LOWERCASE_7_BIT_ASCII = 0x7fffffe000000000000000000000000; - - /// @dev Lookup for 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. - uint128 internal constant UPPERCASE_7_BIT_ASCII = 0x7fffffe0000000000000000; - - /// @dev Lookup for '0123456789'. - uint128 internal constant DIGITS_7_BIT_ASCII = 0x3ff000000000000; - - /// @dev Lookup for '0123456789abcdefABCDEF'. - uint128 internal constant HEXDIGITS_7_BIT_ASCII = 0x7e0000007e03ff000000000000; - - /// @dev Lookup for '01234567'. - uint128 internal constant OCTDIGITS_7_BIT_ASCII = 0xff000000000000; - - /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'. - uint128 internal constant PRINTABLE_7_BIT_ASCII = 0x7fffffffffffffffffffffff00003e00; - - /// @dev Lookup for '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'. - uint128 internal constant PUNCTUATION_7_BIT_ASCII = 0x78000001f8000001fc00fffe00000000; - - /// @dev Lookup for ' \t\n\r\x0b\x0c'. - uint128 internal constant WHITESPACE_7_BIT_ASCII = 0x100003e00; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STRING STORAGE OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the value of the string storage `$` to `s`. - function set(StringStorage storage $, string memory s) internal { - LibBytes.set(bytesStorage($), bytes(s)); - } - - /// @dev Sets the value of the string storage `$` to `s`. - function setCalldata(StringStorage storage $, string calldata s) internal { - LibBytes.setCalldata(bytesStorage($), bytes(s)); - } - - /// @dev Sets the value of the string storage `$` to the empty string. - function clear(StringStorage storage $) internal { - delete $._spacer; - } - - /// @dev Returns whether the value stored is `$` is the empty string "". - function isEmpty(StringStorage storage $) internal view returns (bool) { - return uint256($._spacer) & 0xff == uint256(0); - } - - /// @dev Returns the length of the value stored in `$`. - function length(StringStorage storage $) internal view returns (uint256) { - return LibBytes.length(bytesStorage($)); - } - - /// @dev Returns the value stored in `$`. - function get(StringStorage storage $) internal view returns (string memory) { - return string(LibBytes.get(bytesStorage($))); - } - - /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0. - function uint8At(StringStorage storage $, uint256 i) internal view returns (uint8) { - return LibBytes.uint8At(bytesStorage($), i); - } - - /// @dev Helper to cast `$` to a `BytesStorage`. - function bytesStorage(StringStorage storage $) - internal - pure - returns (LibBytes.BytesStorage storage casted) - { - /// @solidity memory-safe-assembly - assembly { - casted.slot := $.slot - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* DECIMAL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the base 10 decimal representation of `value`. - function toString(uint256 value) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - // The maximum value of a uint256 contains 78 digits (1 byte per digit), but - // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. - // We will need 1 word for the trailing zeros padding, 1 word for the length, - // and 3 words for a maximum of 78 digits. - result := add(mload(0x40), 0x80) - mstore(0x40, add(result, 0x20)) // Allocate memory. - mstore(result, 0) // Zeroize the slot after the string. - - let end := result // Cache the end of the memory to calculate the length later. - let w := not(0) // Tsk. - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for { let temp := value } 1 {} { - result := add(result, w) // `sub(result, 1)`. - // Store the character to the pointer. - // The ASCII index of the '0' character is 48. - mstore8(result, add(48, mod(temp, 10))) - temp := div(temp, 10) // Keep dividing `temp` until zero. - if iszero(temp) { break } - } - let n := sub(end, result) - result := sub(result, 0x20) // Move the pointer 32 bytes back to make room for the length. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the base 10 decimal representation of `value`. - function toString(int256 value) internal pure returns (string memory result) { - if (value >= 0) return toString(uint256(value)); - unchecked { - result = toString(~uint256(value) + 1); - } - /// @solidity memory-safe-assembly - assembly { - // We still have some spare memory space on the left, - // as we have allocated 3 words (96 bytes) for up to 78 digits. - let n := mload(result) // Load the string length. - mstore(result, 0x2d) // Store the '-' character. - result := sub(result, 1) // Move back the string pointer by a byte. - mstore(result, add(n, 1)) // Update the string length. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* HEXADECIMAL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the hexadecimal representation of `value`, - /// left-padded to an input length of `byteCount` bytes. - /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte, - /// giving a total length of `byteCount * 2 + 2` bytes. - /// Reverts if `byteCount` is too small for the output to contain all the digits. - function toHexString(uint256 value, uint256 byteCount) - internal - pure - returns (string memory result) - { - result = toHexStringNoPrefix(value, byteCount); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`, - /// left-padded to an input length of `byteCount` bytes. - /// The output is not prefixed with "0x" and is encoded using 2 hexadecimal digits per byte, - /// giving a total length of `byteCount * 2` bytes. - /// Reverts if `byteCount` is too small for the output to contain all the digits. - function toHexStringNoPrefix(uint256 value, uint256 byteCount) - internal - pure - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - // We need 0x20 bytes for the trailing zeros padding, `byteCount * 2` bytes - // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length. - // We add 0x20 to the total and round down to a multiple of 0x20. - // (0x20 + 0x20 + 0x02 + 0x20) = 0x62. - result := add(mload(0x40), and(add(shl(1, byteCount), 0x42), not(0x1f))) - mstore(0x40, add(result, 0x20)) // Allocate memory. - mstore(result, 0) // Zeroize the slot after the string. - - let end := result // Cache the end to calculate the length later. - // Store "0123456789abcdef" in scratch space. - mstore(0x0f, 0x30313233343536373839616263646566) - - let start := sub(result, add(byteCount, byteCount)) - let w := not(1) // Tsk. - let temp := value - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for {} 1 {} { - result := add(result, w) // `sub(result, 2)`. - mstore8(add(result, 1), mload(and(temp, 15))) - mstore8(result, mload(and(shr(4, temp), 15))) - temp := shr(8, temp) - if iszero(xor(result, start)) { break } - } - if temp { - mstore(0x00, 0x2194895a) // `HexLengthInsufficient()`. - revert(0x1c, 0x04) - } - let n := sub(end, result) - result := sub(result, 0x20) - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. - /// As address are 20 bytes long, the output will left-padded to have - /// a length of `20 * 2 + 2` bytes. - function toHexString(uint256 value) internal pure returns (string memory result) { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x". - /// The output excludes leading "0" from the `toHexString` output. - /// `0x00: "0x0", 0x01: "0x1", 0x12: "0x12", 0x123: "0x123"`. - function toMinimalHexString(uint256 value) internal pure returns (string memory result) { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present. - let n := add(mload(result), 2) // Compute the length. - mstore(add(result, o), 0x3078) // Store the "0x" prefix, accounting for leading zero. - result := sub(add(result, o), 2) // Move the pointer, accounting for leading zero. - mstore(result, sub(n, o)) // Store the length, accounting for leading zero. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output excludes leading "0" from the `toHexStringNoPrefix` output. - /// `0x00: "0", 0x01: "1", 0x12: "12", 0x123: "123"`. - function toMinimalHexStringNoPrefix(uint256 value) - internal - pure - returns (string memory result) - { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present. - let n := mload(result) // Get the length. - result := add(result, o) // Move the pointer, accounting for leading zero. - mstore(result, sub(n, o)) // Store the length, accounting for leading zero. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is encoded using 2 hexadecimal digits per byte. - /// As address are 20 bytes long, the output will left-padded to have - /// a length of `20 * 2` bytes. - function toHexStringNoPrefix(uint256 value) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, - // 0x02 bytes for the prefix, and 0x40 bytes for the digits. - // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0. - result := add(mload(0x40), 0x80) - mstore(0x40, add(result, 0x20)) // Allocate memory. - mstore(result, 0) // Zeroize the slot after the string. - - let end := result // Cache the end to calculate the length later. - mstore(0x0f, 0x30313233343536373839616263646566) // Store the "0123456789abcdef" lookup. - - let w := not(1) // Tsk. - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for { let temp := value } 1 {} { - result := add(result, w) // `sub(result, 2)`. - mstore8(add(result, 1), mload(and(temp, 15))) - mstore8(result, mload(and(shr(4, temp), 15))) - temp := shr(8, temp) - if iszero(temp) { break } - } - let n := sub(end, result) - result := sub(result, 0x20) - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte, - /// and the alphabets are capitalized conditionally according to - /// https://eips.ethereum.org/EIPS/eip-55 - function toHexStringChecksummed(address value) internal pure returns (string memory result) { - result = toHexString(value); - /// @solidity memory-safe-assembly - assembly { - let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...` - let o := add(result, 0x22) - let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... ` - let t := shl(240, 136) // `0b10001000 << 240` - for { let i := 0 } 1 {} { - mstore(add(i, i), mul(t, byte(i, hashed))) - i := add(i, 1) - if eq(i, 20) { break } - } - mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask))))) - o := add(o, 0x20) - mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask))))) - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. - function toHexString(address value) internal pure returns (string memory result) { - result = toHexStringNoPrefix(value); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hexadecimal representation of `value`. - /// The output is encoded using 2 hexadecimal digits per byte. - function toHexStringNoPrefix(address value) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - // Allocate memory. - // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, - // 0x02 bytes for the prefix, and 0x28 bytes for the digits. - // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80. - mstore(0x40, add(result, 0x80)) - mstore(0x0f, 0x30313233343536373839616263646566) // Store the "0123456789abcdef" lookup. - - result := add(result, 2) - mstore(result, 40) // Store the length. - let o := add(result, 0x20) - mstore(add(o, 40), 0) // Zeroize the slot after the string. - value := shl(96, value) - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - for { let i := 0 } 1 {} { - let p := add(o, add(i, i)) - let temp := byte(i, value) - mstore8(add(p, 1), mload(and(temp, 15))) - mstore8(p, mload(shr(4, temp))) - i := add(i, 1) - if eq(i, 20) { break } - } - } - } - - /// @dev Returns the hex encoded string from the raw bytes. - /// The output is encoded using 2 hexadecimal digits per byte. - function toHexString(bytes memory raw) internal pure returns (string memory result) { - result = toHexStringNoPrefix(raw); - /// @solidity memory-safe-assembly - assembly { - let n := add(mload(result), 2) // Compute the length. - mstore(result, 0x3078) // Store the "0x" prefix. - result := sub(result, 2) // Move the pointer. - mstore(result, n) // Store the length. - } - } - - /// @dev Returns the hex encoded string from the raw bytes. - /// The output is encoded using 2 hexadecimal digits per byte. - function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(raw) - result := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix. - mstore(result, add(n, n)) // Store the length of the output. - - mstore(0x0f, 0x30313233343536373839616263646566) // Store the "0123456789abcdef" lookup. - let o := add(result, 0x20) - let end := add(raw, n) - for {} iszero(eq(raw, end)) {} { - raw := add(raw, 1) - mstore8(add(o, 1), mload(and(mload(raw), 15))) - mstore8(o, mload(and(shr(4, mload(raw)), 15))) - o := add(o, 2) - } - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* RUNE STRING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of UTF characters in the string. - function runeCount(string memory s) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - if mload(s) { - mstore(0x00, div(not(0), 255)) - mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506) - let o := add(s, 0x20) - let end := add(o, mload(s)) - for { result := 1 } 1 { result := add(result, 1) } { - o := add(o, byte(0, mload(shr(250, mload(o))))) - if iszero(lt(o, end)) { break } - } - } - } - } - - /// @dev Returns if this string is a 7-bit ASCII string. - /// (i.e. all characters codes are in [0..127]) - function is7BitASCII(string memory s) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - let mask := shl(7, div(not(0), 255)) - let n := mload(s) - if n { - let o := add(s, 0x20) - let end := add(o, n) - let last := mload(end) - mstore(end, 0) - for {} 1 {} { - if and(mask, mload(o)) { - result := 0 - break - } - o := add(o, 0x20) - if iszero(lt(o, end)) { break } - } - mstore(end, last) - } - } - } - - /// @dev Returns if this string is a 7-bit ASCII string, - /// AND all characters are in the `allowed` lookup. - /// Note: If `s` is empty, returns true regardless of `allowed`. - function is7BitASCII(string memory s, uint128 allowed) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - if mload(s) { - let allowed_ := shr(128, shl(128, allowed)) - let o := add(s, 0x20) - for { let end := add(o, mload(s)) } 1 {} { - result := and(result, shr(byte(0, mload(o)), allowed_)) - o := add(o, 1) - if iszero(and(result, lt(o, end))) { break } - } - } - } - } - - /// @dev Converts the bytes in the 7-bit ASCII string `s` to - /// an allowed lookup for use in `is7BitASCII(s, allowed)`. - /// To save runtime gas, you can cache the result in an immutable variable. - function to7BitASCIIAllowedLookup(string memory s) internal pure returns (uint128 result) { - /// @solidity memory-safe-assembly - assembly { - if mload(s) { - let o := add(s, 0x20) - for { let end := add(o, mload(s)) } 1 {} { - result := or(result, shl(byte(0, mload(o)), 1)) - o := add(o, 1) - if iszero(lt(o, end)) { break } - } - if shr(128, result) { - mstore(0x00, 0xc9807e0d) // `StringNot7BitASCII()`. - revert(0x1c, 0x04) - } - } - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTE STRING OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // For performance and bytecode compactness, byte string operations are restricted - // to 7-bit ASCII strings. All offsets are byte offsets, not UTF character offsets. - // Usage of byte string operations on charsets with runes spanning two or more bytes - // can lead to undefined behavior. - - /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`. - function replace(string memory subject, string memory needle, string memory replacement) - internal - pure - returns (string memory) - { - return string(LibBytes.replace(bytes(subject), bytes(needle), bytes(replacement))); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(string memory subject, string memory needle, uint256 from) - internal - pure - returns (uint256) - { - return LibBytes.indexOf(bytes(subject), bytes(needle), from); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from left to right. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function indexOf(string memory subject, string memory needle) internal pure returns (uint256) { - return LibBytes.indexOf(bytes(subject), bytes(needle), 0); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left, starting from `from`. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(string memory subject, string memory needle, uint256 from) - internal - pure - returns (uint256) - { - return LibBytes.lastIndexOf(bytes(subject), bytes(needle), from); - } - - /// @dev Returns the byte index of the first location of `needle` in `subject`, - /// needleing from right to left. - /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found. - function lastIndexOf(string memory subject, string memory needle) - internal - pure - returns (uint256) - { - return LibBytes.lastIndexOf(bytes(subject), bytes(needle), type(uint256).max); - } - - /// @dev Returns true if `needle` is found in `subject`, false otherwise. - function contains(string memory subject, string memory needle) internal pure returns (bool) { - return LibBytes.contains(bytes(subject), bytes(needle)); - } - - /// @dev Returns whether `subject` starts with `needle`. - function startsWith(string memory subject, string memory needle) internal pure returns (bool) { - return LibBytes.startsWith(bytes(subject), bytes(needle)); - } - - /// @dev Returns whether `subject` ends with `needle`. - function endsWith(string memory subject, string memory needle) internal pure returns (bool) { - return LibBytes.endsWith(bytes(subject), bytes(needle)); - } - - /// @dev Returns `subject` repeated `times`. - function repeat(string memory subject, uint256 times) internal pure returns (string memory) { - return string(LibBytes.repeat(bytes(subject), times)); - } - - /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive). - /// `start` and `end` are byte offsets. - function slice(string memory subject, uint256 start, uint256 end) - internal - pure - returns (string memory) - { - return string(LibBytes.slice(bytes(subject), start, end)); - } - - /// @dev Returns a copy of `subject` sliced from `start` to the end of the string. - /// `start` is a byte offset. - function slice(string memory subject, uint256 start) internal pure returns (string memory) { - return string(LibBytes.slice(bytes(subject), start, type(uint256).max)); - } - - /// @dev Returns all the indices of `needle` in `subject`. - /// The indices are byte offsets. - function indicesOf(string memory subject, string memory needle) - internal - pure - returns (uint256[] memory) - { - return LibBytes.indicesOf(bytes(subject), bytes(needle)); - } - - /// @dev Returns an arrays of strings based on the `delimiter` inside of the `subject` string. - function split(string memory subject, string memory delimiter) - internal - pure - returns (string[] memory result) - { - bytes[] memory a = LibBytes.split(bytes(subject), bytes(delimiter)); - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - /// @dev Returns a concatenated string of `a` and `b`. - /// Cheaper than `string.concat()` and does not de-align the free memory pointer. - function concat(string memory a, string memory b) internal pure returns (string memory) { - return string(LibBytes.concat(bytes(a), bytes(b))); - } - - /// @dev Returns a copy of the string in either lowercase or UPPERCASE. - /// WARNING! This function is only compatible with 7-bit ASCII strings. - function toCase(string memory subject, bool toUpper) - internal - pure - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(subject) - if n { - result := mload(0x40) - let o := add(result, 0x20) - let d := sub(subject, result) - let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff) - for { let end := add(o, n) } 1 {} { - let b := byte(0, mload(add(d, o))) - mstore8(o, xor(and(shr(b, flags), 0x20), b)) - o := add(o, 1) - if eq(o, end) { break } - } - mstore(result, n) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - } - - /// @dev Returns a string from a small bytes32 string. - /// `s` must be null-terminated, or behavior will be undefined. - function fromSmallString(bytes32 s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let n := 0 - for {} byte(n, s) { n := add(n, 1) } {} // Scan for '\0'. - mstore(result, n) // Store the length. - let o := add(result, 0x20) - mstore(o, s) // Store the bytes of the string. - mstore(add(o, n), 0) // Zeroize the slot after the string. - mstore(0x40, add(result, 0x40)) // Allocate memory. - } - } - - /// @dev Returns the small string, with all bytes after the first null byte zeroized. - function normalizeSmallString(bytes32 s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - for {} byte(result, s) { result := add(result, 1) } {} // Scan for '\0'. - mstore(0x00, s) - mstore(result, 0x00) - result := mload(0x00) - } - } - - /// @dev Returns the string as a normalized null-terminated small string. - function toSmallString(string memory s) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(s) - if iszero(lt(result, 33)) { - mstore(0x00, 0xec92f9a3) // `TooBigForSmallString()`. - revert(0x1c, 0x04) - } - result := shl(shl(3, sub(32, result)), mload(add(s, result))) - } - } - - /// @dev Returns a lowercased copy of the string. - /// WARNING! This function is only compatible with 7-bit ASCII strings. - function lower(string memory subject) internal pure returns (string memory result) { - result = toCase(subject, false); - } - - /// @dev Returns an UPPERCASED copy of the string. - /// WARNING! This function is only compatible with 7-bit ASCII strings. - function upper(string memory subject) internal pure returns (string memory result) { - result = toCase(subject, true); - } - - /// @dev Escapes the string to be used within HTML tags. - function escapeHTML(string memory s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let end := add(s, mload(s)) - let o := add(result, 0x20) - // Store the bytes of the packed offsets and strides into the scratch space. - // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6. - mstore(0x1f, 0x900094) - mstore(0x08, 0xc0000000a6ab) - // Store ""&'<>" into the scratch space. - mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b)) - for {} iszero(eq(s, end)) {} { - s := add(s, 1) - let c := and(mload(s), 0xff) - // Not in `["\"","'","&","<",">"]`. - if iszero(and(shl(c, 1), 0x500000c400000000)) { - mstore8(o, c) - o := add(o, 1) - continue - } - let t := shr(248, mload(c)) - mstore(o, mload(and(t, 0x1f))) - o := add(o, shr(5, t)) - } - mstore(o, 0) // Zeroize the slot after the string. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /// @dev Escapes the string to be used within double-quotes in a JSON. - /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes. - function escapeJSON(string memory s, bool addDoubleQuotes) - internal - pure - returns (string memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let o := add(result, 0x20) - if addDoubleQuotes { - mstore8(o, 34) - o := add(1, o) - } - // Store "\\u0000" in scratch space. - // Store "0123456789abcdef" in scratch space. - // Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`. - // into the scratch space. - mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672) - // Bitmask for detecting `["\"","\\"]`. - let e := or(shl(0x22, 1), shl(0x5c, 1)) - for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} { - s := add(s, 1) - let c := and(mload(s), 0xff) - if iszero(lt(c, 0x20)) { - if iszero(and(shl(c, 1), e)) { - // Not in `["\"","\\"]`. - mstore8(o, c) - o := add(o, 1) - continue - } - mstore8(o, 0x5c) // "\\". - mstore8(add(o, 1), c) - o := add(o, 2) - continue - } - if iszero(and(shl(c, 1), 0x3700)) { - // Not in `["\b","\t","\n","\f","\d"]`. - mstore8(0x1d, mload(shr(4, c))) // Hex value. - mstore8(0x1e, mload(and(c, 15))) // Hex value. - mstore(o, mload(0x19)) // "\\u00XX". - o := add(o, 6) - continue - } - mstore8(o, 0x5c) // "\\". - mstore8(add(o, 1), mload(add(c, 8))) - o := add(o, 2) - } - if addDoubleQuotes { - mstore8(o, 34) - o := add(1, o) - } - mstore(o, 0) // Zeroize the slot after the string. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /// @dev Escapes the string to be used within double-quotes in a JSON. - function escapeJSON(string memory s) internal pure returns (string memory result) { - result = escapeJSON(s, false); - } - - /// @dev Encodes `s` so that it can be safely used in a URI, - /// just like `encodeURIComponent` in JavaScript. - /// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent - /// See: https://datatracker.ietf.org/doc/html/rfc2396 - /// See: https://datatracker.ietf.org/doc/html/rfc3986 - function encodeURIComponent(string memory s) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - // Store "0123456789ABCDEF" in scratch space. - // Uppercased to be consistent with JavaScript's implementation. - mstore(0x0f, 0x30313233343536373839414243444546) - let o := add(result, 0x20) - for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} { - s := add(s, 1) - let c := and(mload(s), 0xff) - // If not in `[0-9A-Z-a-z-_.!~*'()]`. - if iszero(and(1, shr(c, 0x47fffffe87fffffe03ff678200000000))) { - mstore8(o, 0x25) // '%'. - mstore8(add(o, 1), mload(and(shr(4, c), 15))) - mstore8(add(o, 2), mload(and(c, 15))) - o := add(o, 3) - continue - } - mstore8(o, c) - o := add(o, 1) - } - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate memory. - } - } - - /// @dev Returns whether `a` equals `b`. - function eq(string memory a, string memory b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b))) - } - } - - /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small string. - function eqs(string memory a, bytes32 b) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - // These should be evaluated on compile time, as far as possible. - let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`. - let x := not(or(m, or(b, add(m, and(b, m))))) - let r := shl(7, iszero(iszero(shr(128, x)))) - r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x)))))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - // forgefmt: disable-next-item - result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))), - xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20))))) - } - } - - /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`. - /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1. - function cmp(string memory a, string memory b) internal pure returns (int256) { - return LibBytes.cmp(bytes(a), bytes(b)); - } - - /// @dev Packs a single string with its length into a single word. - /// Returns `bytes32(0)` if the length is zero or greater than 31. - function packOne(string memory a) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - // We don't need to zero right pad the string, - // since this is our own custom non-standard packing scheme. - result := - mul( - // Load the length and the bytes. - mload(add(a, 0x1f)), - // `length != 0 && length < 32`. Abuses underflow. - // Assumes that the length is valid and within the block gas limit. - lt(sub(mload(a), 1), 0x1f) - ) - } - } - - /// @dev Unpacks a string packed using {packOne}. - /// Returns the empty string if `packed` is `bytes32(0)`. - /// If `packed` is not an output of {packOne}, the output behavior is undefined. - function unpackOne(bytes32 packed) internal pure returns (string memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) // Grab the free memory pointer. - mstore(0x40, add(result, 0x40)) // Allocate 2 words (1 for the length, 1 for the bytes). - mstore(result, 0) // Zeroize the length slot. - mstore(add(result, 0x1f), packed) // Store the length and bytes. - mstore(add(add(result, 0x20), mload(result)), 0) // Right pad with zeroes. - } - } - - /// @dev Packs two strings with their lengths into a single word. - /// Returns `bytes32(0)` if combined length is zero or greater than 30. - function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let aLen := mload(a) - // We don't need to zero right pad the strings, - // since this is our own custom non-standard packing scheme. - result := - mul( - or( // Load the length and the bytes of `a` and `b`. - shl(shl(3, sub(0x1f, aLen)), mload(add(a, aLen))), mload(sub(add(b, 0x1e), aLen))), - // `totalLen != 0 && totalLen < 31`. Abuses underflow. - // Assumes that the lengths are valid and within the block gas limit. - lt(sub(add(aLen, mload(b)), 1), 0x1e) - ) - } - } - - /// @dev Unpacks strings packed using {packTwo}. - /// Returns the empty strings if `packed` is `bytes32(0)`. - /// If `packed` is not an output of {packTwo}, the output behavior is undefined. - function unpackTwo(bytes32 packed) - internal - pure - returns (string memory resultA, string memory resultB) - { - /// @solidity memory-safe-assembly - assembly { - resultA := mload(0x40) // Grab the free memory pointer. - resultB := add(resultA, 0x40) - // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words. - mstore(0x40, add(resultB, 0x40)) - // Zeroize the length slots. - mstore(resultA, 0) - mstore(resultB, 0) - // Store the lengths and bytes. - mstore(add(resultA, 0x1f), packed) - mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA)))) - // Right pad with zeroes. - mstore(add(add(resultA, 0x20), mload(resultA)), 0) - mstore(add(add(resultB, 0x20), mload(resultB)), 0) - } - } - - /// @dev Directly returns `a` without copying. - function directReturn(string memory a) internal pure { - /// @solidity memory-safe-assembly - assembly { - // Assumes that the string does not start from the scratch space. - let retStart := sub(a, 0x20) - let retUnpaddedSize := add(mload(a), 0x40) - // Right pad with zeroes. Just in case the string is produced - // by a method that doesn't zero right pad. - mstore(add(retStart, retUnpaddedSize), 0) - mstore(retStart, 0x20) // Store the return offset. - // End the transaction, returning the string. - return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize))) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/LibTransient.sol b/grouperBot/lib/solady/src/utils/g/LibTransient.sol deleted file mode 100644 index 23b53a9..0000000 --- a/grouperBot/lib/solady/src/utils/g/LibTransient.sol +++ /dev/null @@ -1,973 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev Pointer struct to a `uint256` in transient storage. -struct TUint256 { - uint256 _spacer; -} - -/// @dev Pointer struct to a `int256` in transient storage. -struct TInt256 { - uint256 _spacer; -} - -/// @dev Pointer struct to a `bytes32` in transient storage. -struct TBytes32 { - uint256 _spacer; -} - -/// @dev Pointer struct to a `address` in transient storage. -struct TAddress { - uint256 _spacer; -} - -/// @dev Pointer struct to a `bool` in transient storage. -struct TBool { - uint256 _spacer; -} - -/// @dev Pointer struct to a `bytes` in transient storage. -struct TBytes { - uint256 _spacer; -} - -/// @dev Pointer struct to a stack pointer generator in transient storage. -/// This stack does not directly take in values. Instead, it generates pointers -/// that can be casted to any of the other transient storage pointer struct. -struct TStack { - uint256 _spacer; -} - -using LibTransient for TUint256 global; -using LibTransient for TInt256 global; -using LibTransient for TBytes32 global; -using LibTransient for TAddress global; -using LibTransient for TBool global; -using LibTransient for TBytes global; -using LibTransient for TStack global; - -/// @notice Library for transient storage operations. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/LibTransient.sol) -/// @author Modified from Transient Goodies by Philogy (https://github.com/Philogy/transient-goodies/blob/main/src/TransientBytesLib.sol) -/// -/// @dev Note: The functions postfixed with `Compat` will only use transient storage on L1. -/// L2s are super cheap anyway. -/// For best safety, always clear the storage after use. -library LibTransient { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The transient stack is empty. - error StackIsEmpty(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CONSTANTS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The storage slot seed for converting a transient slot to a storage slot. - /// `bytes4(keccak256("_LIB_TRANSIENT_COMPAT_SLOT_SEED"))`. - uint256 private constant _LIB_TRANSIENT_COMPAT_SLOT_SEED = 0x5a0b45f2; - - /// @dev Multiplier to stack base slot, so that in the case where two stacks - /// share consecutive base slots, their pointers will likely not overlap. A prime. - uint256 private constant _STACK_BASE_SALT = 0x9e076501211e1371b; - - /// @dev The canonical address of the transient registry. - /// See: https://gist.github.com/Vectorized/4ab665d7a234ef5aaaff2e5091ec261f - address internal constant REGISTRY = 0x000000000000297f64C7F8d9595e43257908F170; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* UINT256 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `uint256` in transient storage. - function tUint256(bytes32 tSlot) internal pure returns (TUint256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `uint256` in transient storage. - function tUint256(uint256 tSlot) internal pure returns (TUint256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TUint256 storage ptr) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TUint256 storage ptr) internal view returns (uint256 result) { - result = block.chainid == 1 ? get(ptr) : _compat(ptr)._spacer; - } - - /// @dev Sets the value at transient `ptr`. - function set(TUint256 storage ptr, uint256 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, value) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TUint256 storage ptr, uint256 value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = value; - } - - /// @dev Clears the value at transient `ptr`. - function clear(TUint256 storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TUint256 storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /// @dev Increments the value at transient `ptr` by 1. - function inc(TUint256 storage ptr) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by 1. - function incCompat(TUint256 storage ptr) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function inc(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) + delta); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incCompat(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + delta); - } - - /// @dev Decrements the value at transient `ptr` by 1. - function dec(TUint256 storage ptr) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decCompat(TUint256 storage ptr) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function dec(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - set(ptr, newValue = get(ptr) - delta); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decCompat(TUint256 storage ptr, uint256 delta) internal returns (uint256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - delta); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incSigned(TUint256 storage ptr, int256 delta) internal returns (uint256 newValue) { - /// @solidity memory-safe-assembly - assembly { - let currentValue := tload(ptr.slot) - newValue := add(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), slt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - tstore(ptr.slot, newValue) - } - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incSignedCompat(TUint256 storage ptr, int256 delta) - internal - returns (uint256 newValue) - { - if (block.chainid == 1) return incSigned(ptr, delta); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - let currentValue := sload(ptr.slot) - newValue := add(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), slt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - sstore(ptr.slot, newValue) - } - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decSigned(TUint256 storage ptr, int256 delta) internal returns (uint256 newValue) { - /// @solidity memory-safe-assembly - assembly { - let currentValue := tload(ptr.slot) - newValue := sub(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), sgt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - tstore(ptr.slot, newValue) - } - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decSignedCompat(TUint256 storage ptr, int256 delta) - internal - returns (uint256 newValue) - { - if (block.chainid == 1) return decSigned(ptr, delta); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - let currentValue := sload(ptr.slot) - newValue := sub(currentValue, delta) - if iszero(eq(lt(newValue, currentValue), sgt(delta, 0))) { - mstore(0x00, 0x4e487b71) // `Panic(uint256)`. - mstore(0x20, 0x11) // Underflow or overflow panic. - revert(0x1c, 0x24) - } - sstore(ptr.slot, newValue) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* INT256 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `int256` in transient storage. - function tInt256(bytes32 tSlot) internal pure returns (TInt256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `int256` in transient storage. - function tInt256(uint256 tSlot) internal pure returns (TInt256 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TInt256 storage ptr) internal view returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TInt256 storage ptr) internal view returns (int256 result) { - result = block.chainid == 1 ? get(ptr) : int256(_compat(ptr)._spacer); - } - - /// @dev Sets the value at transient `ptr`. - function set(TInt256 storage ptr, int256 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, value) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TInt256 storage ptr, int256 value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = uint256(value); - } - - /// @dev Clears the value at transient `ptr`. - function clear(TInt256 storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TInt256 storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /// @dev Increments the value at transient `ptr` by 1. - function inc(TInt256 storage ptr) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by 1. - function incCompat(TInt256 storage ptr) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + 1); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function inc(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) + delta); - } - - /// @dev Increments the value at transient `ptr` by `delta`. - function incCompat(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) + delta); - } - - /// @dev Decrements the value at transient `ptr` by 1. - function dec(TInt256 storage ptr) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by 1. - function decCompat(TInt256 storage ptr) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - 1); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function dec(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - set(ptr, newValue = get(ptr) - delta); - } - - /// @dev Decrements the value at transient `ptr` by `delta`. - function decCompat(TInt256 storage ptr, int256 delta) internal returns (int256 newValue) { - setCompat(ptr, newValue = getCompat(ptr) - delta); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTES32 OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `bytes32` in transient storage. - function tBytes32(bytes32 tSlot) internal pure returns (TBytes32 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `bytes32` in transient storage. - function tBytes32(uint256 tSlot) internal pure returns (TBytes32 storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TBytes32 storage ptr) internal view returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TBytes32 storage ptr) internal view returns (bytes32 result) { - result = block.chainid == 1 ? get(ptr) : bytes32(_compat(ptr)._spacer); - } - - /// @dev Sets the value at transient `ptr`. - function set(TBytes32 storage ptr, bytes32 value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, value) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TBytes32 storage ptr, bytes32 value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = uint256(value); - } - - /// @dev Clears the value at transient `ptr`. - function clear(TBytes32 storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TBytes32 storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ADDRESS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `address` in transient storage. - function tAddress(bytes32 tSlot) internal pure returns (TAddress storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `address` in transient storage. - function tAddress(uint256 tSlot) internal pure returns (TAddress storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TAddress storage ptr) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TAddress storage ptr) internal view returns (address result) { - result = block.chainid == 1 ? get(ptr) : address(uint160(_compat(ptr)._spacer)); - } - - /// @dev Sets the value at transient `ptr`. - function set(TAddress storage ptr, address value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, shr(96, shl(96, value))) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TAddress storage ptr, address value) internal { - if (block.chainid == 1) return set(ptr, value); - _compat(ptr)._spacer = uint160(value); - } - - /// @dev Clears the value at transient `ptr`. - function clear(TAddress storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TAddress storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BOOL OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `bool` in transient storage. - function tBool(bytes32 tSlot) internal pure returns (TBool storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `bool` in transient storage. - function tBool(uint256 tSlot) internal pure returns (TBool storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the value at transient `ptr`. - function get(TBool storage ptr) internal view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := tload(ptr.slot) - } - } - - /// @dev Returns the value at transient `ptr`. - function getCompat(TBool storage ptr) internal view returns (bool result) { - result = block.chainid == 1 ? get(ptr) : _compat(ptr)._spacer != 0; - } - - /// @dev Sets the value at transient `ptr`. - function set(TBool storage ptr, bool value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, iszero(iszero(value))) - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TBool storage ptr, bool value) internal { - if (block.chainid == 1) return set(ptr, value); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - sstore(ptr.slot, iszero(iszero(value))) - } - } - - /// @dev Clears the value at transient `ptr`. - function clear(TBool storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TBool storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* BYTES OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a `bytes` in transient storage. - function tBytes(bytes32 tSlot) internal pure returns (TBytes storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a `bytes` in transient storage. - function tBytes(uint256 tSlot) internal pure returns (TBytes storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the length of the bytes stored at transient `ptr`. - function length(TBytes storage ptr) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(224, tload(ptr.slot)) - } - } - - /// @dev Returns the length of the bytes stored at transient `ptr`. - function lengthCompat(TBytes storage ptr) internal view returns (uint256 result) { - if (block.chainid == 1) return length(ptr); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - result := shr(224, sload(ptr.slot)) - } - } - - /// @dev Returns the bytes stored at transient `ptr`. - function get(TBytes storage ptr) internal view returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 0x00) - mstore(add(result, 0x1c), tload(ptr.slot)) // Length and first `0x1c` bytes. - let n := mload(result) - let e := add(add(result, 0x20), n) - if iszero(lt(n, 0x1d)) { - mstore(0x00, ptr.slot) - let d := sub(keccak256(0x00, 0x20), result) - for { let o := add(result, 0x3c) } 1 {} { - mstore(o, tload(add(o, d))) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - mstore(e, 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, e)) // Allocate memory. - } - } - - /// @dev Returns the bytes stored at transient `ptr`. - function getCompat(TBytes storage ptr) internal view returns (bytes memory result) { - if (block.chainid == 1) return get(ptr); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, 0x00) - mstore(add(result, 0x1c), sload(ptr.slot)) // Length and first `0x1c` bytes. - let n := mload(result) - let e := add(add(result, 0x20), n) - if iszero(lt(n, 0x1d)) { - mstore(0x00, ptr.slot) - let d := sub(keccak256(0x00, 0x20), result) - for { let o := add(result, 0x3c) } 1 {} { - mstore(o, sload(add(o, d))) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - mstore(e, 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, e)) // Allocate memory. - } - } - - /// @dev Sets the value at transient `ptr`. - function set(TBytes storage ptr, bytes memory value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, mload(add(value, 0x1c))) - if iszero(lt(mload(value), 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(add(value, 0x20), mload(value)) - let d := sub(keccak256(0x00, or(0x20, sub(0, shr(32, mload(value))))), value) - for { let o := add(value, 0x3c) } 1 {} { - tstore(add(o, d), mload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Sets the value at transient `ptr`. - function setCompat(TBytes storage ptr, bytes memory value) internal { - if (block.chainid == 1) return set(ptr, value); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - sstore(ptr.slot, mload(add(value, 0x1c))) - if iszero(lt(mload(value), 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(add(value, 0x20), mload(value)) - let d := sub(keccak256(0x00, or(0x20, sub(0, shr(32, mload(value))))), value) - for { let o := add(value, 0x3c) } 1 {} { - sstore(add(o, d), mload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Sets the value at transient `ptr`. - function setCalldata(TBytes storage ptr, bytes calldata value) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, or(shl(224, value.length), shr(32, calldataload(value.offset)))) - if iszero(lt(value.length, 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(value.offset, value.length) - // forgefmt: disable-next-item - let d := add(sub(keccak256(0x00, or(0x20, sub(0, shr(32, value.length)))), - value.offset), 0x20) - for { let o := add(value.offset, 0x1c) } 1 {} { - tstore(add(o, d), calldataload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Sets the value at transient `ptr`. - function setCalldataCompat(TBytes storage ptr, bytes calldata value) internal { - if (block.chainid == 1) return setCalldata(ptr, value); - ptr = _compat(ptr); - /// @solidity memory-safe-assembly - assembly { - sstore(ptr.slot, or(shl(224, value.length), shr(32, calldataload(value.offset)))) - if iszero(lt(value.length, 0x1d)) { - mstore(0x00, ptr.slot) - let e := add(value.offset, value.length) - // forgefmt: disable-next-item - let d := add(sub(keccak256(0x00, or(0x20, sub(0, shr(32, value.length)))), - value.offset), 0x20) - for { let o := add(value.offset, 0x1c) } 1 {} { - sstore(add(o, d), calldataload(o)) - o := add(o, 0x20) - if iszero(lt(o, e)) { break } - } - } - } - } - - /// @dev Clears the value at transient `ptr`. - function clear(TBytes storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - tstore(ptr.slot, 0) - } - } - - /// @dev Clears the value at transient `ptr`. - function clearCompat(TBytes storage ptr) internal { - if (block.chainid == 1) return clear(ptr); - _compat(ptr)._spacer = 0; - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* STACK OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a pointer to a stack in transient storage. - function tStack(bytes32 tSlot) internal pure returns (TStack storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns a pointer to a stack in transient storage. - function tStack(uint256 tSlot) internal pure returns (TStack storage ptr) { - /// @solidity memory-safe-assembly - assembly { - ptr.slot := tSlot - } - } - - /// @dev Returns the number of elements in the stack. - function length(TStack storage ptr) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(160, shl(128, tload(ptr.slot))) // Removes the base offset and stride. - } - } - - /// @dev Clears the stack at `ptr`. - /// Note: Future usage of the stack will point to a fresh transient storage region. - function clear(TStack storage ptr) internal { - /// @solidity memory-safe-assembly - assembly { - // Clears the length and increments the base pointer by `1 << 128`. - tstore(ptr.slot, shl(128, add(1, shr(128, tload(ptr.slot))))) - } - } - - /// @dev Increments the stack length by 1, and returns a pointer to the top element. - /// We don't want to call this `push` as it does not take in an element value. - /// Note: The value pointed to might not be cleared from previous usage. - function place(TStack storage ptr) internal returns (bytes32 topPtr) { - /// @solidity memory-safe-assembly - assembly { - topPtr := add(0x100000000, tload(ptr.slot)) // Increments by a stride. - tstore(ptr.slot, topPtr) - topPtr := add(mul(_STACK_BASE_SALT, ptr.slot), topPtr) - } - } - - /// @dev Returns a pointer to the top element. Returns the zero pointer if the stack is empty. - /// This method can help avoid an additional `TLOAD`, but you MUST check if the - /// returned pointer is zero. And if it is, please DO NOT read / write to it. - function peek(TStack storage ptr) internal view returns (bytes32 topPtr) { - /// @solidity memory-safe-assembly - assembly { - let t := tload(ptr.slot) - topPtr := mul(iszero(iszero(shl(128, t))), add(mul(_STACK_BASE_SALT, ptr.slot), t)) - } - } - - /// @dev Returns a pointer to the top element. Reverts if the stack is empty. - function top(TStack storage ptr) internal view returns (bytes32 topPtr) { - /// @solidity memory-safe-assembly - assembly { - topPtr := tload(ptr.slot) - if iszero(topPtr) { - mstore(0x00, 0xbb704e21) // `StackIsEmpty()`. - revert(0x1c, 0x04) - } - topPtr := add(mul(_STACK_BASE_SALT, ptr.slot), topPtr) - } - } - - /// @dev Decrements the stack length by 1, returns a pointer to the top element - /// before the popping. Reverts if the stack is empty. - /// Note: Popping from the stack does NOT auto-clear the top value. - function pop(TStack storage ptr) internal returns (bytes32 lastTopPtr) { - /// @solidity memory-safe-assembly - assembly { - lastTopPtr := tload(ptr.slot) - if iszero(lastTopPtr) { - mstore(0x00, 0xbb704e21) // `StackIsEmpty()`. - revert(0x1c, 0x04) - } - tstore(ptr.slot, sub(lastTopPtr, 0x100000000)) // Decrements by a stride. - lastTopPtr := add(mul(_STACK_BASE_SALT, ptr.slot), lastTopPtr) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* TRANSIENT REGISTRY OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Sets the value for the key. - /// If the key does not exist, its admin will be set to the caller. - /// If the key already exist, its value will be overwritten, - /// and the caller must be the current admin for the key. - /// Reverts with empty data if the registry has not been deployed. - function registrySet(bytes32 key, bytes memory value) internal { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, 0xaac438c0) // `set(bytes32,bytes)`. - mstore(add(m, 0x20), key) - mstore(add(m, 0x40), 0x40) - let n := mload(value) - mstore(add(m, 0x60), n) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(m, 0x80), i), mload(add(add(value, 0x20), i))) - } - if iszero( - mul( - returndatasize(), - call(gas(), REGISTRY, 0, add(m, 0x1c), add(n, 0x64), 0x00, 0x20) - ) - ) { revert(0x00, returndatasize()) } - } - } - - /// @dev Returns the value for the key. - /// Reverts if the key does not exist. - /// Reverts with empty data if the registry has not been deployed. - function registryGet(bytes32 key) internal view returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x00, 0x8eaa6ac0) // `get(bytes32)`. - mstore(0x20, key) - if iszero(mul(returndatasize(), staticcall(gas(), REGISTRY, 0x1c, 0x24, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - // We can safely assume that the bytes will be containing the 0x20 offset. - returndatacopy(result, 0x20, sub(returndatasize(), 0x20)) - mstore(0x40, add(result, returndatasize())) // Allocate memory. - } - } - - /// @dev Clears the admin and the value for the key. - /// The caller must be the current admin of the key. - /// Reverts with empty data if the registry has not been deployed. - function registryClear(bytes32 key) internal { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x97040a45) // `clear(bytes32)`. - mstore(0x20, key) - if iszero(mul(returndatasize(), call(gas(), REGISTRY, 0, 0x1c, 0x24, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - } - } - - /// @dev Returns the admin of the key. - /// Returns `address(0)` if the key does not exist. - /// Reverts with empty data if the registry has not been deployed. - function registryAdminOf(bytes32 key) internal view returns (address result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xc5344411) // `adminOf(bytes32)`. - mstore(0x20, key) - if iszero(mul(returndatasize(), staticcall(gas(), REGISTRY, 0x1c, 0x24, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - result := mload(0x00) - } - } - - /// @dev Changes the admin of the key. - /// The caller must be the current admin of the key. - /// The new admin must not be `address(0)`. - /// Reverts with empty data if the registry has not been deployed. - function registryChangeAdmin(bytes32 key, address newAdmin) internal { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, 0x053b1ca3) // `changeAdmin(bytes32,address)`. - mstore(0x20, key) - mstore(0x40, shr(96, shl(96, newAdmin))) - if iszero(mul(returndatasize(), call(gas(), REGISTRY, 0, 0x1c, 0x44, 0x00, 0x20))) { - revert(0x00, returndatasize()) - } - mstore(0x40, m) // Restore the free memory pointer. - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TUint256 storage ptr) private pure returns (TUint256 storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TInt256 storage ptr) private pure returns (TInt256 storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TBytes32 storage ptr) private pure returns (TBytes32 storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TAddress storage ptr) private pure returns (TAddress storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TBool storage ptr) private pure returns (TBool storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } - - /// @dev Returns a regular storage pointer used for compatibility. - function _compat(TBytes storage ptr) private pure returns (TBytes storage c) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x04, _LIB_TRANSIENT_COMPAT_SLOT_SEED) - mstore(0x00, ptr.slot) - c.slot := keccak256(0x00, 0x24) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/MinHeapLib.sol b/grouperBot/lib/solady/src/utils/g/MinHeapLib.sol deleted file mode 100644 index fe80d0a..0000000 --- a/grouperBot/lib/solady/src/utils/g/MinHeapLib.sol +++ /dev/null @@ -1,581 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev A heap in storage. -struct Heap { - uint256[] data; -} - -/// @dev A heap in memory. -struct MemHeap { - uint256[] data; -} - -using MinHeapLib for Heap global; -using MinHeapLib for MemHeap global; - -/// @notice Library for managing a min-heap in storage or memory. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/MinHeapLib.sol) -library MinHeapLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The heap is empty. - error HeapIsEmpty(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Tips: - // - To use as a max-heap, bitwise negate the input and output values (e.g. `heap.push(~x)`). - // - To use on tuples, pack the tuple values into a single integer. - // - To use on signed integers, convert the signed integers into - // their ordered unsigned counterparts via `uint256(x) + (1 << 255)`. - - /// @dev Returns the minimum value of the heap. - /// Reverts if the heap is empty. - function root(Heap storage heap) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - if iszero(sload(heap.slot)) { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } - mstore(0x00, heap.slot) - result := sload(keccak256(0x00, 0x20)) - } - } - - /// @dev Returns the minimum value of the heap. - /// Reverts if the heap is empty. - function root(MemHeap memory heap) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(heap) - if iszero(mload(result)) { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } - result := mload(add(0x20, result)) - } - } - - /// @dev Reserves at least `minimum` slots of memory for the heap. - /// Helps avoid reallocation if you already know the max size of the heap. - function reserve(MemHeap memory heap, uint256 minimum) internal pure { - /// @solidity memory-safe-assembly - assembly { - let w := not(0x1f) - let prime := 204053801631428327883786711931463459222251954273621 - let cap := not(mload(add(mload(heap), w))) - if gt(minimum, mul(iszero(mod(cap, prime)), div(cap, prime))) { - let data := mload(heap) - let n := mload(data) - let newCap := and(add(minimum, 0x1f), w) // Round up to multiple of 32. - mstore(mload(0x40), not(mul(newCap, prime))) - let m := add(mload(0x40), 0x20) - mstore(m, n) // Store the length. - mstore(0x40, add(add(m, 0x20), shl(5, newCap))) // Allocate `heap.data` memory. - mstore(heap, m) // Update `heap.data`. - if n { - for { let i := shl(5, n) } 1 {} { - mstore(add(m, i), mload(add(data, i))) - i := add(i, w) - if iszero(i) { break } - } - } - } - } - } - - /// @dev Returns an array of the `k` smallest items in the heap, - /// sorted in ascending order, without modifying the heap. - /// If the heap has less than `k` items, all items in the heap will be returned. - function smallest(Heap storage heap, uint256 k) internal view returns (uint256[] memory a) { - /// @solidity memory-safe-assembly - assembly { - function pIndex(h_, p_) -> _i { - _i := mload(add(0x20, add(h_, shl(6, p_)))) - } - function pValue(h_, p_) -> _v { - _v := mload(add(h_, shl(6, p_))) - } - function pSet(h_, p_, i_, v_) { - mstore(add(h_, shl(6, p_)), v_) - mstore(add(0x20, add(h_, shl(6, p_))), i_) - } - function pSiftdown(h_, p_, i_, v_) { - for {} 1 {} { - let u_ := shr(1, sub(p_, 1)) - if iszero(mul(p_, lt(v_, pValue(h_, u_)))) { break } - pSet(h_, p_, pIndex(h_, u_), pValue(h_, u_)) - p_ := u_ - } - pSet(h_, p_, i_, v_) - } - function pSiftup(h_, e_, i_, v_) { - let p_ := 0 - for { let c_ := 1 } lt(c_, e_) { c_ := add(1, shl(1, p_)) } { - c_ := add(c_, gt(pValue(h_, c_), pValue(h_, add(c_, lt(add(c_, 1), e_))))) - pSet(h_, p_, pIndex(h_, c_), pValue(h_, c_)) - p_ := c_ - } - pSiftdown(h_, p_, i_, v_) - } - a := mload(0x40) - mstore(0x00, heap.slot) - let sOffset := keccak256(0x00, 0x20) - let o := add(a, 0x20) // Offset into `a`. - let n := sload(heap.slot) // The number of items in the heap. - let m := xor(n, mul(xor(n, k), lt(k, n))) // `min(k, n)`. - let h := add(o, shl(5, m)) // Priority queue. - pSet(h, 0, 0, sload(sOffset)) // Store the root into the priority queue. - for { let e := iszero(eq(o, h)) } e {} { - mstore(o, pValue(h, 0)) - o := add(0x20, o) - if eq(o, h) { break } - let childPos := add(shl(1, pIndex(h, 0)), 1) - if iszero(lt(childPos, n)) { - e := sub(e, 1) - pSiftup(h, e, pIndex(h, e), pValue(h, e)) - continue - } - pSiftup(h, e, childPos, sload(add(sOffset, childPos))) - childPos := add(1, childPos) - if iszero(eq(childPos, n)) { - pSiftdown(h, e, childPos, sload(add(sOffset, childPos))) - e := add(e, 1) - } - } - mstore(a, shr(5, sub(o, add(a, 0x20)))) // Store the length. - mstore(0x40, o) // Allocate memory. - } - } - - /// @dev Returns an array of the `k` smallest items in the heap, - /// sorted in ascending order, without modifying the heap. - /// If the heap has less than `k` items, all items in the heap will be returned. - function smallest(MemHeap memory heap, uint256 k) internal pure returns (uint256[] memory a) { - /// @solidity memory-safe-assembly - assembly { - function pIndex(h_, p_) -> _i { - _i := mload(add(0x20, add(h_, shl(6, p_)))) - } - function pValue(h_, p_) -> _v { - _v := mload(add(h_, shl(6, p_))) - } - function pSet(h_, p_, i_, v_) { - mstore(add(h_, shl(6, p_)), v_) - mstore(add(0x20, add(h_, shl(6, p_))), i_) - } - function pSiftdown(h_, p_, i_, v_) { - for {} 1 {} { - let u_ := shr(1, sub(p_, 1)) - if iszero(mul(p_, lt(v_, pValue(h_, u_)))) { break } - pSet(h_, p_, pIndex(h_, u_), pValue(h_, u_)) - p_ := u_ - } - pSet(h_, p_, i_, v_) - } - function pSiftup(h_, e_, i_, v_) { - let p_ := 0 - for { let c_ := 1 } lt(c_, e_) { c_ := add(1, shl(1, p_)) } { - c_ := add(c_, gt(pValue(h_, c_), pValue(h_, add(c_, lt(add(c_, 1), e_))))) - pSet(h_, p_, pIndex(h_, c_), pValue(h_, c_)) - p_ := c_ - } - pSiftdown(h_, p_, i_, v_) - } - a := mload(0x40) - let sOffset := add(mload(heap), 0x20) - let o := add(a, 0x20) // Offset into `a`. - let n := mload(mload(heap)) // The number of items in the heap. - let m := xor(n, mul(xor(n, k), lt(k, n))) // `min(k, n)`. - let h := add(o, shl(5, m)) // Priority queue. - pSet(h, 0, 0, mload(sOffset)) // Store the root into the priority queue. - for { let e := iszero(eq(o, h)) } e {} { - mstore(o, pValue(h, 0)) - o := add(0x20, o) - if eq(o, h) { break } - let childPos := add(shl(1, pIndex(h, 0)), 1) - if iszero(lt(childPos, n)) { - e := sub(e, 1) - pSiftup(h, e, pIndex(h, e), pValue(h, e)) - continue - } - pSiftup(h, e, childPos, mload(add(sOffset, shl(5, childPos)))) - childPos := add(1, childPos) - if iszero(eq(childPos, n)) { - pSiftdown(h, e, childPos, mload(add(sOffset, shl(5, childPos)))) - e := add(e, 1) - } - } - mstore(a, shr(5, sub(o, add(a, 0x20)))) // Store the length. - mstore(0x40, o) // Allocate memory. - } - } - - /// @dev Returns the number of items in the heap. - function length(Heap storage heap) internal view returns (uint256) { - return heap.data.length; - } - - /// @dev Returns the number of items in the heap. - function length(MemHeap memory heap) internal pure returns (uint256) { - return heap.data.length; - } - - /// @dev Pushes the `value` onto the min-heap. - function push(Heap storage heap, uint256 value) internal { - _set(heap, value, 0, 3); - } - - /// @dev Pushes the `value` onto the min-heap. - function push(MemHeap memory heap, uint256 value) internal pure { - _set(heap, value, 0, 3); - } - - /// @dev Pops the minimum value from the min-heap. - /// Reverts if the heap is empty. - function pop(Heap storage heap) internal returns (uint256 popped) { - (, popped) = _set(heap, 0, 0, 2); - } - - /// @dev Pops the minimum value from the min-heap. - /// Reverts if the heap is empty. - function pop(MemHeap memory heap) internal pure returns (uint256 popped) { - (, popped) = _set(heap, 0, 0, 2); - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value. - function pushPop(Heap storage heap, uint256 value) internal returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 4); - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value. - function pushPop(MemHeap memory heap, uint256 value) internal pure returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 4); - } - - /// @dev Pops the minimum value, and pushes the new `value` onto the min-heap. - /// Reverts if the heap is empty. - function replace(Heap storage heap, uint256 value) internal returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 1); - } - - /// @dev Pops the minimum value, and pushes the new `value` onto the min-heap. - /// Reverts if the heap is empty. - function replace(MemHeap memory heap, uint256 value) internal pure returns (uint256 popped) { - (, popped) = _set(heap, value, 0, 1); - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value - /// if the length of the heap exceeds `maxLength`. - /// - /// Reverts if `maxLength` is zero. - /// - /// - If the queue is not full: - /// (`success` = true, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is not greater than the minimum value: - /// (`success` = false, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is greater than the minimum value: - /// (`success` = true, `hasPopped` = true, `popped` = ) - /// - /// Useful for implementing a bounded priority queue. - /// - /// It is technically possible for the heap size to exceed `maxLength` - /// if `enqueue` has been previously called with a larger `maxLength`. - /// In such a case, the heap will be treated exactly as if it is full, - /// conditionally popping the minimum value if `value` is greater than it. - /// - /// Under normal usage, which keeps `maxLength` constant throughout - /// the lifetime of a heap, this out-of-spec edge case will not be triggered. - function enqueue(Heap storage heap, uint256 value, uint256 maxLength) - internal - returns (bool success, bool hasPopped, uint256 popped) - { - (value, popped) = _set(heap, value, maxLength, 0); - /// @solidity memory-safe-assembly - assembly { - hasPopped := eq(3, value) - success := value - } - } - - /// @dev Pushes the `value` onto the min-heap, and pops the minimum value - /// if the length of the heap exceeds `maxLength`. - /// - /// Reverts if `maxLength` is zero. - /// - /// - If the queue is not full: - /// (`success` = true, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is not greater than the minimum value: - /// (`success` = false, `hasPopped` = false, `popped` = 0) - /// - If the queue is full, and `value` is greater than the minimum value: - /// (`success` = true, `hasPopped` = true, `popped` = ) - /// - /// Useful for implementing a bounded priority queue. - function enqueue(MemHeap memory heap, uint256 value, uint256 maxLength) - internal - pure - returns (bool success, bool hasPopped, uint256 popped) - { - (value, popped) = _set(heap, value, maxLength, 0); - /// @solidity memory-safe-assembly - assembly { - hasPopped := eq(3, value) - success := value - } - } - - /// @dev Increments the free memory pointer by a word and fills the word with 0. - /// This is if you want to take extra precaution that the memory word slot before - /// the `data` array in `MemHeap` doesn't contain a non-zero multiple of prime - /// to masquerade as a prime-checksummed capacity. - /// If you are not directly assigning some array to `data`, - /// you don't have to worry about it. - function bumpFreeMemoryPointer() internal pure { - uint256 zero; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, zero) - mstore(0x40, add(m, 0x20)) - } - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Helper function for heap operations. - /// Designed for code conciseness, bytecode compactness, and decent performance. - function _set(Heap storage heap, uint256 value, uint256 maxLength, uint256 mode) - private - returns (uint256 status, uint256 popped) - { - /// @solidity memory-safe-assembly - assembly { - let n := sload(heap.slot) - mstore(0x00, heap.slot) - let sOffset := keccak256(0x00, 0x20) // Array storage slot offset. - let pos := 0 - let childPos := not(0) - // Operations are ordered from most likely usage to least likely usage. - for {} 1 { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } { - // Mode: `enqueue`. - if iszero(mode) { - if iszero(maxLength) { continue } - // If queue is full. - if iszero(lt(n, maxLength)) { - let r := sload(sOffset) - if iszero(lt(r, value)) { break } - status := 3 - childPos := 1 - popped := r - break - } - status := 1 - pos := n - // Increment and update the length. - sstore(heap.slot, add(pos, 1)) - childPos := sOffset - break - } - if iszero(gt(mode, 2)) { - if iszero(n) { continue } - // Mode: `pop`. - if eq(mode, 2) { - // Decrement and update the length. - n := sub(n, 1) - sstore(heap.slot, n) - // Set the `value` to the last item. - value := sload(add(sOffset, n)) - popped := value - if iszero(n) { break } - } - // Mode: `replace`. - popped := sload(sOffset) - childPos := 1 - break - } - // Mode: `push`. - if eq(mode, 3) { - // Increment and update the length. - pos := n - sstore(heap.slot, add(pos, 1)) - // `sOffset` is used as a value that is `>= n` and `< not(0)`. - childPos := sOffset - break - } - // Mode: `pushPop`. - popped := value - if iszero(n) { break } - let r := sload(sOffset) - if iszero(lt(r, value)) { break } - popped := r - childPos := 1 - break - } - // Siftup. - for {} lt(childPos, n) {} { - let child := sload(add(sOffset, childPos)) - let rightPos := add(childPos, 1) - let right := sload(add(sOffset, rightPos)) - if iszero(gt(lt(rightPos, n), lt(child, right))) { - right := child - rightPos := childPos - } - sstore(add(sOffset, pos), right) - pos := rightPos - childPos := add(shl(1, pos), 1) - } - // Siftdown. - for {} pos {} { - let parentPos := shr(1, sub(pos, 1)) - let parent := sload(add(sOffset, parentPos)) - if iszero(lt(value, parent)) { break } - sstore(add(sOffset, pos), parent) - pos := parentPos - } - // If `childPos` has been changed from `not(0)`. - if add(childPos, 1) { sstore(add(sOffset, pos), value) } - } - } - - /// @dev Helper function for heap operations. - /// Designed for code conciseness, bytecode compactness, and decent performance. - function _set(MemHeap memory heap, uint256 value, uint256 maxLength, uint256 mode) - private - pure - returns (uint256 status, uint256 popped) - { - /// @solidity memory-safe-assembly - assembly { - let data := mload(heap) - let n := mload(data) - // Allocation / reallocation. - for { - let cap := not(mload(sub(data, 0x20))) - let prime := 204053801631428327883786711931463459222251954273621 - cap := mul(iszero(mod(cap, prime)), div(cap, prime)) - } iszero(lt(n, cap)) {} { - let newCap := add(add(cap, cap), shl(5, iszero(cap))) - if iszero(or(cap, iszero(n))) { - for { cap := n } iszero(gt(newCap, n)) {} { newCap := add(newCap, newCap) } - } - mstore(mload(0x40), not(mul(newCap, prime))) // Update `heap.capacity`. - let m := add(mload(0x40), 0x20) - mstore(m, n) // Store the length. - mstore(0x40, add(add(m, 0x20), shl(5, newCap))) // Allocate `heap.data` memory. - if cap { - let w := not(0x1f) - for { let i := shl(5, cap) } 1 {} { - mstore(add(m, i), mload(add(data, i))) - i := add(i, w) - if iszero(i) { break } - } - } - mstore(heap, m) // Update `heap.data`. - data := m - break - } - let sOffset := add(data, 0x20) // Array memory offset. - let pos := 0 - let childPos := not(0) - // Operations are ordered from most likely usage to least likely usage. - for {} 1 { - mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`. - revert(0x1c, 0x04) - } { - // Mode: `enqueue`. - if iszero(mode) { - if iszero(maxLength) { continue } - // If the queue is full. - if iszero(lt(n, maxLength)) { - if iszero(lt(mload(sOffset), value)) { break } - status := 3 - childPos := 1 - popped := mload(sOffset) - break - } - status := 1 - pos := n - // Increment and update the length. - mstore(data, add(pos, 1)) - childPos := 0xff0000000000000000 - break - } - if iszero(gt(mode, 2)) { - if iszero(n) { continue } - // Mode: `pop`. - if eq(mode, 2) { - // Decrement and update the length. - n := sub(n, 1) - mstore(data, n) - // Set the `value` to the last item. - value := mload(add(sOffset, shl(5, n))) - popped := value - if iszero(n) { break } - } - // Mode: `replace`. - popped := mload(sOffset) - childPos := 1 - break - } - // Mode: `push`. - if eq(mode, 3) { - // Increment and update the length. - pos := n - mstore(data, add(pos, 1)) - childPos := 0xff0000000000000000 - break - } - // Mode: `pushPop`. - if iszero(mul(n, lt(mload(sOffset), value))) { - popped := value - break - } - popped := mload(sOffset) - childPos := 1 - break - } - // Siftup. - for {} lt(childPos, n) {} { - let child := mload(add(sOffset, shl(5, childPos))) - let rightPos := add(childPos, 1) - let right := mload(add(sOffset, shl(5, rightPos))) - if iszero(gt(lt(rightPos, n), lt(child, right))) { - mstore(add(sOffset, shl(5, pos)), child) - pos := childPos - childPos := add(shl(1, pos), 1) - continue - } - mstore(add(sOffset, shl(5, pos)), right) - pos := rightPos - childPos := add(shl(1, pos), 1) - } - // Siftdown. - for {} pos {} { - let parentPos := shr(1, sub(pos, 1)) - let parent := mload(add(sOffset, shl(5, parentPos))) - if iszero(lt(value, parent)) { break } - mstore(add(sOffset, shl(5, pos)), parent) - pos := parentPos - } - // If `childPos` has been changed from `not(0)`. - if iszero(shr(128, childPos)) { mstore(add(sOffset, shl(5, pos)), value) } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/RedBlackTreeLib.sol b/grouperBot/lib/solady/src/utils/g/RedBlackTreeLib.sol deleted file mode 100644 index efa863c..0000000 --- a/grouperBot/lib/solady/src/utils/g/RedBlackTreeLib.sol +++ /dev/null @@ -1,722 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev A red-black-tree in storage. -struct Tree { - uint256 _spacer; -} - -using RedBlackTreeLib for Tree global; - -/// @notice Library for managing a red-black-tree in storage. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/RedBlackTreeLib.sol) -/// @author Modified from BokkyPooBahsRedBlackTreeLibrary (https://github.com/bokkypoobah/BokkyPooBahsRedBlackTreeLibrary) -/// @dev This implementation does not support the zero (i.e. empty) value. -/// This implementation supports up to 2147483647 values. -library RedBlackTreeLib { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev The value cannot be zero. - error ValueIsEmpty(); - - /// @dev Cannot insert a value that already exists. - error ValueAlreadyExists(); - - /// @dev Cannot remove a value that does not exist. - error ValueDoesNotExist(); - - /// @dev The pointer is out of bounds. - error PointerOutOfBounds(); - - /// @dev The tree is full. - error TreeIsFull(); - - /// @dev `bytes4(keccak256(bytes("ValueAlreadyExists()")))`. - uint256 internal constant ERROR_VALUE_ALREADY_EXISTS = 0xbb33e6ac; - - /// @dev `bytes4(keccak256(bytes("ValueDoesNotExist()")))`. - uint256 internal constant ERROR_VALUE_DOES_NOT_EXISTS = 0xb113638a; - - /// @dev `bytes4(keccak256(bytes("PointerOutOfBounds()")))`. - uint256 internal constant ERROR_POINTER_OUT_OF_BOUNDS = 0xccd52fbc; - - /// @dev `bytes4(keccak256(bytes("TreeIsFull()")))`. - uint256 internal constant ERROR_TREE_IS_FULL = 0xed732d0c; - - // Custom storage: - // ``` - // mstore(0x20, tree.slot) - // mstore(0x00, _NODES_SLOT_SEED) - // let nodes := shl(_NODES_SLOT_SHIFT, keccak256(0x00, 0x40)) - // - // let root := shr(128, sload(nodes)) - // let totalNodes := and(sload(nodes), _BITMASK_KEY) - // - // let nodePacked := sload(or(nodes, nodeIndex)) - // let nodeLeft := and(nodePacked, _BITMASK_KEY) - // let nodeRight := and(shr(_BITPOS_RIGHT, nodePacked), _BITMASK_KEY) - // let nodeParent := and(shr(_BITPOS_PARENT, nodePacked), _BITMASK_KEY) - // let nodeRed := and(shr(_BITPOS_RED, nodePacked), 1) - // - // let nodeValue := shr(_BITPOS_PACKED_VALUE, nodePacked) - // if iszero(nodeValue) { - // nodeValue := sload(or(_BIT_FULL_VALUE_SLOT, or(nodes, nodeIndex))) - // } - // ``` - // - // Bits Layout of the Root Index Slot: - // - [0..30] `totalNodes` - // - [128..159] `rootNodeIndex` - // - // Bits Layout of a Node: - // - [0..30] `leftChildIndex` - // - [31..61] `rightChildIndex` - // - [62..92] `parentIndex` - // - [93] `isRed` - // - [96..255] `nodePackedValue` - - uint256 private constant _NODES_SLOT_SEED = 0x1dc27bb5462fdadcb; - uint256 private constant _NODES_SLOT_SHIFT = 32; - uint256 private constant _BITMASK_KEY = (1 << 31) - 1; - uint256 private constant _BITPOS_LEFT = 0; - uint256 private constant _BITPOS_RIGHT = 31; - uint256 private constant _BITPOS_PARENT = 31 * 2; - uint256 private constant _BITPOS_RED = 31 * 3; - uint256 private constant _BITMASK_RED = 1 << (31 * 3); - uint256 private constant _BITPOS_PACKED_VALUE = 96; - uint256 private constant _BITMASK_PACKED_VALUE = (1 << 160) - 1; - uint256 private constant _BIT_FULL_VALUE_SLOT = 1 << 31; - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the number of unique values in the tree. - function size(Tree storage tree) internal view returns (uint256 result) { - uint256 nodes = _nodes(tree); - /// @solidity memory-safe-assembly - assembly { - result := and(sload(nodes), _BITMASK_KEY) - } - } - - /// @dev Returns an array of all the values in the tree in ascending sorted order. - /// WARNING! This function can exhaust the block gas limit if the tree is big. - /// It is intended for usage in off-chain view functions. - function values(Tree storage tree) internal view returns (uint256[] memory result) { - uint256 nodes = _nodes(tree); - /// @solidity memory-safe-assembly - assembly { - function visit(current_) { - if iszero(current_) { leave } // If the current node is null, leave. - current_ := or(mload(0x00), current_) // Current node's storage slot. - let packed_ := sload(current_) - visit(and(packed_, _BITMASK_KEY)) // Visit left child. - let value_ := shr(_BITPOS_PACKED_VALUE, packed_) // Current value. - if iszero(value_) { value_ := sload(or(current_, _BIT_FULL_VALUE_SLOT)) } - mstore(mload(0x20), value_) // Append the value to `results`. - mstore(0x20, add(0x20, mload(0x20))) // Advance the offset into `results`. - visit(and(shr(_BITPOS_RIGHT, packed_), _BITMASK_KEY)) // Visit right child. - } - result := mload(0x40) - let rootPacked := sload(nodes) - mstore(result, and(rootPacked, _BITMASK_KEY)) // Length of `result`. - mstore(0x00, nodes) // Cache the nodes pointer in scratch space. - mstore(0x20, add(result, 0x20)) // Cache the offset into `results` in scratch space. - mstore(0x40, add(mload(0x20), shl(5, mload(result)))) // Allocate memory. - visit(shr(128, rootPacked)) // Start the tree traversal from the root node. - } - } - - /// @dev Returns a pointer to the value `x`. - /// If the value `x` is not in the tree, the returned pointer will be empty. - function find(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes,, uint256 key) = _find(tree, x); - result = _pack(nodes, key); - } - - /// @dev Returns a pointer to the nearest value to `x`. - /// In a tie-breaker, the returned pointer will point to the smaller value. - /// If the tree is empty, the returned pointer will be empty. - function nearest(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - unchecked { - if (cursor == uint256(0)) return result; // Nothing found -- empty tree. - if (key != uint256(0)) return _pack(nodes, key); // Exact match. - bytes32 a = _pack(nodes, cursor); - uint256 aValue = value(a); - bytes32 b = x < aValue ? prev(a) : next(a); - if (b == bytes32(0)) return a; // Only node found. - uint256 bValue = value(b); - uint256 aDist = x < aValue ? aValue - x : x - aValue; - uint256 bDist = x < bValue ? bValue - x : x - bValue; - return (aDist == bDist ? aValue < bValue : aDist < bDist) ? a : b; - } - } - - /// @dev Returns a pointer to the nearest value lesser or equal to `x`. - /// If there is no value lesser or equal to `x`, the returned pointer will be empty. - function nearestBefore(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - if (cursor == uint256(0)) return result; // Nothing found -- empty tree. - if (key != uint256(0)) return _pack(nodes, key); // Exact match. - bytes32 a = _pack(nodes, cursor); - return value(a) < x ? a : prev(a); - } - - /// @dev Returns a pointer to the nearest value greater or equal to `x`. - /// If there is no value greater or equal to `x`, the returned pointer will be empty. - function nearestAfter(Tree storage tree, uint256 x) internal view returns (bytes32 result) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - if (cursor == uint256(0)) return result; // Nothing found -- empty tree. - if (key != uint256(0)) return _pack(nodes, key); // Exact match. - bytes32 a = _pack(nodes, cursor); - return value(a) > x ? a : next(a); - } - - /// @dev Returns whether the value `x` exists. - function exists(Tree storage tree, uint256 x) internal view returns (bool result) { - (,, uint256 key) = _find(tree, x); - result = key != 0; - } - - /// @dev Inserts the value `x` into the tree. - /// Reverts if the value `x` already exists. - function insert(Tree storage tree, uint256 x) internal { - uint256 err = tryInsert(tree, x); - if (err != 0) _revert(err); - } - - /// @dev Inserts the value `x` into the tree. - /// Returns a non-zero error code upon failure instead of reverting - /// (except for reverting if `x` is an empty value). - function tryInsert(Tree storage tree, uint256 x) internal returns (uint256 err) { - (uint256 nodes, uint256 cursor, uint256 key) = _find(tree, x); - err = _update(nodes, cursor, key, x, 0); - } - - /// @dev Removes the value `x` from the tree. - /// Reverts if the value does not exist. - function remove(Tree storage tree, uint256 x) internal { - uint256 err = tryRemove(tree, x); - if (err != 0) _revert(err); - } - - /// @dev Removes the value `x` from the tree. - /// Returns a non-zero error code upon failure instead of reverting - /// (except for reverting if `x` is an empty value). - function tryRemove(Tree storage tree, uint256 x) internal returns (uint256 err) { - (uint256 nodes,, uint256 key) = _find(tree, x); - err = _update(nodes, 0, key, 0, 1); - } - - /// @dev Removes the value at pointer `ptr` from the tree. - /// Reverts if `ptr` is empty (i.e. value does not exist), - /// or if `ptr` is out of bounds. - /// After removal, `ptr` may point to another existing value. - /// For safety, do not reuse `ptr` after calling remove on it. - function remove(bytes32 ptr) internal { - uint256 err = tryRemove(ptr); - if (err != 0) _revert(err); - } - - /// @dev Removes the value at pointer `ptr` from the tree. - /// Returns a non-zero error code upon failure instead of reverting. - function tryRemove(bytes32 ptr) internal returns (uint256 err) { - (uint256 nodes, uint256 key) = _unpack(ptr); - err = _update(nodes, 0, key, 0, 1); - } - - /// @dev Returns the value at pointer `ptr`. - /// If `ptr` is empty, the result will be zero. - function value(bytes32 ptr) internal view returns (uint256 result) { - if (ptr == bytes32(0)) return result; - /// @solidity memory-safe-assembly - assembly { - let packed := sload(ptr) - result := shr(_BITPOS_PACKED_VALUE, packed) - if iszero(result) { result := sload(or(ptr, _BIT_FULL_VALUE_SLOT)) } - } - } - - /// @dev Returns a pointer to the smallest value in the tree. - /// If the tree is empty, the returned pointer will be empty. - function first(Tree storage tree) internal view returns (bytes32 result) { - result = _end(tree, _BITPOS_LEFT); - } - - /// @dev Returns a pointer to the largest value in the tree. - /// If the tree is empty, the returned pointer will be empty. - function last(Tree storage tree) internal view returns (bytes32 result) { - result = _end(tree, _BITPOS_RIGHT); - } - - /// @dev Returns the pointer to the next largest value. - /// If there is no next value, or if `ptr` is empty, - /// the returned pointer will be empty. - function next(bytes32 ptr) internal view returns (bytes32 result) { - result = _step(ptr, _BITPOS_LEFT, _BITPOS_RIGHT); - } - - /// @dev Returns the pointer to the next smallest value. - /// If there is no previous value, or if `ptr` is empty, - /// the returned pointer will be empty. - function prev(bytes32 ptr) internal view returns (bytes32 result) { - result = _step(ptr, _BITPOS_RIGHT, _BITPOS_LEFT); - } - - /// @dev Returns whether the pointer is empty. - function isEmpty(bytes32 ptr) internal pure returns (bool result) { - result = ptr == bytes32(0); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* PRIVATE HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unpacks the pointer `ptr` to its components. - function _unpack(bytes32 ptr) private pure returns (uint256 nodes, uint256 key) { - /// @solidity memory-safe-assembly - assembly { - nodes := shl(_NODES_SLOT_SHIFT, shr(_NODES_SLOT_SHIFT, ptr)) - key := and(_BITMASK_KEY, ptr) - } - } - - /// @dev Packs `nodes` and `key` into a single pointer. - function _pack(uint256 nodes, uint256 key) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := mul(or(nodes, key), iszero(iszero(key))) - } - } - - /// @dev Returns the pointer to either end of the tree. - function _end(Tree storage tree, uint256 L) private view returns (bytes32 result) { - uint256 nodes = _nodes(tree); - /// @solidity memory-safe-assembly - assembly { - result := shr(128, sload(nodes)) - if result { - for {} 1 {} { - let packed := sload(or(nodes, result)) - let left := and(shr(L, packed), _BITMASK_KEY) - if iszero(left) { break } - result := left - } - } - } - result = _pack(nodes, uint256(result)); - } - - /// @dev Step the pointer `ptr` forwards or backwards. - function _step(bytes32 ptr, uint256 L, uint256 R) private view returns (bytes32 result) { - if (ptr == bytes32(0)) return ptr; - (uint256 nodes, uint256 target) = _unpack(ptr); - /// @solidity memory-safe-assembly - assembly { - let packed := sload(ptr) - for { result := and(shr(R, packed), _BITMASK_KEY) } 1 {} { - if iszero(result) { - result := and(shr(_BITPOS_PARENT, packed), _BITMASK_KEY) - for {} 1 {} { - if iszero(result) { break } - packed := sload(or(nodes, result)) - if iszero(eq(target, and(shr(R, packed), _BITMASK_KEY))) { break } - target := result - result := and(shr(_BITPOS_PARENT, packed), _BITMASK_KEY) - } - break - } - for {} 1 {} { - packed := sload(or(nodes, result)) - let left := and(shr(L, packed), _BITMASK_KEY) - if iszero(left) { break } - result := left - } - break - } - } - result = _pack(nodes, uint256(result)); - } - - /// @dev Inserts or delete the value `x` from the tree. - function _update(uint256 nodes, uint256 cursor, uint256 key, uint256 x, uint256 mode) - private - returns (uint256 err) - { - /// @solidity memory-safe-assembly - assembly { - function getKey(packed_, bitpos_) -> index_ { - index_ := and(_BITMASK_KEY, shr(bitpos_, packed_)) - } - - function setKey(packed_, bitpos_, key_) -> result_ { - result_ := or(and(not(shl(bitpos_, _BITMASK_KEY)), packed_), shl(bitpos_, key_)) - } - - function rotate(nodes_, key_, L, R) { - let packed_ := sload(or(nodes_, key_)) - let cursor_ := getKey(packed_, R) - let parent_ := getKey(packed_, _BITPOS_PARENT) - let cursorPacked_ := sload(or(nodes_, cursor_)) - let cursorLeft_ := getKey(cursorPacked_, L) - - if cursorLeft_ { - let s_ := or(nodes_, cursorLeft_) - sstore(s_, setKey(sload(s_), _BITPOS_PARENT, key_)) - } - - for {} 1 {} { - if iszero(parent_) { - mstore(0x00, cursor_) - break - } - let s_ := or(nodes_, parent_) - let parentPacked_ := sload(s_) - if eq(key_, getKey(parentPacked_, L)) { - sstore(s_, setKey(parentPacked_, L, cursor_)) - break - } - sstore(s_, setKey(parentPacked_, R, cursor_)) - break - } - packed_ := setKey(packed_, R, cursorLeft_) - sstore(or(nodes_, key_), setKey(packed_, _BITPOS_PARENT, cursor_)) - cursorPacked_ := setKey(cursorPacked_, _BITPOS_PARENT, parent_) - sstore(or(nodes_, cursor_), setKey(cursorPacked_, L, key_)) - } - - function insert(nodes_, cursor_, key_, x_) -> err_ { - if key_ { - err_ := ERROR_VALUE_ALREADY_EXISTS - leave - } - - let totalNodes_ := add(shr(128, mload(0x20)), 1) - if gt(totalNodes_, _BITMASK_KEY) { - err_ := ERROR_TREE_IS_FULL - leave - } - - mstore(0x20, shl(128, totalNodes_)) - - { - let packed_ := or(_BITMASK_RED, shl(_BITPOS_PARENT, cursor_)) - let nodePointer_ := or(nodes_, totalNodes_) - - for {} 1 {} { - if iszero(gt(x_, _BITMASK_PACKED_VALUE)) { - packed_ := or(shl(_BITPOS_PACKED_VALUE, x_), packed_) - break - } - sstore(or(nodePointer_, _BIT_FULL_VALUE_SLOT), x_) - break - } - sstore(nodePointer_, packed_) - - for {} 1 {} { - if iszero(cursor_) { - mstore(0x00, totalNodes_) - break - } - let s_ := or(nodes_, cursor_) - let cPacked_ := sload(s_) - let cValue_ := shr(_BITPOS_PACKED_VALUE, cPacked_) - if iszero(cValue_) { cValue_ := sload(or(s_, _BIT_FULL_VALUE_SLOT)) } - if iszero(lt(x_, cValue_)) { - sstore(s_, setKey(cPacked_, _BITPOS_RIGHT, totalNodes_)) - break - } - sstore(s_, setKey(cPacked_, _BITPOS_LEFT, totalNodes_)) - break - } - } - - // Insert fixup workflow: - - key_ := totalNodes_ - let BR := _BITMASK_RED - for {} iszero(eq(key_, mload(0x00))) {} { - let packed_ := sload(or(nodes_, key_)) - let parent_ := getKey(packed_, _BITPOS_PARENT) - let parentPacked_ := sload(or(nodes_, parent_)) - if iszero(and(BR, parentPacked_)) { break } - - let grandParent_ := getKey(parentPacked_, _BITPOS_PARENT) - let grandParentPacked_ := sload(or(nodes_, grandParent_)) - - let R := mul(eq(parent_, getKey(grandParentPacked_, 0)), _BITPOS_RIGHT) - let L := xor(R, _BITPOS_RIGHT) - - let c_ := getKey(grandParentPacked_, R) - let cPacked_ := sload(or(nodes_, c_)) - if iszero(and(BR, cPacked_)) { - if eq(key_, getKey(parentPacked_, R)) { - key_ := parent_ - rotate(nodes_, key_, L, R) - parent_ := getKey(sload(or(nodes_, key_)), _BITPOS_PARENT) - parentPacked_ := sload(or(nodes_, parent_)) - } - sstore(or(nodes_, parent_), and(parentPacked_, not(BR))) - let s_ := or(nodes_, grandParent_) - sstore(s_, or(sload(s_), BR)) - rotate(nodes_, grandParent_, R, L) - break - } - sstore(or(nodes_, parent_), and(parentPacked_, not(BR))) - sstore(or(nodes_, c_), and(cPacked_, not(BR))) - sstore(or(nodes_, grandParent_), or(grandParentPacked_, BR)) - key_ := grandParent_ - } - let root_ := or(nodes_, mload(0x00)) - sstore(root_, and(sload(root_), not(BR))) - } - - function removeFixup(nodes_, key_) { - let BR := _BITMASK_RED - for {} iszero(eq(key_, mload(0x00))) {} { - let packed_ := sload(or(nodes_, key_)) - if and(BR, packed_) { break } - - let parent_ := getKey(packed_, _BITPOS_PARENT) - let parentPacked_ := sload(or(nodes_, parent_)) - - let R := mul(eq(key_, getKey(parentPacked_, 0)), _BITPOS_RIGHT) - let L := xor(R, _BITPOS_RIGHT) - - let cursor_ := getKey(parentPacked_, R) - let cursorPacked_ := sload(or(nodes_, cursor_)) - - if and(BR, cursorPacked_) { - sstore(or(nodes_, cursor_), and(cursorPacked_, not(BR))) - sstore(or(nodes_, parent_), or(parentPacked_, BR)) - rotate(nodes_, parent_, L, R) - cursor_ := getKey(sload(or(nodes_, parent_)), R) - cursorPacked_ := sload(or(nodes_, cursor_)) - } - - let cursorLeft_ := getKey(cursorPacked_, L) - let cursorLeftPacked_ := sload(or(nodes_, cursorLeft_)) - let cursorRight_ := getKey(cursorPacked_, R) - let cursorRightPacked_ := sload(or(nodes_, cursorRight_)) - - if iszero(and(BR, or(cursorLeftPacked_, cursorRightPacked_))) { - sstore(or(nodes_, cursor_), or(cursorPacked_, BR)) - key_ := parent_ - continue - } - - if iszero(and(BR, cursorRightPacked_)) { - sstore(or(nodes_, cursorLeft_), and(cursorLeftPacked_, not(BR))) - sstore(or(nodes_, cursor_), or(cursorPacked_, BR)) - rotate(nodes_, cursor_, R, L) - cursor_ := getKey(sload(or(nodes_, parent_)), R) - cursorPacked_ := sload(or(nodes_, cursor_)) - cursorRight_ := getKey(cursorPacked_, R) - cursorRightPacked_ := sload(or(nodes_, cursorRight_)) - } - - parentPacked_ := sload(or(nodes_, parent_)) - // forgefmt: disable-next-item - sstore(or(nodes_, cursor_), xor(cursorPacked_, and(BR, xor(cursorPacked_, parentPacked_)))) - sstore(or(nodes_, parent_), and(parentPacked_, not(BR))) - sstore(or(nodes_, cursorRight_), and(cursorRightPacked_, not(BR))) - rotate(nodes_, parent_, L, R) - break - } - sstore(or(nodes_, key_), and(sload(or(nodes_, key_)), not(BR))) - } - - function replaceParent(nodes_, parent_, a_, b_) { - if iszero(parent_) { - mstore(0x00, a_) - leave - } - let s_ := or(nodes_, parent_) - let p_ := sload(s_) - let t_ := iszero(eq(b_, getKey(p_, _BITPOS_LEFT))) - sstore(s_, setKey(p_, mul(t_, _BITPOS_RIGHT), a_)) - } - - // In `remove`, the parent of the null value (index 0) may be temporarily set - // to a non-zero value. This is an optimization that unifies the removal cases. - function remove(nodes_, key_) -> err_ { - if gt(key_, shr(128, mload(0x20))) { - err_ := ERROR_POINTER_OUT_OF_BOUNDS - leave - } - if iszero(key_) { - err_ := ERROR_VALUE_DOES_NOT_EXISTS - leave - } - - let cursor_ := key_ - { - let packed_ := sload(or(nodes_, key_)) - let left_ := getKey(packed_, _BITPOS_LEFT) - let right_ := getKey(packed_, _BITPOS_RIGHT) - if mul(left_, right_) { - for { cursor_ := right_ } 1 {} { - let cursorLeft_ := getKey(sload(or(nodes_, cursor_)), _BITPOS_LEFT) - if iszero(cursorLeft_) { break } - cursor_ := cursorLeft_ - } - } - } - - let cursorPacked_ := sload(or(nodes_, cursor_)) - let probe_ := getKey(cursorPacked_, _BITPOS_LEFT) - probe_ := getKey(cursorPacked_, mul(iszero(probe_), _BITPOS_RIGHT)) - - let yParent_ := getKey(cursorPacked_, _BITPOS_PARENT) - let probeSlot_ := or(nodes_, probe_) - sstore(probeSlot_, setKey(sload(probeSlot_), _BITPOS_PARENT, yParent_)) - replaceParent(nodes_, yParent_, probe_, cursor_) - - if iszero(eq(cursor_, key_)) { - let packed_ := sload(or(nodes_, key_)) - replaceParent(nodes_, getKey(packed_, _BITPOS_PARENT), cursor_, key_) - - let leftSlot_ := or(nodes_, getKey(packed_, _BITPOS_LEFT)) - sstore(leftSlot_, setKey(sload(leftSlot_), _BITPOS_PARENT, cursor_)) - - let rightSlot_ := or(nodes_, getKey(packed_, _BITPOS_RIGHT)) - sstore(rightSlot_, setKey(sload(rightSlot_), _BITPOS_PARENT, cursor_)) - - // Copy `left`, `right`, `red` from `key_` to `cursor_`. - // forgefmt: disable-next-item - sstore(or(nodes_, cursor_), xor(cursorPacked_, - and(xor(packed_, cursorPacked_), sub(shl(_BITPOS_PACKED_VALUE, 1), 1)))) - - let t_ := cursor_ - cursor_ := key_ - key_ := t_ - } - - if iszero(and(_BITMASK_RED, cursorPacked_)) { removeFixup(nodes_, probe_) } - - // Remove last workflow: - - let last_ := shr(128, mload(0x20)) - let lastPacked_ := sload(or(nodes_, last_)) - let lastValue_ := shr(_BITPOS_PACKED_VALUE, lastPacked_) - let lastFullValue_ := 0 - if iszero(lastValue_) { - lastValue_ := sload(or(_BIT_FULL_VALUE_SLOT, or(nodes_, last_))) - lastFullValue_ := lastValue_ - } - - let cursorValue_ := shr(_BITPOS_PACKED_VALUE, sload(or(nodes_, cursor_))) - let cursorFullValue_ := 0 - if iszero(cursorValue_) { - cursorValue_ := sload(or(_BIT_FULL_VALUE_SLOT, or(nodes_, cursor_))) - cursorFullValue_ := cursorValue_ - } - - if iszero(eq(lastValue_, cursorValue_)) { - sstore(or(nodes_, cursor_), lastPacked_) - if iszero(eq(lastFullValue_, cursorFullValue_)) { - sstore(or(_BIT_FULL_VALUE_SLOT, or(nodes_, cursor_)), lastFullValue_) - } - for { let lastParent_ := getKey(lastPacked_, _BITPOS_PARENT) } 1 {} { - if iszero(lastParent_) { - mstore(0x00, cursor_) - break - } - let s_ := or(nodes_, lastParent_) - let p_ := sload(s_) - let t_ := iszero(eq(last_, getKey(p_, _BITPOS_LEFT))) - sstore(s_, setKey(p_, mul(t_, _BITPOS_RIGHT), cursor_)) - break - } - let lastRight_ := getKey(lastPacked_, _BITPOS_RIGHT) - if lastRight_ { - let s_ := or(nodes_, lastRight_) - sstore(s_, setKey(sload(s_), _BITPOS_PARENT, cursor_)) - } - let lastLeft_ := getKey(lastPacked_, _BITPOS_LEFT) - if lastLeft_ { - let s_ := or(nodes_, lastLeft_) - sstore(s_, setKey(sload(s_), _BITPOS_PARENT, cursor_)) - } - } - sstore(or(nodes_, last_), 0) - if lastFullValue_ { sstore(or(_BIT_FULL_VALUE_SLOT, or(nodes_, last_)), 0) } - - mstore(0x20, shl(128, sub(last_, 1))) - } - - mstore(0x00, codesize()) // Zeroize the first 0x10 bytes. - mstore(0x10, sload(nodes)) - - for {} 1 {} { - if iszero(mode) { - err := insert(nodes, cursor, key, x) - break - } - err := remove(nodes, key) - break - } - - sstore(nodes, mload(0x10)) - } - } - - /// @dev Returns the pointer to the `nodes` for the tree. - function _nodes(Tree storage tree) private pure returns (uint256 nodes) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, tree.slot) - mstore(0x00, _NODES_SLOT_SEED) - nodes := shl(_NODES_SLOT_SHIFT, keccak256(0x00, 0x40)) - } - } - - /// @dev Finds `x` in `tree`. The `key` will be zero if `x` is not found. - function _find(Tree storage tree, uint256 x) - private - view - returns (uint256 nodes, uint256 cursor, uint256 key) - { - if (x == uint256(0)) _revert(0xc94f1877); // `ValueIsEmpty()`. - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, tree.slot) - mstore(0x00, _NODES_SLOT_SEED) - nodes := shl(_NODES_SLOT_SHIFT, keccak256(0x00, 0x40)) - // Layout scratch space so that `mload(0x00) == 0`, `mload(0x01) == _BITPOS_RIGHT`. - mstore(0x01, _BITPOS_RIGHT) // `_BITPOS_RIGHT` is 31. - for { let probe := shr(128, sload(nodes)) } probe {} { - cursor := probe - let nodePacked := sload(or(nodes, probe)) - let nodeValue := shr(_BITPOS_PACKED_VALUE, nodePacked) - if iszero(nodeValue) { - nodeValue := sload(or(or(nodes, probe), _BIT_FULL_VALUE_SLOT)) - } - if eq(nodeValue, x) { - key := cursor - break - } - probe := and(shr(mload(gt(x, nodeValue)), nodePacked), _BITMASK_KEY) - } - } - } - - /// @dev Helper to revert `err` efficiently. - function _revert(uint256 err) private pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, err) - revert(0x1c, 0x04) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/g/WebAuthn.sol b/grouperBot/lib/solady/src/utils/g/WebAuthn.sol deleted file mode 100644 index d9b66f9..0000000 --- a/grouperBot/lib/solady/src/utils/g/WebAuthn.sol +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -// This file is auto-generated. - -/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ -/* STRUCTS */ -/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - -/// @dev Helps make encoding and decoding easier, alleviates stack-too-deep. -struct WebAuthnAuth { - // The WebAuthn authenticator data. - // See: https://www.w3.org/TR/webauthn-2/#dom-authenticatorassertionresponse-authenticatordata. - bytes authenticatorData; - // The WebAuthn client data JSON. - // See: https://www.w3.org/TR/webauthn-2/#dom-authenticatorresponse-clientdatajson. - string clientDataJSON; - // Start index of "challenge":"..." in `clientDataJSON`. - uint256 challengeIndex; - // Start index of "type":"..." in `clientDataJSON`. - uint256 typeIndex; - // The r value of secp256r1 signature. - bytes32 r; - // The s value of secp256r1 signature. - bytes32 s; -} - -using WebAuthn for WebAuthnAuth global; - -import {Base64} from "../Base64.sol"; -import {P256} from "../P256.sol"; - -/// @notice WebAuthn helper. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/g/WebAuthn.sol) -/// @author Modified from Daimo WebAuthn (https://github.com/daimo-eth/p256-verifier/blob/master/src/WebAuthn.sol) -/// @author Modified from Coinbase WebAuthn (https://github.com/base-org/webauthn-sol/blob/main/src/WebAuthn.sol) -library WebAuthn { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* WEBAUTHN VERIFICATION OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Verifies a Webauthn Authentication Assertion. - /// See: https://www.w3.org/TR/webauthn-2/#sctn-verifying-assertion. - /// - /// We do not verify all the steps as described in the specification, only ones - /// relevant to our context. Please carefully read through this list before usage. - /// - /// Specifically, we do verify the following: - /// - Verify that `authenticatorData` (which comes from the authenticator, - /// such as iCloud Keychain) indicates a well-formed assertion with the - /// "User Present" bit set. If `requireUserVerification` is set, checks that the - /// authenticator enforced user verification. User verification should be required - /// if, and only if, `options.userVerification` is set to required in the request. - /// - Verifies that the client JSON is of type "webauthn.get", - /// i.e. the client was responding to a request to assert authentication. - /// - Verifies that the client JSON contains the requested challenge. - /// - Verifies that (r, s) constitute a valid signature over both the - /// `authData` and client JSON, for public key (x, y). - /// - /// We make some assumptions about the particular use case of this verifier, - /// so we do NOT verify the following: - /// - Does NOT verify that the origin in the `clientDataJSON` matches the - /// Relying Party's origin: it is considered the authenticator's responsibility to - /// ensure that the user is interacting with the correct RP. This is enforced by - /// most high quality authenticators properly, particularly the iCloud Keychain - /// and Google Password Manager were tested. - /// - Does NOT verify That `topOrigin` in `clientDataJSON` is well-formed: - /// We assume it would never be present, i.e. the credentials are never used in a - /// cross-origin/iframe context. The website/app set up should disallow cross-origin - /// usage of the credentials. This is the default behavior for created credentials - /// in common settings. - /// - Does NOT verify that the `rpIdHash` in `authenticatorData` is the SHA-256 hash - /// of the RP ID expected by the Relying Party: - /// this means that we rely on the authenticator to properly enforce - /// credentials to be used only by the correct RP. - /// This is generally enforced with features like Apple App Site Association - /// and Google Asset Links. To protect from edge cases in which a previously-linked - /// RP ID is removed from the authorized RP IDs, we recommend that messages - /// signed by the authenticator include some expiry mechanism. - /// - Does NOT verify the credential backup state: this assumes the credential backup - /// state is NOT used as part of Relying Party business logic or policy. - /// - Does NOT verify the values of the client extension outputs: - /// this assumes that the Relying Party does not use client extension outputs. - /// - Does NOT verify the signature counter: signature counters are intended to enable - /// risk scoring for the Relying Party. This assumes risk scoring is not used as part - /// of Relying Party business logic or policy. - /// - Does NOT verify the attestation object: this assumes that - /// response.attestationObject is NOT present in the response, - /// i.e. the RP does not intend to verify an attestation. - function verify( - bytes memory challenge, - bool requireUserVerification, - WebAuthnAuth memory auth, - bytes32 x, - bytes32 y - ) internal view returns (bool result) { - bytes32 messageHash; - string memory encoded = Base64.encode(challenge, true, true); - /// @solidity memory-safe-assembly - assembly { - let clientDataJSON := mload(add(auth, 0x20)) - let n := mload(clientDataJSON) // `clientDataJSON`'s length. - let o := add(clientDataJSON, 0x20) // Start of `clientData`'s bytes. - { - let c := mload(add(auth, 0x40)) // Challenge index in `clientDataJSON`. - let t := mload(add(auth, 0x60)) // Type index in `clientDataJSON`. - let l := mload(encoded) // Cache `encoded`'s length. - let q := add(l, 0x0d) // Length of `encoded` prefixed with '"challenge":"'. - mstore(encoded, shr(152, '"challenge":"')) // Temp prefix with '"challenge":"'. - result := - and( - // 11. Verify JSON's type. Also checks for possible addition overflows. - and( - eq(shr(88, mload(add(o, t))), shr(88, '"type":"webauthn.get"')), - lt(shr(128, or(t, c)), lt(add(0x14, t), n)) - ), - // 12. Verify JSON's challenge. Includes a check for the closing '"'. - and( - eq(keccak256(add(o, c), q), keccak256(add(encoded, 0x13), q)), - and(eq(byte(0, mload(add(add(o, c), q))), 34), lt(add(q, c), n)) - ) - ) - mstore(encoded, l) // Restore `encoded`'s length, in case of string interning. - } - // Skip 13., 14., 15. - let l := mload(mload(auth)) // Length of `authenticatorData`. - // 16. Verify that the "User Present" flag is set (bit 0). - // 17. Verify that the "User Verified" flag is set (bit 2), if required. - // See: https://www.w3.org/TR/webauthn-2/#flags. - let u := or(1, shl(2, iszero(iszero(requireUserVerification)))) - result := and(and(result, gt(l, 0x20)), eq(and(mload(add(mload(auth), 0x21)), u), u)) - if result { - let p := add(mload(auth), 0x20) // Start of `authenticatorData`'s bytes. - let e := add(p, l) // Location of the word after `authenticatorData`. - let w := mload(e) // Cache the word after `authenticatorData`. - // 19. Compute `sha256(clientDataJSON)`. - // 20. Compute `sha256(authenticatorData ‖ sha256(clientDataJSON))`. - // forgefmt: disable-next-item - messageHash := mload(staticcall(gas(), - shl(1, staticcall(gas(), 2, o, n, e, 0x20)), p, add(l, 0x20), 0x01, 0x20)) - mstore(e, w) // Restore the word after `authenticatorData`, in case of reuse. - // `returndatasize()` is `0x20` on `sha256` success, and `0x00` otherwise. - if iszero(returndatasize()) { invalid() } - } - } - // `P256.verifySignature` returns false if `s > N/2` due to the malleability check. - if (result) result = P256.verifySignature(messageHash, auth.r, auth.s, x, y); - } - - /// @dev Plain variant of verify. - function verify( - bytes memory challenge, - bool requireUserVerification, - bytes memory authenticatorData, - string memory clientDataJSON, - uint256 challengeIndex, - uint256 typeIndex, - bytes32 r, - bytes32 s, - bytes32 x, - bytes32 y - ) internal view returns (bool) { - return verify( - challenge, - requireUserVerification, - WebAuthnAuth(authenticatorData, clientDataJSON, challengeIndex, typeIndex, r, s), - x, - y - ); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* ENCODING / DECODING HELPERS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns `abi.encode(auth)`. - function encodeAuth(WebAuthnAuth memory auth) internal pure returns (bytes memory) { - return abi.encode(auth); - } - - /// @dev Performs a best-effort attempt to `abi.decode(auth)`. Won't revert. - /// If any fields cannot be successfully extracted, `decoded` will not be populated, - /// which will cause `verify` to return false (as `clientDataJSON` is empty). - function tryDecodeAuth(bytes memory encodedAuth) - internal - pure - returns (WebAuthnAuth memory decoded) - { - /// @solidity memory-safe-assembly - assembly { - for { let n := mload(encodedAuth) } iszero(lt(n, 0xc0)) {} { - let o := add(encodedAuth, 0x20) // Start of `encodedAuth`'s bytes. - let e := add(o, n) // End of `encodedAuth` in memory. - let p := add(mload(o), o) // Start of `encodedAuth`. - if or(gt(add(p, 0xc0), e), lt(p, o)) { break } - let authenticatorData := add(mload(p), p) - let clientDataJSON := add(mload(add(p, 0x20)), p) - if or( - or(gt(authenticatorData, e), lt(authenticatorData, p)), - or(gt(clientDataJSON, e), lt(clientDataJSON, p)) - ) { break } - if or( - gt(add(add(authenticatorData, 0x20), mload(authenticatorData)), e), - gt(add(add(clientDataJSON, 0x20), mload(clientDataJSON)), e) - ) { break } - mstore(decoded, authenticatorData) // `authenticatorData`. - mstore(add(decoded, 0x20), clientDataJSON) // `clientDataJSON`. - mstore(add(decoded, 0x40), mload(add(p, 0x40))) // `challengeIndex`. - mstore(add(decoded, 0x60), mload(add(p, 0x60))) // `typeIndex`. - mstore(add(decoded, 0x80), mload(add(p, 0x80))) // `r`. - mstore(add(decoded, 0xa0), mload(add(p, 0xa0))) // `s`. - break - } - } - } - - /// @dev Returns the compact encoding of `auth`: - /// ``` - /// abi.encodePacked( - /// uint16(auth.authenticatorData.length), - /// bytes(auth.authenticatorData), - /// bytes(auth.clientDataJSON), - /// uint16(auth.challengeIndex), - /// uint16(auth.typeIndex), - /// bytes32(auth.r), - /// bytes32(auth.s) - /// ) - /// ``` - /// Returns the empty string if any length or index exceeds 16 bits. - function tryEncodeAuthCompact(WebAuthnAuth memory auth) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - function copyBytes(o_, s_, c_) -> _e { - mstore(o_, shl(240, mload(s_))) - o_ := add(o_, c_) - _e := add(o_, mload(s_)) // The end of the bytes. - for { let d_ := sub(add(0x20, s_), o_) } 1 {} { - mstore(o_, mload(add(d_, o_))) - o_ := add(o_, 0x20) - if iszero(lt(o_, _e)) { break } - } - } - let clientDataJSON := mload(add(0x20, auth)) - let c := mload(add(0x40, auth)) // `challengeIndex`. - let t := mload(add(0x60, auth)) // `typeIndex`. - // If none of the lengths are more than `0xffff`. - if iszero(shr(16, or(or(t, c), or(mload(mload(auth)), mload(clientDataJSON))))) { - result := mload(0x40) - // `authenticatorData`, `clientDataJSON`. - let o := copyBytes(copyBytes(add(result, 0x20), mload(auth), 2), clientDataJSON, 0) - mstore(o, or(shl(240, c), shl(224, t))) // `challengeIndex`, `typeIndex`. - mstore(add(o, 0x04), mload(add(0x80, auth))) // `r`. - mstore(add(o, 0x24), mload(add(0xa0, auth))) // `s`. - mstore(result, sub(add(o, 0x24), result)) // Store the length. - mstore(add(o, 0x44), 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x64)) // Allocate memory . - } - } - } - - /// @dev Approximately the same gas as `tryDecodeAuth`, but helps save on calldata. - /// If any fields cannot be successfully extracted, `decoded` will not be populated, - /// which will cause `verify` to return false (as `clientDataJSON` is empty). - function tryDecodeAuthCompact(bytes memory encodedAuth) - internal - pure - returns (WebAuthnAuth memory decoded) - { - /// @solidity memory-safe-assembly - assembly { - function extractBytes(o_, l_) -> _m { - _m := mload(0x40) // Grab the free memory pointer. - let s_ := add(_m, 0x20) - for { let i_ := 0 } 1 {} { - mstore(add(s_, i_), mload(add(o_, i_))) - i_ := add(i_, 0x20) - if iszero(lt(i_, l_)) { break } - } - mstore(_m, l_) // Store the length. - mstore(add(l_, s_), 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, add(l_, s_))) // Allocate memory. - } - let n := mload(encodedAuth) - if iszero(lt(n, 0x46)) { - let o := add(encodedAuth, 0x20) // Start of `encodedAuth`'s bytes. - let e := add(o, n) // End of `encodedAuth` in memory. - n := shr(240, mload(o)) // Length of `authenticatorData`. - let a := add(o, 0x02) // Start of `authenticatorData`. - let c := add(a, n) // Start of `clientDataJSON`. - let j := sub(e, 0x44) // Start of `challengeIndex`. - if iszero(gt(c, j)) { - mstore(decoded, extractBytes(a, n)) // `authenticatorData`. - mstore(add(decoded, 0x20), extractBytes(c, sub(j, c))) // `clientDataJSON`. - mstore(add(decoded, 0x40), shr(240, mload(j))) // `challengeIndex`. - mstore(add(decoded, 0x60), shr(240, mload(add(j, 0x02)))) // `typeIndex`. - mstore(add(decoded, 0x80), mload(add(j, 0x04))) // `r`. - mstore(add(decoded, 0xa0), mload(add(j, 0x24))) // `s`. - } - } - } - } - - /// @dev Calldata variant of `tryDecodeAuthCompact`. - function tryDecodeAuthCompactCalldata(bytes calldata encodedAuth) - internal - pure - returns (WebAuthnAuth memory decoded) - { - /// @solidity memory-safe-assembly - assembly { - function extractBytes(o_, l_) -> _m { - _m := mload(0x40) // Grab the free memory pointer. - let s_ := add(_m, 0x20) - calldatacopy(s_, o_, l_) - mstore(_m, l_) // Store the length. - mstore(add(l_, s_), 0) // Zeroize the slot after the string. - mstore(0x40, add(0x20, add(l_, s_))) // Allocate memory. - } - if iszero(lt(encodedAuth.length, 0x46)) { - let e := add(encodedAuth.offset, encodedAuth.length) // End of `encodedAuth`. - let n := shr(240, calldataload(encodedAuth.offset)) // Length of `authenticatorData`. - let a := add(encodedAuth.offset, 0x02) // Start of `authenticatorData`. - let c := add(a, n) // Start of `clientDataJSON`. - let j := sub(e, 0x44) // Start of `challengeIndex`. - if iszero(gt(c, j)) { - mstore(decoded, extractBytes(a, n)) // `authenticatorData`. - mstore(add(decoded, 0x20), extractBytes(c, sub(j, c))) // `clientDataJSON`. - mstore(add(decoded, 0x40), shr(240, calldataload(j))) // `challengeIndex`. - mstore(add(decoded, 0x60), shr(240, calldataload(add(j, 0x02)))) // `typeIndex`. - mstore(add(decoded, 0x80), calldataload(add(j, 0x04))) // `r`. - mstore(add(decoded, 0xa0), calldataload(add(j, 0x24))) // `s`. - } - } - } - } -} diff --git a/grouperBot/lib/solady/src/utils/legacy/CWIA.sol b/grouperBot/lib/solady/src/utils/legacy/CWIA.sol deleted file mode 100644 index 7744e09..0000000 --- a/grouperBot/lib/solady/src/utils/legacy/CWIA.sol +++ /dev/null @@ -1,387 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Class with helper read functions for clone with immutable args. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/legacy/CWIA.sol) -/// @author Adapted from clones with immutable args by zefram.eth, Saw-mon & Natalie -/// (https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args) -abstract contract CWIA { - /// @dev Reads all of the immutable args. - function _getArgBytes() internal pure returns (bytes memory arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := mload(0x40) - let length := sub(calldatasize(), add(2, offset)) // 2 bytes are used for the length. - mstore(arg, length) // Store the length. - calldatacopy(add(arg, 0x20), offset, length) - let o := add(add(arg, 0x20), length) - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate the memory. - } - } - - /// @dev Reads an immutable arg with type bytes. - function _getArgBytes(uint256 argOffset, uint256 length) - internal - pure - returns (bytes memory arg) - { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := mload(0x40) - mstore(arg, length) // Store the length. - calldatacopy(add(arg, 0x20), add(offset, argOffset), length) - let o := add(add(arg, 0x20), length) - mstore(o, 0) // Zeroize the slot after the bytes. - mstore(0x40, add(o, 0x20)) // Allocate the memory. - } - } - - /// @dev Reads an immutable arg with type address. - function _getArgAddress(uint256 argOffset) internal pure returns (address arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(96, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads a uint256 array stored in the immutable args. - function _getArgUint256Array(uint256 argOffset, uint256 length) - internal - pure - returns (uint256[] memory arg) - { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := mload(0x40) - mstore(arg, length) // Store the length. - calldatacopy(add(arg, 0x20), add(offset, argOffset), shl(5, length)) - mstore(0x40, add(add(arg, 0x20), shl(5, length))) // Allocate the memory. - } - } - - /// @dev Reads a bytes32 array stored in the immutable args. - function _getArgBytes32Array(uint256 argOffset, uint256 length) - internal - pure - returns (bytes32[] memory arg) - { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := mload(0x40) - mstore(arg, length) // Store the length. - calldatacopy(add(arg, 0x20), add(offset, argOffset), shl(5, length)) - mstore(0x40, add(add(arg, 0x20), shl(5, length))) // Allocate the memory. - } - } - - /// @dev Reads an immutable arg with type bytes32. - function _getArgBytes32(uint256 argOffset) internal pure returns (bytes32 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := calldataload(add(offset, argOffset)) - } - } - - /// @dev Reads an immutable arg with type uint256. - function _getArgUint256(uint256 argOffset) internal pure returns (uint256 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := calldataload(add(offset, argOffset)) - } - } - - /// @dev Reads an immutable arg with type uint248. - function _getArgUint248(uint256 argOffset) internal pure returns (uint248 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(8, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint240. - function _getArgUint240(uint256 argOffset) internal pure returns (uint240 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(16, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint232. - function _getArgUint232(uint256 argOffset) internal pure returns (uint232 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(24, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint224. - function _getArgUint224(uint256 argOffset) internal pure returns (uint224 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(0x20, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint216. - function _getArgUint216(uint256 argOffset) internal pure returns (uint216 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(40, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint208. - function _getArgUint208(uint256 argOffset) internal pure returns (uint208 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(48, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint200. - function _getArgUint200(uint256 argOffset) internal pure returns (uint200 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(56, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint192. - function _getArgUint192(uint256 argOffset) internal pure returns (uint192 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(64, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint184. - function _getArgUint184(uint256 argOffset) internal pure returns (uint184 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(72, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint176. - function _getArgUint176(uint256 argOffset) internal pure returns (uint176 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(80, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint168. - function _getArgUint168(uint256 argOffset) internal pure returns (uint168 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(88, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint160. - function _getArgUint160(uint256 argOffset) internal pure returns (uint160 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(96, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint152. - function _getArgUint152(uint256 argOffset) internal pure returns (uint152 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(104, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint144. - function _getArgUint144(uint256 argOffset) internal pure returns (uint144 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(112, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint136. - function _getArgUint136(uint256 argOffset) internal pure returns (uint136 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(120, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint128. - function _getArgUint128(uint256 argOffset) internal pure returns (uint128 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(128, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint120. - function _getArgUint120(uint256 argOffset) internal pure returns (uint120 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(136, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint112. - function _getArgUint112(uint256 argOffset) internal pure returns (uint112 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(144, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint104. - function _getArgUint104(uint256 argOffset) internal pure returns (uint104 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(152, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint96. - function _getArgUint96(uint256 argOffset) internal pure returns (uint96 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(160, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint88. - function _getArgUint88(uint256 argOffset) internal pure returns (uint88 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(168, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint80. - function _getArgUint80(uint256 argOffset) internal pure returns (uint80 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(176, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint72. - function _getArgUint72(uint256 argOffset) internal pure returns (uint72 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(184, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint64. - function _getArgUint64(uint256 argOffset) internal pure returns (uint64 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(192, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint56. - function _getArgUint56(uint256 argOffset) internal pure returns (uint56 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(200, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint48. - function _getArgUint48(uint256 argOffset) internal pure returns (uint48 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(208, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint40. - function _getArgUint40(uint256 argOffset) internal pure returns (uint40 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(216, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint32. - function _getArgUint32(uint256 argOffset) internal pure returns (uint32 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(224, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint24. - function _getArgUint24(uint256 argOffset) internal pure returns (uint24 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(232, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint16. - function _getArgUint16(uint256 argOffset) internal pure returns (uint16 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(240, calldataload(add(offset, argOffset))) - } - } - - /// @dev Reads an immutable arg with type uint8. - function _getArgUint8(uint256 argOffset) internal pure returns (uint8 arg) { - uint256 offset = _getImmutableArgsOffset(); - /// @solidity memory-safe-assembly - assembly { - arg := shr(248, calldataload(add(offset, argOffset))) - } - } - - /// @return offset The offset of the packed immutable args in calldata. - function _getImmutableArgsOffset() internal pure returns (uint256 offset) { - /// @solidity memory-safe-assembly - assembly { - offset := sub(calldatasize(), shr(240, calldataload(sub(calldatasize(), 2)))) - } - } -} diff --git a/grouperBot/lib/solady/src/utils/legacy/LibCWIA.sol b/grouperBot/lib/solady/src/utils/legacy/LibCWIA.sol deleted file mode 100644 index c00dbe2..0000000 --- a/grouperBot/lib/solady/src/utils/legacy/LibCWIA.sol +++ /dev/null @@ -1,387 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @notice Clones with immutable args (CWIA) deployment library -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/legacy/CWIA.sol) -/// @author Clones with immutable args by wighawag, zefram.eth, Saw-mon & Natalie -/// (https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args) -/// -/// @dev -/// The implementation of CWIA here implements a `receive()` method that emits the -/// `ReceiveETH(uint256)` event. This skips the `DELEGATECALL` when there is no calldata, -/// enabling us to accept hard gas-capped `sends` & `transfers` for maximum backwards -/// composability. The minimal proxy implementation does not offer this feature. -library LibCWIA { - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CUSTOM ERRORS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Unable to deploy the clone. - error DeploymentFailed(); - - /// @dev The salt must start with either the zero address or `by`. - error SaltDoesNotStartWith(); - - /// @dev The ETH transfer has failed. - error ETHTransferFailed(); - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* CLONES WITH IMMUTABLE ARGS OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - // Note: This implementation of CWIA differs from the original implementation. - // If the calldata is empty, it will emit a `ReceiveETH(uint256)` event and skip the `DELEGATECALL`. - - /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `data`. - function clone(address implementation, bytes memory data) internal returns (address instance) { - instance = clone(0, implementation, data); - } - - /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `data`. - /// Deposits `value` ETH during deployment. - function clone(uint256 value, address implementation, bytes memory data) - internal - returns (address instance) - { - assembly { - // Compute the boundaries of the data and cache the memory slots around it. - let mBefore3 := mload(sub(data, 0x60)) - let mBefore2 := mload(sub(data, 0x40)) - let mBefore1 := mload(sub(data, 0x20)) - let dataLength := mload(data) - let dataEnd := add(add(data, 0x20), dataLength) - let mAfter1 := mload(dataEnd) - - // +2 bytes for telling how much data there is appended to the call. - let extraLength := add(dataLength, 2) - // The `creationSize` is `extraLength + 108` - // The `runSize` is `creationSize - 10`. - - /** - * ---------------------------------------------------------------------------------------------------+ - * CREATION (10 bytes) | - * ---------------------------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------------------------| - * 61 runSize | PUSH2 runSize | r | | - * 3d | RETURNDATASIZE | 0 r | | - * 81 | DUP2 | r 0 r | | - * 60 offset | PUSH1 offset | o r 0 r | | - * 3d | RETURNDATASIZE | 0 o r 0 r | | - * 39 | CODECOPY | 0 r | [0..runSize): runtime code | - * f3 | RETURN | | [0..runSize): runtime code | - * ---------------------------------------------------------------------------------------------------| - * RUNTIME (98 bytes + extraLength) | - * ---------------------------------------------------------------------------------------------------| - * Opcode | Mnemonic | Stack | Memory | - * ---------------------------------------------------------------------------------------------------| - * | - * ::: if no calldata, emit event & return w/o `DELEGATECALL` ::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 60 0x2c | PUSH1 0x2c | 0x2c cds | | - * 57 | JUMPI | | | - * 34 | CALLVALUE | cv | | - * 3d | RETURNDATASIZE | 0 cv | | - * 52 | MSTORE | | [0..0x20): callvalue | - * 7f sig | PUSH32 0x9e.. | sig | [0..0x20): callvalue | - * 59 | MSIZE | 0x20 sig | [0..0x20): callvalue | - * 3d | RETURNDATASIZE | 0 0x20 sig | [0..0x20): callvalue | - * a1 | LOG1 | | [0..0x20): callvalue | - * 00 | STOP | | [0..0x20): callvalue | - * 5b | JUMPDEST | | | - * | - * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds | | - * 3d | RETURNDATASIZE | 0 cds | | - * 3d | RETURNDATASIZE | 0 0 cds | | - * 37 | CALLDATACOPY | | [0..cds): calldata | - * | - * ::: keep some values in stack :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 0 0 | [0..cds): calldata | - * 3d | RETURNDATASIZE | 0 0 0 0 | [0..cds): calldata | - * 61 extra | PUSH2 extra | e 0 0 0 0 | [0..cds): calldata | - * | - * ::: copy extra data to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 80 | DUP1 | e e 0 0 0 0 | [0..cds): calldata | - * 60 0x62 | PUSH1 0x62 | 0x62 e e 0 0 0 0 | [0..cds): calldata | - * 36 | CALLDATASIZE | cds 0x62 e e 0 0 0 0 | [0..cds): calldata | - * 39 | CODECOPY | e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * | - * ::: delegate call to the implementation contract ::::::::::::::::::::::::::::::::::::::::::::::::: | - * 36 | CALLDATASIZE | cds e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * 01 | ADD | cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * 3d | RETURNDATASIZE | 0 cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * 73 addr | PUSH20 addr | addr 0 cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * 5a | GAS | gas addr 0 cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * f4 | DELEGATECALL | success 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * | - * ::: copy return data to memory ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 3d | RETURNDATASIZE | rds success 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * 3d | RETURNDATASIZE | rds rds success 0 0 | [0..cds): calldata, [cds..cds+e): extraData | - * 93 | SWAP4 | 0 rds success 0 rds | [0..cds): calldata, [cds..cds+e): extraData | - * 80 | DUP1 | 0 0 rds success 0 rds | [0..cds): calldata, [cds..cds+e): extraData | - * 3e | RETURNDATACOPY | success 0 rds | [0..rds): returndata | - * | - * 60 0x60 | PUSH1 0x60 | 0x60 success 0 rds | [0..rds): returndata | - * 57 | JUMPI | 0 rds | [0..rds): returndata | - * | - * ::: revert ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * fd | REVERT | | [0..rds): returndata | - * | - * ::: return ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | - * 5b | JUMPDEST | 0 rds | [0..rds): returndata | - * f3 | RETURN | | [0..rds): returndata | - * ---------------------------------------------------------------------------------------------------+ - */ - mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. - mstore(sub(data, 0x0d), implementation) // Write the address of the implementation. - // Write the rest of the bytecode. - mstore( - sub(data, 0x21), - or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) - ) - // `keccak256("ReceiveETH(uint256)")` - mstore( - sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff - ) - mstore( - // Do a out-of-gas revert if `extraLength` is too big. 0xffff - 0x62 + 0x01 = 0xff9e. - // The actual EVM limit may be smaller and may change over time. - sub(data, add(0x59, lt(extraLength, 0xff9e))), - or(shl(0x78, add(extraLength, 0x62)), 0xfd6100003d81600a3d39f336602c57343d527f) - ) - mstore(dataEnd, shl(0xf0, extraLength)) - - instance := create(value, sub(data, 0x4c), add(extraLength, 0x6c)) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - - // Restore the overwritten memory surrounding `data`. - mstore(dataEnd, mAfter1) - mstore(data, dataLength) - mstore(sub(data, 0x20), mBefore1) - mstore(sub(data, 0x40), mBefore2) - mstore(sub(data, 0x60), mBefore3) - } - } - - /// @dev Deploys a deterministic clone of `implementation` - /// with immutable arguments encoded in `data` and `salt`. - function cloneDeterministic(address implementation, bytes memory data, bytes32 salt) - internal - returns (address instance) - { - instance = cloneDeterministic(0, implementation, data, salt); - } - - /// @dev Deploys a deterministic clone of `implementation` - /// with immutable arguments encoded in `data` and `salt`. - function cloneDeterministic( - uint256 value, - address implementation, - bytes memory data, - bytes32 salt - ) internal returns (address instance) { - assembly { - // Compute the boundaries of the data and cache the memory slots around it. - let mBefore3 := mload(sub(data, 0x60)) - let mBefore2 := mload(sub(data, 0x40)) - let mBefore1 := mload(sub(data, 0x20)) - let dataLength := mload(data) - let dataEnd := add(add(data, 0x20), dataLength) - let mAfter1 := mload(dataEnd) - - // +2 bytes for telling how much data there is appended to the call. - let extraLength := add(dataLength, 2) - - mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. - mstore(sub(data, 0x0d), implementation) // Write the address of the implementation. - // Write the rest of the bytecode. - mstore( - sub(data, 0x21), - or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) - ) - // `keccak256("ReceiveETH(uint256)")` - mstore( - sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff - ) - mstore( - // Do a out-of-gas revert if `extraLength` is too big. 0xffff - 0x62 + 0x01 = 0xff9e. - // The actual EVM limit may be smaller and may change over time. - sub(data, add(0x59, lt(extraLength, 0xff9e))), - or(shl(0x78, add(extraLength, 0x62)), 0xfd6100003d81600a3d39f336602c57343d527f) - ) - mstore(dataEnd, shl(0xf0, extraLength)) - - instance := create2(value, sub(data, 0x4c), add(extraLength, 0x6c), salt) - if iszero(instance) { - mstore(0x00, 0x30116425) // `DeploymentFailed()`. - revert(0x1c, 0x04) - } - - // Restore the overwritten memory surrounding `data`. - mstore(dataEnd, mAfter1) - mstore(data, dataLength) - mstore(sub(data, 0x20), mBefore1) - mstore(sub(data, 0x40), mBefore2) - mstore(sub(data, 0x60), mBefore3) - } - } - - /// @dev Returns the initialization code hash of the clone of `implementation` - /// using immutable arguments encoded in `data`. - function initCode(address implementation, bytes memory data) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let dataLength := mload(data) - - // Do a out-of-gas revert if `dataLength` is too big. 0xffff - 0x02 - 0x62 = 0xff9b. - // The actual EVM limit may be smaller and may change over time. - returndatacopy(returndatasize(), returndatasize(), gt(dataLength, 0xff9b)) - - let o := add(result, 0x8c) - let end := add(o, dataLength) - - // Copy the `data` into `result`. - for { let d := sub(add(data, 0x20), o) } 1 {} { - mstore(o, mload(add(o, d))) - o := add(o, 0x20) - if iszero(lt(o, end)) { break } - } - - // +2 bytes for telling how much data there is appended to the call. - let extraLength := add(dataLength, 2) - - mstore(add(result, 0x6c), 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. - mstore(add(result, 0x5f), implementation) // Write the address of the implementation. - // Write the rest of the bytecode. - mstore( - add(result, 0x4b), - or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) - ) - // `keccak256("ReceiveETH(uint256)")` - mstore( - add(result, 0x32), - 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff - ) - mstore( - add(result, 0x12), - or(shl(0x78, add(extraLength, 0x62)), 0x6100003d81600a3d39f336602c57343d527f) - ) - mstore(end, shl(0xf0, extraLength)) - mstore(add(end, 0x02), 0) // Zeroize the slot after the result. - mstore(result, add(extraLength, 0x6c)) // Store the length. - mstore(0x40, add(0x22, end)) // Allocate memory. - } - } - - /// @dev Returns the initialization code hash of the clone of `implementation` - /// using immutable arguments encoded in `data`. - /// Used for mining vanity addresses with create2crunch. - function initCodeHash(address implementation, bytes memory data) - internal - pure - returns (bytes32 hash) - { - assembly { - // Compute the boundaries of the data and cache the memory slots around it. - let mBefore3 := mload(sub(data, 0x60)) - let mBefore2 := mload(sub(data, 0x40)) - let mBefore1 := mload(sub(data, 0x20)) - let dataLength := mload(data) - let dataEnd := add(add(data, 0x20), dataLength) - let mAfter1 := mload(dataEnd) - - // Do a out-of-gas revert if `dataLength` is too big. 0xffff - 0x02 - 0x62 = 0xff9b. - // The actual EVM limit may be smaller and may change over time. - returndatacopy(returndatasize(), returndatasize(), gt(dataLength, 0xff9b)) - - // +2 bytes for telling how much data there is appended to the call. - let extraLength := add(dataLength, 2) - - mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. - mstore(sub(data, 0x0d), implementation) // Write the address of the implementation. - // Write the rest of the bytecode. - mstore( - sub(data, 0x21), - or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) - ) - // `keccak256("ReceiveETH(uint256)")` - mstore( - sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff - ) - mstore( - sub(data, 0x5a), - or(shl(0x78, add(extraLength, 0x62)), 0x6100003d81600a3d39f336602c57343d527f) - ) - mstore(dataEnd, shl(0xf0, extraLength)) - - hash := keccak256(sub(data, 0x4c), add(extraLength, 0x6c)) - - // Restore the overwritten memory surrounding `data`. - mstore(dataEnd, mAfter1) - mstore(data, dataLength) - mstore(sub(data, 0x20), mBefore1) - mstore(sub(data, 0x40), mBefore2) - mstore(sub(data, 0x60), mBefore3) - } - } - - /// @dev Returns the address of the deterministic clone of - /// `implementation` using immutable arguments encoded in `data`, with `salt`, by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddress( - address implementation, - bytes memory data, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - bytes32 hash = initCodeHash(implementation, data); - predicted = predictDeterministicAddress(hash, salt, deployer); - } - - /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ - /* OTHER OPERATIONS */ - /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - - /// @dev Returns the address when a contract with initialization code hash, - /// `hash`, is deployed with `salt`, by `deployer`. - /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. - function predictDeterministicAddress(bytes32 hash, bytes32 salt, address deployer) - internal - pure - returns (address predicted) - { - /// @solidity memory-safe-assembly - assembly { - // Compute and store the bytecode hash. - mstore8(0x00, 0xff) // Write the prefix. - mstore(0x35, hash) - mstore(0x01, shl(96, deployer)) - mstore(0x15, salt) - predicted := keccak256(0x00, 0x55) - mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. - } - } - - /// @dev Requires that `salt` starts with either the zero address or `by`. - function checkStartsWith(bytes32 salt, address by) internal pure { - /// @solidity memory-safe-assembly - assembly { - // If the salt does not start with the zero address or `by`. - if iszero(or(iszero(shr(96, salt)), eq(shr(96, shl(96, by)), shr(96, salt)))) { - mstore(0x00, 0x0c4549ef) // `SaltDoesNotStartWith()`. - revert(0x1c, 0x04) - } - } - } -} diff --git a/grouperBot/lib/solady/test/Base58.t.sol b/grouperBot/lib/solady/test/Base58.t.sol deleted file mode 100644 index dd61b22..0000000 --- a/grouperBot/lib/solady/test/Base58.t.sol +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {Base58} from "../src/utils/Base58.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract Base58Test is SoladyTest { - function testBase58DecodeRevertsIfInvalidCharacter(bytes1 c) public { - if (isValidBase58Character(c)) { - this.base58DecodeRevertsIfInvalidCharacter(c); - } else { - vm.expectRevert(Base58.Base58DecodingError.selector); - this.base58DecodeRevertsIfInvalidCharacter(c); - } - } - - function isValidBase58Character(bytes1 c) internal pure returns (bool) { - bytes memory allowed = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; - for (uint256 i; i < allowed.length; ++i) { - if (allowed[i] == c) return true; - } - return false; - } - - function base58DecodeRevertsIfInvalidCharacter(bytes1 c) public { - emit LogBytes(Base58.decode(string(abi.encodePacked(c)))); - } - - function testBase58EncodeDecode(bytes memory data, uint256 r) public { - if (r & 0x00f == 0) { - _brutalizeMemory(); - } - if (r & 0x0f0 == 0) { - _misalignFreeMemoryPointer(); - } - if (r & 0xf00 == 0) { - data = abi.encodePacked(new bytes(_bound(_random(), 0, 128)), data); - } - - uint256 h; - uint256 m; - /// @solidity memory-safe-assembly - assembly { - // Since `encode` writes memory backwards, we do some extra checks to ensure - // that the initial length overestimate is sufficient. - mstore(0x00, r) - mstore(0x20, "hehe") - h := keccak256(0x00, 0x40) - m := mload(0x40) - mstore(m, h) - mstore(0x40, add(m, 0x20)) - } - string memory encoded = Base58.encode(data); - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(mload(m), h)) { invalid() } - } - - _checkMemory(encoded); - if (r & 0x00f000 == 0) { - _brutalizeMemory(); - } - if (r & 0x0f0000 == 0) { - _misalignFreeMemoryPointer(); - } - - /// @solidity memory-safe-assembly - assembly { - // Since `decode` writes memory backwards, we do some extra checks to ensure - // that the initial length overestimate is sufficient. - mstore(0x00, r) - mstore(0x20, "haha") - h := keccak256(0x00, 0x40) - m := mload(0x40) - mstore(m, h) - mstore(0x40, add(m, 0x20)) - } - bytes memory decoded = Base58.decode(encoded); - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(mload(m), h)) { invalid() } - } - - _checkMemory(decoded); - assertEq(data, decoded); - } - - function testBase58EncodeDecode() public { - this._testBase58EncodeDecode(hex"", ""); - this._testBase58EncodeDecode(hex"0d", "E"); - this._testBase58EncodeDecode(hex"000e", "1F"); - this._testBase58EncodeDecode(hex"00f3", "15C"); - this._testBase58EncodeDecode(hex"00", "1"); - this._testBase58EncodeDecode(hex"f2", "5B"); - this._testBase58EncodeDecode(hex"0002da", "1Db"); - this._testBase58EncodeDecode(hex"0027b9", "142L"); - this._testBase58EncodeDecode(hex"00d80f", "1HSe"); - this._testBase58EncodeDecode(hex"ce", "4Z"); - this._testBase58EncodeDecode(hex"7c", "39"); - this._testBase58EncodeDecode(hex"cd0b5dfe722552f609ce", "CX9VkoSqX63kbo"); - this._testBase58EncodeDecode( - hex"00598b3dc0966af86beb7898fc9921c2fbc38a19d52dee9dfed69e3d", - "1D6w66tNCxvikkpma3BXnRnABJQojACXjHxtdJ" - ); - this._testBase58EncodeDecode( - hex"09100a2fc14628f168c2c9b980fb840857fbb9fe031013c9bf7e218d5c", - "Qs1VMdvTSeZkZ5p4e4xQaLa8J3ptpJzJAcM1Mp7" - ); - this._testBase58EncodeDecode( - hex"001d85089c34888205378be7e8f9ff5e2f", "14eRVxHMi5hh14FM9Gpd1Ua" - ); - this._testBase58EncodeDecode( - hex"0090ccbb306b1cc8f226e905623d19604fd0ad73bd80b8b4712e", - "121GLNsu9Tdp147zdSjFvJudL1pp1Qv39myF" - ); - this._testBase58EncodeDecode(hex"012ee97bcab1", "bB9gNQp"); - this._testBase58EncodeDecode( - hex"00f91f623af2d76e8ee2abdbfe5e3671373ad4736d2433397c93e08e63e9ce1830", - "1HmUGpDZUwcvX5xPMNQ9oHoMz8nKQF6EWgqno2iSXQJc7" - ); - this._testBase58EncodeDecode( - hex"00000000000000000000000000000000000000000000000000000000000000fb53beb02ab2ab6583638677b592b2b56f321d94972b38acfd6d4cd1202f77ff1fddf68b9d2c4bdb1b6ced6ef31e282e48790854ce9c0ab93435761d0f5db1e16817119e682391a23f633d9cdd6481a07585ec17d6aeca0849eab41f5895cfc4e9503f97345a364964d7e024c947ae7c238d1a4705", - "1111111111111111111111111111111QVs5qPAkBrBEtm1UXSAcNGHgA6cUYDn4oAXAxgEQ5jntH1aWoie6t7a1j2RTmP4E5uGFpWwTUj7zyeKcs7BKMXJBRXHuokJ13KmbHC6RLtAbUdobwBcjx2UjCK5rPwVBjABFvjgGAaFFwEZgnRPudGLqLqJdCx6G" - ); - this._testBase58EncodeDecode( - hex"000000000000000000000000000000000000000031f89a3264997ab236bf9c5200a5353c4e04a134ad572583a140f9c3cc7d4f3f6331716c", - "11111111111111111111P1So9spX62PHGLRTG8SgU1Lm19f6SgCozbp8Use7LdcMGYAKD" - ); - this._testBase58EncodeDecode( - hex"000000000000000000000013bc3b22341190c36a1cda2a0a1ed6f93a080447160b626b2f711c9a266bdc17622794eb9d", - "11111111111fN3TfvHm4xfWWJT7FqjTP9WXJiCoKJejeRgQmU6LcWUgJezrH2" - ); - this._testBase58EncodeDecode( - hex"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b1859e09c90d4ac3dd4c89c3c2452b4d22c92d0eee246e75d72d7209078d5230159b5e52249d5b6017e6992696028d390c61d26c0d42395072378ad89df7b94dbef0624cd0e1e091829c6292e9cf8303b43bec", - "1111111111111111111111111111111111111111111111111113sLfBS3DP3qb3hQoRZDt1DotgrCJU5N17jh4bFG6cs5KGz4Z1wqWJC6bHVbgKYXAUMVvoqFbZAzC5Rg95xvsbmhTLkuH3jbPkqiXuGcRm2wGmiom8f" - ); - this._testBase58EncodeDecode( - hex"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000322a08fd25e4a383cf093664c6a28531bdfa2e6d3a0afdddae9a58fe1074642f979d6cc1dd196e77d63fac03e9e52815bb211a760e37470b006e9682a8d432", - "11111111111111111111111111111111111111111111111111111111111EBQAEDu1wmQTkQGGtoxiwzZzxPp3q6jswQS8BoqBuKzxhmVg8ThLq8Z6HjrcBPX5BsGYWTA7sjHP9CeASeFEsj" - ); - this._testBase58EncodeDecode( - hex"00000000000000c305c2e9ca1fed1817ff8ddc60fb26b5665ce958f9cbeb3f907e6ae500d5917d24b3b30b0d9e382e9521eeb232c7f5d328f0e239cec44d21d49472727a1ec7555580c88f2776", - "11111119a4d2p5cardGk5zgtKRV5xmbugoNWw3fp8eWTq3sjbVTYr7aXiE3wGzqe5bGgusiYsBzvdPibo5BVNxaxudCXc6WkikU8xwP" - ); - this._testBase58EncodeDecode( - hex"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fcee37b107ba13473fff385e60e48f7085c72ca9fa64af6c21a568a281161db2af9844f52867ea6048a502da3dd827158b199f1c7e330028b849e135d7f5418923e", - "11111111111111111111111111111111111111111111111111eKPzXLFs4zguFbvYgRSoJDb6mTyCPFhve4Yww4PNDs89z8Kxd72pkXqDix6FkN62WxgNfrNry43pbizFaUuzaExHCy" - ); - this._testBase58EncodeDecode( - hex"00000013dff1618a82531e334a62f0de8f17c074732abf4c59cd7c", - "1112p67UFfiuvQD92aDbWzpm1Z5EU6Q8TtpB" - ); - this._testBase58EncodeDecode( - hex"00000000000000000000003fd220658684b1ccef6552", "11111111111GpuXVbXqt99pach" - ); - this._testBase58EncodeDecode( - hex"0000000000000000000000000000000000000000000000000000e8271fe396fe0cf6bcc1f7881c9cbae4d147bbb61e947fb129177acd9887c0dca8348ffd2a385ecdac852073b60d7daf003d6e188c1841ddc5b68c3b9e3eda4c090f3567c54bd372676ee0ff9fbfede9", - "111111111111111111111111113Xj8EySrK3wEvmYt59y4b1vxzjGwPc688wZA4jXsyGNgEh7ghaP9ohvqseUcNUUCeqLxtyzWDPfngB1iHzjsEeaN14UjSeSZdCoWUSVHAYVtX2" - ); - this._testBase58EncodeDecode( - hex"0000000000000000000000000000000000000000000000000000000000000000000000003c58cebe89322eee5505a37a842fb64cd726c8a8adaa8a20c34de8eaff08373abe2f5912c912dde618fcb0b4a8a14da4f3fbc7d6004684fcedd7f133af9abe9360793485dbe855f3875e631c96d8ee775240cac29f2c8640aa9485f8c6b6410c0ac7fc83", - "1111111111111111111111111111111111113M2hXzVT7xgwnteR7ZsprbP5xBdDBWkkQHpVUJScKLca3WAfPSCUQ59d3a4zGU4P2Q5Dvgmz9LVbf1erXBmxLsha5PEhFmHDBpyGW5ZFSJswPtGRYQeVPWKpr3cbQbexUFsNpqVea" - ); - this._testBase58EncodeDecode( - hex"000000000000000000000000000000000000000000000000000000000000000060234520525c5c627553370b53eb6d76c7766490efc4dae6fd5c5940008b5110eb834a2168c9728d51840c4e571321d4f08391009a0c3785c6c6b9b14d774629995acf59bf07f88b2762b426ddd135516a24daf2", - "111111111111111111111111111111117rbt7xcf57aaNKwQwTxYHWqqtGYNiSM63bYVGhBKNExhvAubcT68EToxSShmawAr33vALSbua2s1xt9C6yPCXU5dGA8cr1B8GS6WXVCh24heoNrUbSR" - ); - this._testBase58EncodeDecode( - hex"000000000000000000000000000000000000000000000000000000000000000000003b4c61dee11d868b463c055521a78d6552daefdfdc3fc03216cd84667365c0346a2954fe099bdf4baea658b3cee9589c6d217f8b3642", - "11111111111111111111111111111111115nJEXtj9QijtXd2gqb9bgPvanHGcXLdhKX14UbmuitdejFDnZ5MiGpHALxfnMVvo4CbVKcPHhK" - ); - this._testBase58EncodeDecode( - hex"000000000000000000000000000013ba6b7a5b28ee62e23e2f037169950bfaa76a49cd560bf283cb7a76eab12b0766f61979108cd0bed77d37", - "111111111111112THktPmYvuwnWuVqbsNgWfAaR1dxCTi6zHB6ggkAidRRhwrrWmL3PGGCJ2J" - ); - this._testBase58EncodeDecode( - hex"000000000000000000000000000000000000000000000000000000000000000000000000000000e357a949bd269668402d9fe64611b55659fa5c077ed6896ba83c99f6362ff3ddfb145512bd7825d25d99b62f392d42c397191d91a85cb3aac3f5aba7a1f8c7c5098ea8d8e452eab896ce53510d58f64518509dc4c9a93f9feccb8040b18fc8065e9811e954c4c421264d528ae0817f4981a11bfe", - "1111111111111111111111111111111111111115pJo5spTW949hEVQhtDHsyhLcMfUC6gHCM9pPGYter8CD12cNuXbshZvtDZoFAjwjuCftRhweQ7TcuARE52aqNzC5He3rqs1YdEreCTYqoPuQDqufzeDjywYJQmkgwaLrDbhKcjUbxFVMertvBGeUkB7tDiSMBs" - ); - this._testBase58EncodeDecode( - hex"00000000000000000000000000000000000000af64ba6caafbbca128653eff8c51", - "111111111111111111127UskEy2WhgsTGAY4Qi4" - ); - this._testBase58EncodeDecode( - hex"0000000000000000000000000f744c6b510384801d5d10035f00b562f05c585aac1fe57f27b640096aafc1cb28a859d7ece16ee8c6813708193047aafd18c4", - "111111111111qkJMpKZLaSweHBvLEBUxhcB7AnaBv6QRC7mkQS54QEuh8PYp7pn7VfueHTsD4W1gF7px3" - ); - this._testBase58EncodeDecode( - hex"0000000000000000000000000000000000000000a4ae531a4546129e810fe716bef089bf466eed25dd729688c82481c3eea5cec22219d7dfcccb814a141dd14b98677f905c5efbc38f65040216f27042dcdf31ac81eff75985176ed0a40ae16eadca11464e40f16ee8fc2fd06ec6629d098759365df73073e4d4124b6003457367a484dc278b2e", - "11111111111111111111nqeSEB5S7wspidSeWX3LCxrjoSxFcAEE3C9LFix6tQHFWPMUWMSoFf2rStXF5JxarB4Dhxvnhbanz6mLyMerUKxU6WFag1vQMgCTLeeNHcRiu1srGtHB3YrVgoz6h2mAHyhs1ukVrGYmSmmKRty75Jx4zJ661" - ); - this._testBase58EncodeDecode( - hex"000000451c0d1e6a9b414cd8ee1d1fa7f7805de82932a48991c9edaf814215d069d5f1fef3a63f931792b2d113ce0a309d5e22a1d9ede1cca2e7e358e9d2600498f2e9a0c8159cebffa293512fe5b0f3d9971bb2a07d1b7df5f81af612141e4693147428285c21621c8e772a627ca1a9", - "1119kd1Rja2XCCMQDiRBv7EEX5upePsrmhBRHL4kkK8oBR3dSvVE4yuRtUzZKmtvWiBUD6qFk3HCoWpDapRw7WhBi3qR94ZeLkFuAZbqN4D2N4V6AgLdh2n1JwM3Z8i9quwNPHY4TNU2B2NYwZ2tons2" - ); - this._testBase58EncodeDecode( - hex"0000000000000000000000000000cc50f101efa6b062341bdc59edc70e9776728db82f5779100210d5907ebbe56673ef72e013987a297d560ad9e2229c508ce3568e5dd0f61e671e15f21521f9206a435c634b1f0d254326965d6c6eac24aec4b7fecc84b753d76d4e1bca902d662deb23a678f6cc1811", - "111111111111114xLrKJa5yzRCpMhRUMMv6WoK9hkibnv9rVbDQgxq5oWvSUv3UBJUjQ5xeFapu4ZZ4nDoi1C34c115cirJd5f1LucLojD45CuiGWNbCFQsPcQPfpkheZe1b5xWGsBPZzvZHxUaik4YAtk5sEg" - ); - } - - function _testBase58EncodeDecode(bytes memory data, string memory expectedEncoded) public { - string memory encoded = Base58.encode(data); - assertEq(expectedEncoded, encoded); - bytes memory decoded = Base58.decode(encoded); - assertEq(data, decoded); - } - - function testCarryBoundsTrick(uint248 limb, uint8 carry) public pure { - if (carry < 58) { - uint256 acc = uint256(limb) * 58 + uint256(carry); - assert((acc >> 248) < 58); - } - } - - function check_CarryBoundsTrick(uint248 limb, uint8 carry) public pure { - testCarryBoundsTrick(limb, carry); - } - - function testEncodeWordDifferential(bytes32 word) public { - string memory expected = Base58.encode(abi.encodePacked(word)); - string memory computed = Base58.encodeWord(word); - assertEq(computed, expected); - } - - function testEncodeDecodeWord(bytes32 word) public { - string memory encoded = Base58.encodeWord(word); - assertEq(Base58.decodeWord(encoded), word); - } - - function testDecodeWordDifferential(bytes32 word) public { - string memory encoded = Base58.encodeWord(word); - bytes32 expected = _decodeWordOriginal(encoded); - bytes32 computed = Base58.decodeWord(encoded); - _checkMemory(); - assertEq(computed, expected); - } - - function testDecodeWordOverflowsReverts() public { - bytes32 expected = bytes32(type(uint256).max); - assertEq(this.decodeWord("JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG"), expected); - assertEq(this.decodeWord("1JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG"), expected); - assertEq(this.decodeWord("11JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG"), expected); - - vm.expectRevert(Base58.Base58DecodingError.selector); - this.decodeWord("JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFH"); - vm.expectRevert(Base58.Base58DecodingError.selector); - this.decodeWord("JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFJ"); - } - - function testDecodeWordInvalidCharacterReverts() public { - vm.expectRevert(Base58.Base58DecodingError.selector); - this.decodeWord("JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFH@"); - } - - function decodeWord(string memory encoded) public pure returns (bytes32) { - return Base58.decodeWord(encoded); - } - - function _decodeWordOriginal(string memory encoded) internal pure returns (bytes32 result) { - bytes memory t = Base58.decode(encoded); - /// @solidity memory-safe-assembly - assembly { - let n := mload(t) - if iszero(lt(n, 0x21)) { - mstore(0x00, 0xe8fad793) // `Base58DecodingError()`. - revert(0x1c, 0x04) - } - result := mload(add(t, n)) - } - } - - function testDecodeWordGas() public { - bytes32 expected = bytes32(type(uint256).max); - assertEq(Base58.decodeWord("JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG"), expected); - } - - function testDecodeGas() public { - bytes memory expected = abi.encodePacked(type(uint256).max); - assertEq(Base58.decode("JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG"), expected); - } -} diff --git a/grouperBot/lib/solady/test/Base64.t.sol b/grouperBot/lib/solady/test/Base64.t.sol deleted file mode 100644 index 727128a..0000000 --- a/grouperBot/lib/solady/test/Base64.t.sol +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {Base64} from "../src/utils/Base64.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract Base64Test is SoladyTest { - function testBase64EncodeEmptyString() public { - _testBase64Encode("", ""); - } - - function testBase64EncodeShortStrings() public { - _testBase64Encode("M", "TQ=="); - _testBase64Encode("Mi", "TWk="); - _testBase64Encode("Mil", "TWls"); - _testBase64Encode("Mila", "TWlsYQ=="); - _testBase64Encode("Milad", "TWlsYWQ="); - _testBase64Encode("Milady", "TWlsYWR5"); - } - - function testBase64EncodeToStringWithDoublePadding() public { - _testBase64Encode("test", "dGVzdA=="); - } - - function testBase64EncodeToStringWithSinglePadding() public { - _testBase64Encode("test1", "dGVzdDE="); - } - - function testBase64EncodeToStringWithNoPadding() public { - _testBase64Encode("test12", "dGVzdDEy"); - } - - function testBase64EncodeSentence() public { - _testBase64Encode( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", - "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=" - ); - } - - function testBase64WordBoundary() public { - // Base64.encode allocates memory in multiples of 32 bytes. - // This checks if the amount of memory allocated is enough. - _testBase64Encode("012345678901234567890", "MDEyMzQ1Njc4OTAxMjM0NTY3ODkw"); - _testBase64Encode("0123456789012345678901", "MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMQ=="); - _testBase64Encode("01234567890123456789012", "MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="); - _testBase64Encode("012345678901234567890123", "MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz"); - _testBase64Encode("0123456789012345678901234", "MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNA=="); - } - - function _testBase64Encode(string memory input, string memory output) private { - assertEq(Base64.encode(_withDirtyEndBits(bytes(input))), output); - } - - function _withDirtyEndBits(bytes memory input) private view returns (bytes memory output) { - /// @solidity memory-safe-assembly - assembly { - output := mload(0x40) - let n := mload(input) - - mstore(0x00, gas()) - let r := keccak256(0x00, 0x60) - mstore(add(output, add(0x20, n)), r) - mstore(add(output, add(0x40, n)), r) - - pop(staticcall(gas(), 4, input, add(0x20, n), output, add(0x20, n))) - - mstore(0x40, add(output, add(0x40, n))) - } - } - - function testBase64EncodeDecode(bytes memory input) public { - string memory encoded = Base64.encode(input); - bytes memory decoded = Base64.decode(encoded); - - assertEq(input, decoded); - } - - function testBase64DecodeShortStringGas() public { - assertEq(Base64.decode("TWlsYWR5").length, 6); - } - - function testBase64DecodeSentenceGas() public { - assertEq( - Base64.decode( - "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=" - ).length, - 56 - ); - } - - function testBase64EncodeDecodeAltModes(bytes memory input) public brutalizeMemory { - for (uint256 i; i < 2; ++i) { - _misalignFreeMemoryPointer(); - if (_randomChance(2)) { - input = _withDirtyEndBits(input); - } - string memory encoded = Base64.encode(input); - _checkMemory(encoded); - - if (_random() & 1 == 0) { - encoded = LibString.replace(encoded, "=", ""); - } - if (_random() & 1 == 0) { - encoded = LibString.replace(encoded, "/", ","); - } - if (_random() & 1 == 0) { - encoded = LibString.replace(encoded, "/", "_"); - } - if (_random() & 1 == 0) { - encoded = LibString.replace(encoded, "+", "-"); - } - - _misalignFreeMemoryPointer(); - bytes memory decoded = Base64.decode(encoded); - _checkMemory(decoded); - - assertEq(input, decoded); - - input = abi.encode(encoded); - } - } - - function testBase64EncodeFileSafeAndNoPadding(bytes memory input, bool fileSafe, bool noPadding) - public - { - string memory expectedEncoded = Base64.encode(input); - - if (fileSafe) { - expectedEncoded = LibString.replace(expectedEncoded, "+", "-"); - expectedEncoded = LibString.replace(expectedEncoded, "/", "_"); - } - if (noPadding) { - expectedEncoded = LibString.replace(expectedEncoded, "=", ""); - } - - assertEq(Base64.encode(input, fileSafe, noPadding), expectedEncoded); - } -} diff --git a/grouperBot/lib/solady/test/BlockHashLib.t.sol b/grouperBot/lib/solady/test/BlockHashLib.t.sol deleted file mode 100644 index c372aa8..0000000 --- a/grouperBot/lib/solady/test/BlockHashLib.t.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {BlockHashLib} from "../src/utils/BlockHashLib.sol"; - -contract BlockHashLibTest is SoladyTest { - uint256 internal startingBlock; - - address internal constant SYSTEM_ADDRESS = 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE; - - bytes private constant _HISTORY_STORAGE_BYTECODE = - hex"3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500"; - - function testBlockHash( - uint256 simulationBlockNumber, - uint256 queryBlockNumber, - uint256 savedBlockedNumber, - bytes32 hashToSave - ) public { - if (_randomChance(2)) { - vm.etch(BlockHashLib.HISTORY_STORAGE_ADDRESS, _HISTORY_STORAGE_BYTECODE); - } - - savedBlockedNumber = _bound(savedBlockedNumber, 0, 2 ** 64 - 1); - - vm.roll(savedBlockedNumber + 1); - vm.prank(SYSTEM_ADDRESS); - (bool success,) = BlockHashLib.HISTORY_STORAGE_ADDRESS.call(abi.encode(hashToSave)); - require(success); - - vm.setBlockhash(savedBlockedNumber, hashToSave); - - vm.roll(simulationBlockNumber); - - assertEq(BlockHashLib.blockHash(queryBlockNumber), _blockHash(queryBlockNumber)); - - // Some random comment to trigger the CI via a visible diff. 3287623879676 - } - - function _blockHash(uint256 blockNumber) internal view returns (bytes32) { - (bool success, bytes memory result) = - address(this).staticcall(abi.encodeWithSignature("blockHash(uint256)", blockNumber)); - if (!success) return 0; - return abi.decode(result, (bytes32)); - } - - function blockHash(uint256 blockNumber) public view returns (bytes32 result) { - if (block.number <= blockNumber + 256) return blockhash(blockNumber); - address a = BlockHashLib.HISTORY_STORAGE_ADDRESS; - if (a.code.length == 0) return 0; - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, blockNumber) - mstore(0x00, 0) - pop(staticcall(gas(), a, 0x20, 0x20, 0x00, 0x20)) - result := mload(0x00) - } - } -} diff --git a/grouperBot/lib/solady/test/Brutalizer.t.sol b/grouperBot/lib/solady/test/Brutalizer.t.sol deleted file mode 100644 index dd120a6..0000000 --- a/grouperBot/lib/solady/test/Brutalizer.t.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; - -contract BrutalizerTest is SoladyTest { - function testBrutalizedBool(bytes32, bool x) public { - bool brutalized = _brutalized(x); - assertEq(brutalized, x); - if (x) { - for (bool isBrutalized; !isBrutalized;) { - brutalized = _brutalized(x); - assertEq(brutalized, x); - /// @solidity memory-safe-assembly - assembly { - isBrutalized := gt(brutalized, 1) - } - } - } - } - - function testBrutalizedAddress(bytes32, address x) public { - address brutalized = _brutalized(x); - assertEq(brutalized, x); - for (bool isBrutalized; !isBrutalized;) { - brutalized = _brutalized(x); - assertEq(brutalized, x); - /// @solidity memory-safe-assembly - assembly { - isBrutalized := shr(160, brutalized) - } - } - } - - function testBrutalizedUint8(bytes32, uint8 x) public { - uint8 brutalized = _brutalizedUint8(x); - assertEq(brutalized, x); - for (bool isBrutalized; !isBrutalized;) { - brutalized = _brutalizedUint8(x); - assertEq(brutalized, x); - /// @solidity memory-safe-assembly - assembly { - isBrutalized := shr(8, brutalized) - } - } - } - - function testBrutalizedUint248(bytes32, uint248 x) public { - uint248 brutalized = _brutalizedUint248(x); - assertEq(brutalized, x); - for (bool isBrutalized; !isBrutalized;) { - brutalized = _brutalizedUint248(x); - assertEq(brutalized, x); - /// @solidity memory-safe-assembly - assembly { - isBrutalized := shr(248, brutalized) - } - } - } - - function testBrutalizedBytes1(bytes32, bytes1 x) public { - bytes1 brutalized = _brutalizedBytes1(x); - assertEq(brutalized, x); - for (bool isBrutalized; !isBrutalized;) { - brutalized = _brutalizedBytes1(x); - assertEq(brutalized, x); - /// @solidity memory-safe-assembly - assembly { - isBrutalized := shl(8, brutalized) - } - } - } - - function testBrutalizedBytes31(bytes32, bytes31 x) public { - bytes31 brutalized = _brutalizedBytes31(x); - assertEq(brutalized, x); - for (bool isBrutalized; !isBrutalized;) { - brutalized = _brutalizedBytes31(x); - assertEq(brutalized, x); - /// @solidity memory-safe-assembly - assembly { - isBrutalized := shl(248, brutalized) - } - } - } -} diff --git a/grouperBot/lib/solady/test/CREATE3.t.sol b/grouperBot/lib/solady/test/CREATE3.t.sol deleted file mode 100644 index 218ee7f..0000000 --- a/grouperBot/lib/solady/test/CREATE3.t.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {WETH} from "../src/tokens/WETH.sol"; -import {MockERC20} from "./utils/mocks/MockERC20.sol"; -import {MockCd} from "./utils/mocks/MockCd.sol"; - -import {CREATE3} from "../src/utils/CREATE3.sol"; - -import "./utils/SoladyTest.sol"; - -contract CREATE3Test is SoladyTest { - function testDeployERC20() public { - bytes32 salt = keccak256(bytes("A salt!")); - - MockERC20 deployed = MockERC20( - this.deployDeterministic( - abi.encodePacked(type(MockERC20).creationCode, abi.encode("Mock Token", "MOCK", 18)), - salt - ) - ); - - assertEq(address(deployed), CREATE3.predictDeterministicAddress(salt)); - - assertEq(deployed.name(), "Mock Token"); - assertEq(deployed.symbol(), "MOCK"); - assertEq(deployed.decimals(), 18); - } - - function testDeployedUpperBitsSafeForPlainSolidity() public { - bytes32 salt = keccak256(bytes("A salt!")); - address deployed = CREATE3.predictDeterministicAddress(salt); - uint256 someNumber = 123456789; - uint256 packed = (someNumber << 160) | uint160(deployed); - uint256 someNumberUnpacked = packed >> 160; - assertEq(someNumber, someNumberUnpacked); - } - - function testDoubleDeploySameBytecodeReverts() public { - bytes32 salt = keccak256(bytes("Salty...")); - - this.deployDeterministic(type(MockCd).creationCode, salt); - vm.expectRevert(CREATE3.DeploymentFailed.selector); - this.deployDeterministic(type(MockCd).creationCode, salt); - } - - function testDoubleDeployDifferentBytecodeReverts() public { - bytes32 salt = keccak256(bytes("and sweet!")); - - this.deployDeterministic(type(WETH).creationCode, salt); - vm.expectRevert(CREATE3.DeploymentFailed.selector); - this.deployDeterministic(type(MockCd).creationCode, salt); - } - - function testDeployERC20( - bytes32 salt, - string calldata name, - string calldata symbol, - uint8 decimals - ) public { - MockERC20 deployed = MockERC20( - this.deployDeterministic( - abi.encodePacked(type(MockERC20).creationCode, abi.encode(name, symbol, decimals)), - salt - ) - ); - - assertEq(address(deployed), CREATE3.predictDeterministicAddress(salt)); - - assertEq(deployed.name(), name); - assertEq(deployed.symbol(), symbol); - assertEq(deployed.decimals(), decimals); - } - - function testDoubleDeploySameBytecodeReverts(bytes32 salt, bytes calldata bytecode) public { - bytes memory creationCode = _initCode(bytecode); - this.deployDeterministic(creationCode, salt); - vm.expectRevert(CREATE3.DeploymentFailed.selector); - this.deployDeterministic(creationCode, salt); - } - - function testDoubleDeployDifferentBytecodeReverts( - bytes32 salt, - bytes memory bytecode1, - bytes memory bytecode2 - ) public { - this.deployDeterministic(_initCode(bytecode1), salt); - vm.expectRevert(CREATE3.DeploymentFailed.selector); - this.deployDeterministic(_initCode(bytecode2), salt); - } - - function deployDeterministic(uint256 value, bytes calldata creationCode, bytes32 salt) - public - returns (address) - { - return CREATE3.deployDeterministic(value, creationCode, salt); - } - - function deployDeterministic(bytes calldata creationCode, bytes32 salt) - public - returns (address) - { - return deployDeterministic(0, creationCode, salt); - } - - function _initCode(bytes memory bytecode) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - // Trim the length if needed. - let length := mload(bytecode) - let maxLength := 24566 // `24576 - 0xa`. - if iszero(lt(length, maxLength)) { mstore(bytecode, maxLength) } - // The following snippet is from SSTORE2. - result := mload(0x40) - length := mload(bytecode) - let dataSize := add(length, 1) - mstore(0x40, and(add(add(result, dataSize), 0x60), not(0x1f))) - mstore(add(result, 0x0b), or(0x61000080600a3d393df300, shl(0x40, dataSize))) - mstore(result, add(dataSize, 0xa)) // Store the length of result. - // Copy the bytes over. - for { let i := 0 } lt(i, length) { i := add(i, 0x20) } { - mstore(add(add(bytecode, 0x20), i), mload(add(add(result, 0x2b), i))) - } - } - } -} diff --git a/grouperBot/lib/solady/test/CallContextChecker.t.sol b/grouperBot/lib/solady/test/CallContextChecker.t.sol deleted file mode 100644 index d7cde2e..0000000 --- a/grouperBot/lib/solady/test/CallContextChecker.t.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {CallContextChecker} from "../src/utils/CallContextChecker.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {MockCallContextChecker} from "../test/utils/mocks/MockCallContextChecker.sol"; - -contract CallContextCheckerTest is SoladyTest { - MockCallContextChecker impl1; - - address proxy; - - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - event Upgraded(address indexed implementation); - - function setUp() public { - impl1 = new MockCallContextChecker(); - proxy = LibClone.deployERC1967(address(impl1)); - MockCallContextChecker(proxy).initialize(address(this)); - } - - function testCheckOnlyEIP7702Authority() public { - address authority = _randomHashedAddress(); - vm.etch(authority, abi.encodePacked(hex"ef0100", impl1)); - // Runtime REVM detection. - // If this check fails, then we are not ready to test it in CI. - // The exact length is 23 at the time of writing as of the EIP7702 spec, - // but we give our heuristic some leeway. - if (authority.code.length > 0x20) return; - - uint256 x = _random(); - MockCallContextChecker(authority).setX(x); - uint256 retrievedX = MockCallContextChecker(authority).x(); - assertEq(retrievedX, x); - MockCallContextChecker(authority).checkOnlyEIP7702Authority(); - vm.expectRevert(CallContextChecker.UnauthorizedCallContext.selector); - MockCallContextChecker(impl1).checkOnlyEIP7702Authority(); - vm.expectRevert(CallContextChecker.UnauthorizedCallContext.selector); - MockCallContextChecker(proxy).checkOnlyEIP7702Authority(); - } - - function testCheckNotDelegated() public { - vm.expectRevert(CallContextChecker.UnauthorizedCallContext.selector); - MockCallContextChecker(proxy).checkNotDelegated(); - assertTrue(impl1.checkNotDelegated()); - } - - function testCheckOnlyProxy() public { - vm.expectRevert(CallContextChecker.UnauthorizedCallContext.selector); - impl1.checkOnlyProxy(); - assertTrue(MockCallContextChecker(proxy).checkOnlyProxy()); - } - - function testNotDelegatedGuard() public { - assertEq(impl1.proxiableUUID(), _ERC1967_IMPLEMENTATION_SLOT); - vm.expectRevert(CallContextChecker.UnauthorizedCallContext.selector); - MockCallContextChecker(proxy).proxiableUUID(); - } - - function testOnlyProxyGuard() public { - vm.expectRevert(CallContextChecker.UnauthorizedCallContext.selector); - impl1.upgradeToAndCall(address(1), bytes("")); - } -} diff --git a/grouperBot/lib/solady/test/DateTimeLib.t.sol b/grouperBot/lib/solady/test/DateTimeLib.t.sol deleted file mode 100644 index 4ad904d..0000000 --- a/grouperBot/lib/solady/test/DateTimeLib.t.sol +++ /dev/null @@ -1,868 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "../test/utils/SoladyTest.sol"; -import {DateTimeLib} from "../src/utils/DateTimeLib.sol"; - -contract DateTimeLibTest is SoladyTest { - struct DateTime { - uint256 year; - uint256 month; - uint256 day; - uint256 hour; - uint256 minute; - uint256 second; - } - - function testDateTimeMaxSupported() public { - DateTime memory d; - assertEq( - DateTimeLib.dateToEpochDay(DateTimeLib.MAX_SUPPORTED_YEAR, 12, 31), - DateTimeLib.MAX_SUPPORTED_EPOCH_DAY - ); - assertEq( - DateTimeLib.dateToTimestamp(DateTimeLib.MAX_SUPPORTED_YEAR, 12, 31) + 86400 - 1, - DateTimeLib.MAX_SUPPORTED_TIMESTAMP - ); - (d.year, d.month, d.day) = DateTimeLib.timestampToDate(DateTimeLib.MAX_SUPPORTED_TIMESTAMP); - assertTrue(d.year == DateTimeLib.MAX_SUPPORTED_YEAR && d.month == 12 && d.day == 31); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(DateTimeLib.MAX_SUPPORTED_EPOCH_DAY); - assertTrue(d.year == DateTimeLib.MAX_SUPPORTED_YEAR && d.month == 12 && d.day == 31); - (d.year, d.month, d.day) = - DateTimeLib.timestampToDate(DateTimeLib.MAX_SUPPORTED_TIMESTAMP + 1); - assertFalse(d.year == DateTimeLib.MAX_SUPPORTED_YEAR && d.month == 12 && d.day == 31); - (d.year, d.month, d.day) = - DateTimeLib.epochDayToDate(DateTimeLib.MAX_SUPPORTED_EPOCH_DAY + 1); - assertFalse(d.year == DateTimeLib.MAX_SUPPORTED_YEAR && d.month == 12 && d.day == 31); - } - - function testDateToEpochDay() public { - assertEq(DateTimeLib.dateToEpochDay(1970, 1, 1), 0); - assertEq(DateTimeLib.dateToEpochDay(1970, 1, 2), 1); - assertEq(DateTimeLib.dateToEpochDay(1970, 2, 1), 31); - assertEq(DateTimeLib.dateToEpochDay(1970, 3, 1), 59); - assertEq(DateTimeLib.dateToEpochDay(1970, 4, 1), 90); - assertEq(DateTimeLib.dateToEpochDay(1970, 5, 1), 120); - assertEq(DateTimeLib.dateToEpochDay(1970, 6, 1), 151); - assertEq(DateTimeLib.dateToEpochDay(1970, 7, 1), 181); - assertEq(DateTimeLib.dateToEpochDay(1970, 8, 1), 212); - assertEq(DateTimeLib.dateToEpochDay(1970, 9, 1), 243); - assertEq(DateTimeLib.dateToEpochDay(1970, 10, 1), 273); - assertEq(DateTimeLib.dateToEpochDay(1970, 11, 1), 304); - assertEq(DateTimeLib.dateToEpochDay(1970, 12, 1), 334); - assertEq(DateTimeLib.dateToEpochDay(1970, 12, 31), 364); - assertEq(DateTimeLib.dateToEpochDay(1971, 1, 1), 365); - assertEq(DateTimeLib.dateToEpochDay(1980, 11, 3), 3959); - assertEq(DateTimeLib.dateToEpochDay(2000, 3, 1), 11017); - assertEq(DateTimeLib.dateToEpochDay(2355, 12, 31), 140982); - assertEq(DateTimeLib.dateToEpochDay(99999, 12, 31), 35804721); - assertEq(DateTimeLib.dateToEpochDay(100000, 12, 31), 35805087); - assertEq(DateTimeLib.dateToEpochDay(604800, 2, 29), 220179195); - assertEq(DateTimeLib.dateToEpochDay(1667347200, 2, 29), 608985340227); - assertEq(DateTimeLib.dateToEpochDay(1667952000, 2, 29), 609206238891); - } - - function testDateToEpochDayGas() public { - unchecked { - uint256 sum; - for (uint256 i; i < 256; ++i) { - uint256 year = _bound(_random(), 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - uint256 month = _bound(_random(), 1, 12); - uint256 md = DateTimeLib.daysInMonth(year, month); - uint256 day = _bound(_random(), 1, md); - uint256 epochDay = DateTimeLib.dateToEpochDay(year, month, day); - sum += epochDay; - } - assertTrue(sum != 0); - } - } - - function testDateToEpochDayGas2() public { - unchecked { - uint256 sum; - for (uint256 i; i < 256; ++i) { - uint256 year = _bound(_random(), 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - uint256 month = _bound(_random(), 1, 12); - uint256 md = DateTimeLib.daysInMonth(year, month); - uint256 day = _bound(_random(), 1, md); - uint256 epochDay = _dateToEpochDayOriginal2(year, month, day); - sum += epochDay; - } - assertTrue(sum != 0); - } - } - - function testEpochDayToDateGas() public { - unchecked { - uint256 sum; - for (uint256 i; i < 256; ++i) { - uint256 epochDay = _bound(_random(), 0, DateTimeLib.MAX_SUPPORTED_EPOCH_DAY); - (uint256 year, uint256 month, uint256 day) = DateTimeLib.epochDayToDate(epochDay); - sum += year + month + day; - } - assertTrue(sum != 0); - } - } - - function testEpochDayToDateGas2() public { - unchecked { - uint256 sum; - for (uint256 i; i < 256; ++i) { - uint256 epochDay = _bound(_random(), 0, DateTimeLib.MAX_SUPPORTED_EPOCH_DAY); - (uint256 year, uint256 month, uint256 day) = _epochDayToDateOriginal2(epochDay); - sum += year + month + day; - } - assertTrue(sum != 0); - } - } - - function testDateToEpochDayDifferential(DateTime memory d) public { - d.year = _bound(d.year, 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - d.month = _bound(d.month, 1, 12); - d.day = _bound(d.day, 1, DateTimeLib.daysInMonth(d.year, d.month)); - uint256 expectedResult = _dateToEpochDayOriginal(d.year, d.month, d.day); - assertEq(DateTimeLib.dateToEpochDay(d.year, d.month, d.day), expectedResult); - } - - function testDateToEpochDayDifferential2(DateTime memory d) public { - d.year = _bound(d.year, 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - d.month = _bound(d.month, 1, 12); - d.day = _bound(d.day, 1, DateTimeLib.daysInMonth(d.year, d.month)); - uint256 expectedResult = _dateToEpochDayOriginal2(d.year, d.month, d.day); - assertEq(DateTimeLib.dateToEpochDay(d.year, d.month, d.day), expectedResult); - } - - function testEpochDayToDateDifferential(uint256 timestamp) public { - timestamp = _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day) = _epochDayToDateOriginal(timestamp); - (b.year, b.month, b.day) = DateTimeLib.epochDayToDate(timestamp); - assertTrue(a.year == b.year && a.month == b.month && a.day == b.day); - } - - function testEpochDayToDateDifferential2(uint256 timestamp) public { - timestamp = _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day) = _epochDayToDateOriginal2(timestamp); - (b.year, b.month, b.day) = DateTimeLib.epochDayToDate(timestamp); - assertTrue(a.year == b.year && a.month == b.month && a.day == b.day); - } - - function testDaysToDate() public { - DateTime memory d; - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(0); - assertTrue(d.year == 1970 && d.month == 1 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(31); - assertTrue(d.year == 1970 && d.month == 2 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(59); - assertTrue(d.year == 1970 && d.month == 3 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(90); - assertTrue(d.year == 1970 && d.month == 4 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(120); - assertTrue(d.year == 1970 && d.month == 5 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(151); - assertTrue(d.year == 1970 && d.month == 6 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(181); - assertTrue(d.year == 1970 && d.month == 7 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(212); - assertTrue(d.year == 1970 && d.month == 8 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(243); - assertTrue(d.year == 1970 && d.month == 9 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(273); - assertTrue(d.year == 1970 && d.month == 10 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(304); - assertTrue(d.year == 1970 && d.month == 11 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(334); - assertTrue(d.year == 1970 && d.month == 12 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(365); - assertTrue(d.year == 1971 && d.month == 1 && d.day == 1); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(10987); - assertTrue(d.year == 2000 && d.month == 1 && d.day == 31); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(18321); - assertTrue(d.year == 2020 && d.month == 2 && d.day == 29); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(156468); - assertTrue(d.year == 2398 && d.month == 5 && d.day == 25); - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(35805087); - assertTrue(d.year == 100000 && d.month == 12 && d.day == 31); - } - - function testEpochDayToDate(uint256 epochDay) public { - DateTime memory d; - (d.year, d.month, d.day) = DateTimeLib.epochDayToDate(epochDay); - assertEq(epochDay, DateTimeLib.dateToEpochDay(d.year, d.month, d.day)); - } - - function testDateToAndFroEpochDay(DateTime memory a) public { - a.year = _bound(a.year, 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - a.month = _bound(a.month, 1, 12); - uint256 md = DateTimeLib.daysInMonth(a.year, a.month); - a.day = _bound(a.day, 1, md); - uint256 epochDay = DateTimeLib.dateToEpochDay(a.year, a.month, a.day); - DateTime memory b; - (b.year, b.month, b.day) = DateTimeLib.epochDayToDate(epochDay); - assertTrue(a.year == b.year && a.month == b.month && a.day == b.day); - } - - function testDateTimeToAndFroTimestamp(DateTime memory a) public { - a.year = _bound(a.year, 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - a.month = _bound(a.month, 1, 12); - uint256 md = DateTimeLib.daysInMonth(a.year, a.month); - a.day = _bound(a.day, 1, md); - a.hour = _bound(a.hour, 0, 23); - a.minute = _bound(a.minute, 0, 59); - a.second = _bound(a.second, 0, 59); - uint256 timestamp = - DateTimeLib.dateTimeToTimestamp(a.year, a.month, a.day, a.hour, a.minute, a.second); - DateTime memory b; - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(timestamp); - assertTrue(a.year == b.year && a.month == b.month && a.day == b.day); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - } - - function testDateToAndFroEpochDay() public { - unchecked { - for (uint256 i; i < 256; ++i) { - uint256 year = _bound(_random(), 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - uint256 month = _bound(_random(), 1, 12); - uint256 md = DateTimeLib.daysInMonth(year, month); - uint256 day = _bound(_random(), 1, md); - uint256 epochDay = DateTimeLib.dateToEpochDay(year, month, day); - (uint256 y, uint256 m, uint256 d) = DateTimeLib.epochDayToDate(epochDay); - assertTrue(year == y && month == m && day == d); - } - } - } - - function testDateToAndFroTimestamp() public { - unchecked { - for (uint256 i; i < 256; ++i) { - uint256 year = _bound(_random(), 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - uint256 month = _bound(_random(), 1, 12); - uint256 md = DateTimeLib.daysInMonth(year, month); - uint256 day = _bound(_random(), 1, md); - uint256 timestamp = DateTimeLib.dateToTimestamp(year, month, day); - assertEq(timestamp, DateTimeLib.dateToEpochDay(year, month, day) * 86400); - (uint256 y, uint256 m, uint256 d) = DateTimeLib.timestampToDate(timestamp); - assertTrue(year == y && month == m && day == d); - } - } - } - - function testIsLeapYear() public { - assertTrue(DateTimeLib.isLeapYear(2000)); - assertTrue(DateTimeLib.isLeapYear(2024)); - assertTrue(DateTimeLib.isLeapYear(2048)); - assertTrue(DateTimeLib.isLeapYear(2072)); - assertTrue(DateTimeLib.isLeapYear(2104)); - assertTrue(DateTimeLib.isLeapYear(2128)); - assertTrue(DateTimeLib.isLeapYear(10032)); - assertTrue(DateTimeLib.isLeapYear(10124)); - assertTrue(DateTimeLib.isLeapYear(10296)); - assertTrue(DateTimeLib.isLeapYear(10400)); - assertTrue(DateTimeLib.isLeapYear(10916)); - } - - function testIsLeapYear(uint256 year) public { - assertEq( - DateTimeLib.isLeapYear(year), (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0) - ); - } - - function testDaysInMonth() public { - assertEq(DateTimeLib.daysInMonth(2022, 1), 31); - assertEq(DateTimeLib.daysInMonth(2022, 2), 28); - assertEq(DateTimeLib.daysInMonth(2022, 3), 31); - assertEq(DateTimeLib.daysInMonth(2022, 4), 30); - assertEq(DateTimeLib.daysInMonth(2022, 5), 31); - assertEq(DateTimeLib.daysInMonth(2022, 6), 30); - assertEq(DateTimeLib.daysInMonth(2022, 7), 31); - assertEq(DateTimeLib.daysInMonth(2022, 8), 31); - assertEq(DateTimeLib.daysInMonth(2022, 9), 30); - assertEq(DateTimeLib.daysInMonth(2022, 10), 31); - assertEq(DateTimeLib.daysInMonth(2022, 11), 30); - assertEq(DateTimeLib.daysInMonth(2022, 12), 31); - assertEq(DateTimeLib.daysInMonth(2024, 1), 31); - assertEq(DateTimeLib.daysInMonth(2024, 2), 29); - assertEq(DateTimeLib.daysInMonth(1900, 2), 28); - } - - function testDaysInMonth(uint256 year, uint256 month) public { - month = _bound(month, 1, 12); - if (DateTimeLib.isLeapYear(year) && month == 2) { - assertEq(DateTimeLib.daysInMonth(year, month), 29); - } else if ( - month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 - || month == 12 - ) { - assertEq(DateTimeLib.daysInMonth(year, month), 31); - } else if (month == 2) { - assertEq(DateTimeLib.daysInMonth(year, month), 28); - } else { - assertEq(DateTimeLib.daysInMonth(year, month), 30); - } - } - - function testWeekday() public { - assertEq(DateTimeLib.weekday(1), 4); - assertEq(DateTimeLib.weekday(86400), 5); - assertEq(DateTimeLib.weekday(86401), 5); - assertEq(DateTimeLib.weekday(172800), 6); - assertEq(DateTimeLib.weekday(259200), 7); - assertEq(DateTimeLib.weekday(345600), 1); - assertEq(DateTimeLib.weekday(432000), 2); - assertEq(DateTimeLib.weekday(518400), 3); - } - - function testDayOfWeek() public { - uint256 timestamp = 0; - uint256 weekday = 3; - unchecked { - for (uint256 i = 0; i < 1000; ++i) { - assertEq(DateTimeLib.weekday(timestamp) - 1, weekday); - timestamp += 86400; - weekday = (weekday + 1) % 7; - } - } - } - - function testIsSupportedDateTrue() public { - assertTrue(DateTimeLib.isSupportedDate(1970, 1, 1)); - assertTrue(DateTimeLib.isSupportedDate(1971, 5, 31)); - assertTrue(DateTimeLib.isSupportedDate(1971, 6, 30)); - assertTrue(DateTimeLib.isSupportedDate(1971, 12, 31)); - assertTrue(DateTimeLib.isSupportedDate(1972, 2, 28)); - assertTrue(DateTimeLib.isSupportedDate(1972, 4, 30)); - assertTrue(DateTimeLib.isSupportedDate(1972, 5, 31)); - assertTrue(DateTimeLib.isSupportedDate(2000, 2, 29)); - assertTrue(DateTimeLib.isSupportedDate(DateTimeLib.MAX_SUPPORTED_YEAR, 5, 31)); - } - - function testIsSupportedDateFalse() public { - assertFalse(DateTimeLib.isSupportedDate(0, 0, 0)); - assertFalse(DateTimeLib.isSupportedDate(1970, 0, 0)); - assertFalse(DateTimeLib.isSupportedDate(1970, 1, 0)); - assertFalse(DateTimeLib.isSupportedDate(1969, 1, 1)); - assertFalse(DateTimeLib.isSupportedDate(1800, 1, 1)); - assertFalse(DateTimeLib.isSupportedDate(1970, 13, 1)); - assertFalse(DateTimeLib.isSupportedDate(1700, 13, 1)); - assertFalse(DateTimeLib.isSupportedDate(1970, 15, 32)); - assertFalse(DateTimeLib.isSupportedDate(1970, 1, 32)); - assertFalse(DateTimeLib.isSupportedDate(1970, 13, 1)); - assertFalse(DateTimeLib.isSupportedDate(1879, 1, 1)); - assertFalse(DateTimeLib.isSupportedDate(1970, 4, 31)); - assertFalse(DateTimeLib.isSupportedDate(1970, 6, 31)); - assertFalse(DateTimeLib.isSupportedDate(1970, 7, 32)); - assertFalse(DateTimeLib.isSupportedDate(2000, 2, 30)); - assertFalse(DateTimeLib.isSupportedDate(DateTimeLib.MAX_SUPPORTED_YEAR + 1, 5, 31)); - assertFalse(DateTimeLib.isSupportedDate(type(uint256).max, 5, 31)); - } - - function testIsSupportedDateTime(DateTime memory a) public { - a.month = _bound(a.month, 0, 20); - a.day = _bound(a.day, 0, 50); - a.hour = _bound(a.hour, 0, 50); - a.minute = _bound(a.minute, 0, 100); - a.second = _bound(a.second, 0, 100); - bool isSupported = (1970 <= a.year && a.year <= DateTimeLib.MAX_SUPPORTED_YEAR) - && (1 <= a.month && a.month <= 12) - && (1 <= a.day && a.day <= DateTimeLib.daysInMonth(a.year, a.month)) && (a.hour < 24) - && (a.minute < 60) && (a.second < 60); - assertEq( - DateTimeLib.isSupportedDateTime(a.year, a.month, a.day, a.hour, a.minute, a.second), - isSupported - ); - } - - function testIsSupportedEpochDayTrue() public { - assertTrue(DateTimeLib.isSupportedEpochDay(0)); - assertTrue(DateTimeLib.isSupportedEpochDay(DateTimeLib.MAX_SUPPORTED_EPOCH_DAY)); - } - - function testIsSupportedEpochDayFalse() public { - assertFalse(DateTimeLib.isSupportedEpochDay(DateTimeLib.MAX_SUPPORTED_EPOCH_DAY + 1)); - assertFalse(DateTimeLib.isSupportedEpochDay(DateTimeLib.MAX_SUPPORTED_EPOCH_DAY + 2)); - } - - function testIsSupportedTimestampTrue() public { - assertTrue(DateTimeLib.isSupportedTimestamp(0)); - assertTrue(DateTimeLib.isSupportedTimestamp(DateTimeLib.MAX_SUPPORTED_TIMESTAMP)); - } - - function testIsSupportedTimestampFalse() public { - assertFalse(DateTimeLib.isSupportedTimestamp(DateTimeLib.MAX_SUPPORTED_TIMESTAMP + 1)); - assertFalse(DateTimeLib.isSupportedTimestamp(DateTimeLib.MAX_SUPPORTED_TIMESTAMP + 2)); - } - - function testNthWeekdayInMonthOfYearTimestamp() public { - uint256 wd; - // 1st 2nd 3rd 4th monday in November 2022. - wd = DateTimeLib.MON; - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 1, wd), 1667779200); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 2, wd), 1668384000); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 3, wd), 1668988800); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 4, wd), 1669593600); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 5, wd), 0); - - // 1st... 5th Wednesday in November 2022. - wd = DateTimeLib.WED; - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 1, wd), 1667347200); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 2, wd), 1667952000); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 3, wd), 1668556800); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 4, wd), 1669161600); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 5, wd), 1669766400); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 11, 6, wd), 0); - - // 1st... 5th Friday in December 2022. - wd = DateTimeLib.FRI; - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 12, 1, wd), 1669939200); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 12, 2, wd), 1670544000); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 12, 3, wd), 1671148800); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 12, 4, wd), 1671753600); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 12, 5, wd), 1672358400); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022, 12, 6, wd), 0); - - // 1st... 5th Sunday in January 2023. - wd = DateTimeLib.SUN; - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2023, 1, 1, wd), 1672531200); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2023, 1, 2, wd), 1673136000); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2023, 1, 3, wd), 1673740800); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2023, 1, 4, wd), 1674345600); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2023, 1, 5, wd), 1674950400); - assertEq(DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2023, 1, 6, wd), 0); - } - - function testNthWeekdayInMonthOfYearTimestamp( - uint256 year, - uint256 month, - uint256 n, - uint256 weekday - ) public { - unchecked { - year = _bound(year, 1970, DateTimeLib.MAX_SUPPORTED_YEAR); - month = _bound(month, 1, 12); - n = _bound(n, 1, 10); - weekday = _bound(weekday, 1, 7); - // Count number of weekdays for the month in the year. - uint256 md = DateTimeLib.daysInMonth(year, month); - uint256 timestamp = DateTimeLib.dateToTimestamp(year, month, 1); - uint256 m; - uint256 found; - for (uint256 i; i < md;) { - if (DateTimeLib.weekday(timestamp) == weekday) { - if (++m == n) { - found = 1; - break; - } - } - if (m == 0) { - timestamp += 86400; - i += 1; - } else { - timestamp += 86400 * 7; - i += 7; - } - } - assertEq( - DateTimeLib.nthWeekdayInMonthOfYearTimestamp(year, month, n, weekday), - found * timestamp - ); - } - } - - function testMondayTimestamp() public { - // Thursday 01 January 1970 -> 0 - assertEq(DateTimeLib.mondayTimestamp(0), 0); - // Friday 02 January 1970 -> 86400 - assertEq(DateTimeLib.mondayTimestamp(86400), 0); - // Saturday 03 January 1970 -> 172800 - assertEq(DateTimeLib.mondayTimestamp(172800), 0); - // Sunday 04 January 1970 -> 259200 - assertEq(DateTimeLib.mondayTimestamp(259200), 0); - // Monday 05 January 19700 -> 345600 - assertEq(DateTimeLib.mondayTimestamp(345600), 345600); - // Monday 07 November 2022 -> 1667779200 - assertEq(DateTimeLib.mondayTimestamp(1667779200), 1667779200); - // Sunday 06 November 2022 -> 1667692800 - assertEq(DateTimeLib.mondayTimestamp(1667692800), 1667174400); - // Saturday 05 November 2022 -> 1667606400 - assertEq(DateTimeLib.mondayTimestamp(1667606400), 1667174400); - // Friday 04 November 2022 -> 1667520000 - assertEq(DateTimeLib.mondayTimestamp(1667520000), 1667174400); - // Thursday 03 November 2022 -> 1667433600 - assertEq(DateTimeLib.mondayTimestamp(1667433600), 1667174400); - // Wednesday 02 November 2022 -> 1667347200 - assertEq(DateTimeLib.mondayTimestamp(1667347200), 1667174400); - // Tuesday 01 November 2022 -> 1667260800 - assertEq(DateTimeLib.mondayTimestamp(1667260800), 1667174400); - // Monday 01 November 2022 -> 1667260800 - assertEq(DateTimeLib.mondayTimestamp(1667174400), 1667174400); - } - - function testMondayTimestamp(uint256 timestamp) public { - uint256 day = timestamp / 86400; - uint256 weekday = (day + 3) % 7; - assertEq( - DateTimeLib.mondayTimestamp(timestamp), timestamp > 345599 ? (day - weekday) * 86400 : 0 - ); - } - - function testIsWeekEnd(uint256 timestamp) public { - timestamp = _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP); - uint256 weekday = DateTimeLib.weekday(timestamp); - assertEq( - DateTimeLib.isWeekEnd(timestamp), - weekday == DateTimeLib.SAT || weekday == DateTimeLib.SUN - ); - } - - function testAddSubDiffYears(uint256 timestamp, uint256 numYears) public { - uint256 maxNumYears = 1000000; - numYears = _bound(numYears, 0, maxNumYears); - timestamp = - _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP - maxNumYears * 366 * 86400); - uint256 result = DateTimeLib.addYears(timestamp, numYears); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day, a.hour, a.minute, a.second) = - DateTimeLib.timestampToDateTime(timestamp); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - if (numYears != 0) assertTrue(a.year != b.year); - if (a.day <= 28) assertEq(a.day, b.day); - assertTrue(a.month == b.month); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - uint256 diff = DateTimeLib.diffYears(timestamp, result); - assertTrue(diff == numYears); - result = DateTimeLib.subYears(result, numYears); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - assertTrue(a.year == b.year && a.month == b.month); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - } - - function addYears(uint256 timestamp, uint256 numYears) public pure returns (uint256) { - return DateTimeLib.addYears(timestamp, numYears); - } - - function subYears(uint256 timestamp, uint256 numYears) public pure returns (uint256) { - return DateTimeLib.subYears(timestamp, numYears); - } - - function diffYears(uint256 timestamp, uint256 numYears) public pure returns (uint256) { - return DateTimeLib.diffYears(timestamp, numYears); - } - - function addMonths(uint256 timestamp, uint256 numMonths) public pure returns (uint256) { - return DateTimeLib.addMonths(timestamp, numMonths); - } - - function subMonths(uint256 timestamp, uint256 numMonths) public pure returns (uint256) { - return DateTimeLib.subMonths(timestamp, numMonths); - } - - function diffMonths(uint256 timestamp, uint256 numMonths) public pure returns (uint256) { - return DateTimeLib.diffMonths(timestamp, numMonths); - } - - function addDays(uint256 timestamp, uint256 numDays) public pure returns (uint256) { - return DateTimeLib.addDays(timestamp, numDays); - } - - function subDays(uint256 timestamp, uint256 numDays) public pure returns (uint256) { - return DateTimeLib.subDays(timestamp, numDays); - } - - function diffDays(uint256 timestamp, uint256 numDays) public pure returns (uint256) { - return DateTimeLib.diffDays(timestamp, numDays); - } - - function addHours(uint256 timestamp, uint256 numHours) public pure returns (uint256) { - return DateTimeLib.addHours(timestamp, numHours); - } - - function subHours(uint256 timestamp, uint256 numHours) public pure returns (uint256) { - return DateTimeLib.subHours(timestamp, numHours); - } - - function diffHours(uint256 timestamp, uint256 numHours) public pure returns (uint256) { - return DateTimeLib.diffHours(timestamp, numHours); - } - - function addMinutes(uint256 timestamp, uint256 numMinutes) public pure returns (uint256) { - return DateTimeLib.addMinutes(timestamp, numMinutes); - } - - function subMinutes(uint256 timestamp, uint256 numMinutes) public pure returns (uint256) { - return DateTimeLib.subMinutes(timestamp, numMinutes); - } - - function diffMinutes(uint256 timestamp, uint256 numMinutes) public pure returns (uint256) { - return DateTimeLib.diffMinutes(timestamp, numMinutes); - } - - function addSeconds(uint256 timestamp, uint256 numSeconds) public pure returns (uint256) { - return DateTimeLib.addSeconds(timestamp, numSeconds); - } - - function subSeconds(uint256 timestamp, uint256 numSeconds) public pure returns (uint256) { - return DateTimeLib.subSeconds(timestamp, numSeconds); - } - - function diffSeconds(uint256 timestamp, uint256 numSeconds) public pure returns (uint256) { - return DateTimeLib.diffSeconds(timestamp, numSeconds); - } - - function testDateTimeArithmeticReverts() public { - vm.expectRevert(stdError.arithmeticError); - this.addYears(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.subYears(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.diffYears(2 ** 128 - 1, 2 ** 127 - 1); - - vm.expectRevert(stdError.arithmeticError); - this.addMonths(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.subMonths(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.diffMonths(2 ** 128 - 1, 2 ** 127 - 1); - - vm.expectRevert(stdError.arithmeticError); - this.addDays(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.subDays(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.diffDays(2 ** 128 - 1, 2 ** 127 - 1); - - vm.expectRevert(stdError.arithmeticError); - this.addHours(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.subHours(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.diffHours(2 ** 128 - 1, 2 ** 127 - 1); - - vm.expectRevert(stdError.arithmeticError); - this.addMinutes(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.subMinutes(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.diffMinutes(2 ** 128 - 1, 2 ** 127 - 1); - - vm.expectRevert(stdError.arithmeticError); - this.addSeconds(2 ** 256 - 1, 2 ** 256 - 1); - vm.expectRevert(stdError.arithmeticError); - this.subSeconds(2 ** 128 - 1, 2 ** 255 - 1); - vm.expectRevert(stdError.arithmeticError); - this.diffSeconds(2 ** 128 - 1, 2 ** 127 - 1); - } - - function testAddSubDiffMonths(uint256 timestamp, uint256 numMonths) public { - uint256 maxNumMonths = 1000000; - numMonths = _bound(numMonths, 0, maxNumMonths); - timestamp = - _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP - maxNumMonths * 32 * 86400); - uint256 result = DateTimeLib.addMonths(timestamp, numMonths); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day, a.hour, a.minute, a.second) = - DateTimeLib.timestampToDateTime(timestamp); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - if (numMonths != 0) assertTrue(a.year != b.year || a.month != b.month); - if (a.day <= 28) assertEq(a.day, b.day); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - uint256 diff = DateTimeLib.diffMonths(timestamp, result); - assertTrue(diff == numMonths); - result = DateTimeLib.subMonths(result, numMonths); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - assertTrue(a.year == b.year && a.month == b.month); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - } - - function testAddSubDiffDays(uint256 timestamp, uint256 numDays) public { - uint256 maxNumDays = 100000000; - numDays = _bound(numDays, 0, maxNumDays); - timestamp = _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP - maxNumDays * 86400); - uint256 result = DateTimeLib.addDays(timestamp, numDays); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day, a.hour, a.minute, a.second) = - DateTimeLib.timestampToDateTime(timestamp); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - if (numDays != 0) { - assertTrue(a.year != b.year || a.month != b.month || a.day != b.day); - } - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - uint256 diff = DateTimeLib.diffDays(timestamp, result); - assertTrue(diff == numDays); - result = DateTimeLib.subDays(result, numDays); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - assertTrue(a.year == b.year && a.month == b.month); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - } - - function testAddSubDiffHours(uint256 timestamp, uint256 numHours) public { - uint256 maxNumHours = 10000000000; - numHours = _bound(numHours, 0, maxNumHours); - timestamp = _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP - maxNumHours * 3600); - uint256 result = DateTimeLib.addHours(timestamp, numHours); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day, a.hour, a.minute, a.second) = - DateTimeLib.timestampToDateTime(timestamp); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - if (numHours != 0) { - assertTrue(a.year != b.year || a.month != b.month || a.day != b.day || a.hour != b.hour); - } - assertTrue(a.minute == b.minute && a.second == b.second); - uint256 diff = DateTimeLib.diffHours(timestamp, result); - assertTrue(diff == numHours); - result = DateTimeLib.subHours(result, numHours); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - assertTrue(a.year == b.year && a.month == b.month); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - } - - function testAddSubDiffMinutes(uint256 timestamp, uint256 numMinutes) public { - uint256 maxNumMinutes = 10000000000; - numMinutes = _bound(numMinutes, 0, maxNumMinutes); - timestamp = _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP - maxNumMinutes * 60); - uint256 result = DateTimeLib.addMinutes(timestamp, numMinutes); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day, a.hour, a.minute, a.second) = - DateTimeLib.timestampToDateTime(timestamp); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - if (numMinutes != 0) { - assertTrue( - (a.year != b.year || a.month != b.month || a.day != b.day) - || (a.hour != b.hour || a.minute != b.minute) - ); - } - assertTrue(a.second == b.second); - uint256 diff = DateTimeLib.diffMinutes(timestamp, result); - assertTrue(diff == numMinutes); - result = DateTimeLib.subMinutes(result, numMinutes); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - assertTrue(a.year == b.year && a.month == b.month); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - } - - function testAddSubDiffSeconds(uint256 timestamp, uint256 numSeconds) public { - uint256 maxNumSeconds = 1000000000000; - numSeconds = _bound(numSeconds, 0, maxNumSeconds); - timestamp = _bound(timestamp, 0, DateTimeLib.MAX_SUPPORTED_TIMESTAMP - maxNumSeconds); - uint256 result = DateTimeLib.addSeconds(timestamp, numSeconds); - DateTime memory a; - DateTime memory b; - (a.year, a.month, a.day, a.hour, a.minute, a.second) = - DateTimeLib.timestampToDateTime(timestamp); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - if (numSeconds != 0) { - assertTrue( - (a.year != b.year || a.month != b.month || a.day != b.day) - || (a.hour != b.hour || a.minute != b.minute || a.second != b.second) - ); - } - uint256 diff = DateTimeLib.diffSeconds(timestamp, result); - assertTrue(diff == numSeconds); - result = DateTimeLib.subSeconds(result, numSeconds); - (b.year, b.month, b.day, b.hour, b.minute, b.second) = - DateTimeLib.timestampToDateTime(result); - assertTrue(a.year == b.year && a.month == b.month); - assertTrue(a.hour == b.hour && a.minute == b.minute && a.second == b.second); - } - - function _dateToEpochDayOriginal(uint256 year, uint256 month, uint256 day) - internal - pure - returns (uint256) - { - unchecked { - if (month <= 2) { - year -= 1; - } - uint256 era = year / 400; - uint256 yoe = year - era * 400; - uint256 doy = (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; - uint256 doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; - return era * 146097 + doe - 719468; - } - } - - function _dateToEpochDayOriginal2(uint256 year, uint256 month, uint256 day) - internal - pure - returns (uint256 _days) - { - unchecked { - int256 _year = int256(year); - int256 _month = int256(month); - int256 _day = int256(day); - - int256 _m = (_month - 14) / 12; - int256 __days = _day - 32075 + ((1461 * (_year + 4800 + _m)) / 4) - + ((367 * (_month - 2 - _m * 12)) / 12) - ((3 * ((_year + 4900 + _m) / 100)) / 4) - - 2440588; - - _days = uint256(__days); - } - } - - function _epochDayToDateOriginal(uint256 timestamp) - internal - pure - returns (uint256 year, uint256 month, uint256 day) - { - unchecked { - timestamp += 719468; - uint256 era = timestamp / 146097; - uint256 doe = timestamp - era * 146097; - uint256 yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; - year = yoe + era * 400; - uint256 doy = doe - (365 * yoe + yoe / 4 - yoe / 100); - uint256 mp = (5 * doy + 2) / 153; - day = doy - (153 * mp + 2) / 5 + 1; - month = mp < 10 ? mp + 3 : mp - 9; - if (month <= 2) { - year += 1; - } - } - } - - function _epochDayToDateOriginal2(uint256 _days) - internal - pure - returns (uint256 year, uint256 month, uint256 day) - { - unchecked { - int256 __days = int256(_days); - - int256 L = __days + 68569 + 2440588; - int256 N = (4 * L) / 146097; - L = L - (146097 * N + 3) / 4; - int256 _year = (4000 * (L + 1)) / 1461001; - L = L - (1461 * _year) / 4 + 31; - int256 _month = (80 * L) / 2447; - int256 _day = L - (2447 * _month) / 80; - L = _month / 11; - _month = _month + 2 - 12 * L; - _year = 100 * (N - 49) + _year + L; - - year = uint256(_year); - month = uint256(_month); - day = uint256(_day); - } - } -} diff --git a/grouperBot/lib/solady/test/DeploylessPredeployQueryer.t.sol b/grouperBot/lib/solady/test/DeploylessPredeployQueryer.t.sol deleted file mode 100644 index 1e6b9af..0000000 --- a/grouperBot/lib/solady/test/DeploylessPredeployQueryer.t.sol +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {DeploylessPredeployQueryer} from "../src/utils/DeploylessPredeployQueryer.sol"; - -library RandomBytesGeneratorLib { - function generate(bytes memory seed) internal pure returns (bytes memory result) { - result = generate(uint256(keccak256(seed))); - } - - function generate(uint256 seed) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := add(0x20, mload(0x40)) - mstore(0x00, seed) - let n := mod(keccak256(0x00, 0x20), 300) - mstore(result, n) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(0x20, i) - mstore(add(i, add(result, 0x20)), keccak256(0x00, 0x40)) - } - mstore(0x40, add(n, add(result, 0x20))) - } - } - - function next(uint256 seed) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, seed) - result := keccak256(0x00, 0x20) - } - } -} - -contract Target { - function generate(bytes memory seed) public pure returns (bytes memory result) { - result = RandomBytesGeneratorLib.generate(seed); - /// @solidity memory-safe-assembly - assembly { - mstore(sub(result, 0x20), 0x20) - return(sub(result, 0x20), add(add(0x40, mod(seed, 50)), mload(result))) - } - } - - function generate(uint256 seed) public pure returns (bytes memory result) { - result = RandomBytesGeneratorLib.generate(seed); - /// @solidity memory-safe-assembly - assembly { - mstore(sub(result, 0x20), 0x20) - return(sub(result, 0x20), add(add(0x40, mod(seed, 50)), mload(result))) - } - } - - function next(uint256 seed) public pure returns (uint256 result) { - result = RandomBytesGeneratorLib.next(seed); - } -} - -contract Factory { - address public implementation; - - constructor() { - implementation = address(new Target()); - } - - function deploy(bytes32 salt) public returns (address) { - if (predictDeployment(salt).code.length != 0) return predictDeployment(salt); - return LibClone.cloneDeterministic(implementation, salt); - } - - function predictDeployment(bytes32 salt) public view returns (address) { - return LibClone.predictDeterministicAddress(implementation, salt, address(this)); - } -} - -contract DeploylessPredeployQueryerTest is SoladyTest { - Factory factory; - - bytes internal constant _CREATION_CODE = - hex"3860b63d393d516020805190606051833b15607e575b5059926040908285528351938460051b9459523d604087015260005b858103603e578680590390f35b6000828683820101510138908688820151910147875af115607457603f19875903018482890101523d59523d6000593e84016031565b3d6000803e3d6000fd5b816000828193519083479101906040515af11560ad5783815114601f3d111660155763d1f6b81290526004601cfd5b3d81803e3d90fdfe"; - - function setUp() public { - factory = new Factory(); - } - - struct _TestTemps { - address target; - uint256 n; - uint256[] seeds; - bytes[] bytesSeeds; - address deployed; - bytes factoryCalldata; - bytes[] targetQueryCalldata; - bytes[] decoded; - } - - function _deployQuery( - address target, - bytes[] memory targetQueryCalldata, - bytes memory factoryCalldata - ) internal returns (address result) { - if (_randomChance(2)) { - return address( - new DeploylessPredeployQueryer( - target, targetQueryCalldata, address(factory), factoryCalldata - ) - ); - } - bytes memory args = - abi.encode(target, targetQueryCalldata, address(factory), factoryCalldata); - bytes memory initcode; - if (false && _randomChance(2)) { - initcode = _CREATION_CODE; - } else { - initcode = type(DeploylessPredeployQueryer).creationCode; - } - initcode = abi.encodePacked(initcode, args); - /// @solidity memory-safe-assembly - assembly { - result := create(0, add(0x20, initcode), mload(initcode)) - } - } - - function testTargetGenerate() public { - vm.pauseGasMetering(); - Target target = new Target(); - for (uint256 i; i < 16; ++i) { - bytes memory seed = _randomBytes(); - assertEq(target.generate(seed), RandomBytesGeneratorLib.generate(seed)); - } - vm.resumeGasMetering(); - } - - function testPredeployQueryer(bytes32 salt) public { - unchecked { - _TestTemps memory t; - t.target = factory.predictDeployment(salt); - if (_randomChance(2)) { - assertEq(factory.deploy(salt), t.target); - } - t.factoryCalldata = abi.encodeWithSignature("deploy(bytes32)", salt); - t.n = _random() % 3; - t.targetQueryCalldata = new bytes[](t.n); - t.seeds = new uint256[](t.n); - t.bytesSeeds = new bytes[](t.n); - if (_randomChance(2)) { - vm.expectRevert(DeploylessPredeployQueryer.ReturnedAddressMismatch.selector); - address wrongTarget = address(uint160(t.target) ^ 1); - t.deployed = _deployQuery(wrongTarget, t.targetQueryCalldata, t.factoryCalldata); - } - if (_randomChance(2)) { - for (uint256 i; i < t.n; ++i) { - t.bytesSeeds[i] = _randomBytes(); - t.targetQueryCalldata[i] = - abi.encodeWithSignature("generate(bytes)", t.bytesSeeds[i]); - } - t.deployed = _deployQuery(t.target, t.targetQueryCalldata, t.factoryCalldata); - t.decoded = abi.decode(t.deployed.code, (bytes[])); - assertEq(t.decoded.length, t.n); - for (uint256 i; i < t.n; ++i) { - assertEq( - abi.decode(t.decoded[i], (bytes)), - RandomBytesGeneratorLib.generate(t.bytesSeeds[i]) - ); - } - } - for (uint256 i; i < t.n; ++i) { - t.seeds[i] = _random(); - t.targetQueryCalldata[i] = abi.encodeWithSignature("next(uint256)", t.seeds[i]); - } - t.deployed = _deployQuery(t.target, t.targetQueryCalldata, t.factoryCalldata); - t.decoded = abi.decode(t.deployed.code, (bytes[])); - for (uint256 i; i < t.n; ++i) { - assertEq( - abi.decode(t.decoded[i], (uint256)), RandomBytesGeneratorLib.next(t.seeds[i]) - ); - } - } - } -} diff --git a/grouperBot/lib/solady/test/DynamicArrayLib.t.sol b/grouperBot/lib/solady/test/DynamicArrayLib.t.sol deleted file mode 100644 index 18a5e94..0000000 --- a/grouperBot/lib/solady/test/DynamicArrayLib.t.sol +++ /dev/null @@ -1,671 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {DynamicArrayLib} from "../src/utils/DynamicArrayLib.sol"; - -contract DynamicArrayLibTest is SoladyTest { - using DynamicArrayLib for *; - - function testDynamicArrayPushAndPop() public { - uint256 n = 100; - DynamicArrayLib.DynamicArray memory a; - unchecked { - for (uint256 i; i != n; ++i) { - a.p(i); - } - for (uint256 i; i != n; ++i) { - assertEq(a.get(i), i); - } - for (uint256 i; i != n; ++i) { - assertEq(a.length(), 100 - i); - assertEq(a.pop(), 99 - i); - } - } - } - - function testDynamicArrayPushAfterReserve() public { - uint256 n = 100; - DynamicArrayLib.DynamicArray memory a; - a.reserve(n); - unchecked { - for (uint256 i; i != n; ++i) { - a.p(i); - } - for (uint256 i; i != n; ++i) { - assertEq(a.get(i), i); - } - } - } - - function testDynamicArrayWrap() public { - { - address[] memory a = new address[](2); - a[1] = address(1); - assertEq(DynamicArrayLib.wrap(a).get(0), 0); - assertEq(DynamicArrayLib.wrap(a).get(1), 1); - } - { - bytes32[] memory a = new bytes32[](2); - a[1] = bytes32(uint256(1)); - assertEq(DynamicArrayLib.wrap(a).get(0), 0); - assertEq(DynamicArrayLib.wrap(a).get(1), 1); - } - { - bool[] memory a = new bool[](2); - a[1] = true; - assertEq(DynamicArrayLib.wrap(a).get(0), 0); - assertEq(DynamicArrayLib.wrap(a).get(1), 1); - } - } - - function testDynamicArrayResize(uint256[] memory data, uint256 n) public { - DynamicArrayLib.DynamicArray memory a; - a.data = data; - n = _bound(_random(), 0, 0xff); - a.resize(n); - assertEq(a.data.length, n); - _checkMemory(a.data); - unchecked { - for (uint256 i; i != n; ++i) { - if (i < data.length) { - assertEq(a.get(i), data[i]); - } else { - assertEq(a.get(i), 0); - } - } - } - uint256 lengthBefore = n; - n = _bound(_random(), 0, 0xff); - a.resize(n); - assertEq(a.data.length, n); - _checkMemory(a.data); - unchecked { - for (uint256 i; i != n; ++i) { - if (i < lengthBefore && i < data.length) { - assertEq(a.get(i), data[i]); - } else { - assertEq(a.get(i), 0); - } - } - } - } - - function testDynamicArrayExpandAndTruncate(bytes32) public { - uint256 n = _bound(_random(), 0, 0xff); - DynamicArrayLib.DynamicArray memory a; - uint256 lengthBefore = a.expand(n).length(); - assertEq(lengthBefore, n); - _checkMemory(a.data); - n = _bound(_random(), 0, 0xff); - a.expand(n); - if (n > lengthBefore) { - assertEq(a.length(), n); - } else { - assertEq(a.length(), lengthBefore); - } - bool hasValues; - if (_randomChance(32)) { - hasValues = true; - unchecked { - for (uint256 i; i != a.length(); ++i) { - a.set(i, i); - } - } - } - lengthBefore = a.length(); - n = _bound(_random(), 0, 0xff); - a.truncate(n); - if (n < lengthBefore) { - assertEq(a.length(), n); - } else { - assertEq(a.length(), lengthBefore); - } - _checkMemory(a.data); - if (hasValues) { - unchecked { - for (uint256 i; i != a.length(); ++i) { - assertEq(a.get(i), i); - } - } - } - } - - function testDynamicArrayPushPop(uint256 n, uint256 r) public { - n = _bound(n, 0, 50); - if (_randomChance(2)) _misalignFreeMemoryPointer(); - if (_randomChance(8)) _brutalizeMemory(); - - DynamicArrayLib.DynamicArray memory a; - assertEq(a.data.length, 0); - - unchecked { - if (_randomChance(16)) a.free(); - if (_randomChance(16)) assertEq(a.pop(), 0); - if (_randomChance(16)) a.reserve(_bound(_random(), 0, 50)); - if (_randomChance(2)) _checkMemory(a.data); - - for (uint256 i; i != n; ++i) { - a.p(i ^ r); - assertEq(a.length(), i + 1); - _checkMemory(a.data); - - if (_randomChance(8)) { - a.reserve(_bound(_random(), 0, 50)); - _checkMemory(a.data); - assertEq(a.length(), i + 1); - } - if (_randomChance(16)) { - assertEq(keccak256(abi.encodePacked(a.data)), a.hash()); - } - if (_randomChance(16)) { - for (uint256 j; j != i; ++j) { - assertEq(a.get(j), j ^ r); - } - } - } - for (uint256 i; i != n; ++i) { - assertEq(a.get(i), i ^ r); - } - - assertEq(keccak256(abi.encodePacked(a.data)), a.hash()); - - if (_randomChance(16)) { - assertEq(a.free().length(), 0); - if (_randomChance(16)) a.reserve(_bound(_random(), 0, 50)); - if (_randomChance(2)) _checkMemory(a.data); - for (uint256 i; i != n; ++i) { - a.p(i ^ r); - _checkMemory(a.data); - } - for (uint256 i; i != n; ++i) { - assertEq(a.get(i), i ^ r); - } - } - - if (_randomChance(2)) { - a.clear(); - assertEq(a.length(), 0); - } else { - if (_randomChance(2)) { - uint256 newLength = _bound(_random(), 0, 50); - a.resize(newLength); - assertEq(a.length(), newLength); - _checkMemory(a.data); - for (uint256 i; i != newLength; ++i) { - if (i < n) { - assertEq(a.get(i), i ^ r); - } else { - assertEq(a.getBytes32(i), bytes32(0)); - } - } - } else { - for (uint256 i; i != n; ++i) { - assertEq(a.pop(), (n - 1 - i) ^ r); - } - assertEq(a.pop(), 0); - } - } - } - } - - function testDynamicArraySlice() public { - DynamicArrayLib.DynamicArray memory a = DynamicArrayLib.p("a").p("b").p("c"); - assertEq(a.slice(0, 3).hash(), DynamicArrayLib.p("a").p("b").p("c").hash()); - assertEq(a.slice(1, 3).hash(), DynamicArrayLib.p("b").p("c").hash()); - assertEq(a.slice(2, 3).hash(), DynamicArrayLib.p("c").hash()); - assertEq(a.slice(3, 3).hash(), DynamicArrayLib.p().hash()); - assertEq(a.slice(0, 2).hash(), DynamicArrayLib.p("a").p("b").hash()); - assertEq(a.slice(0, 1).hash(), DynamicArrayLib.p("a").hash()); - assertEq(a.slice(0, 0).hash(), DynamicArrayLib.p().hash()); - assertEq(a.slice(1, 2).hash(), DynamicArrayLib.p("b").hash()); - assertEq(a.slice(1, 1).hash(), DynamicArrayLib.p().hash()); - } - - function testDynamicArraySlice(uint256[] memory data, uint256 start, uint256 end) public { - DynamicArrayLib.DynamicArray memory a; - a.data = data; - unchecked { - start = _bound(start, 0, a.data.length + 2); - end = _bound(end, 0, a.data.length + 2); - DynamicArrayLib.DynamicArray memory slice; - if (_randomChance(2) && end > a.data.length) { - slice = a.slice(start); - } else { - slice = a.slice(start, end); - } - _checkMemory(slice.data); - assertEq(slice.data, _sliceOriginal(data, start, end)); - } - } - - function testDynamicArrayCopyOrAllSlice() public { - uint256[] memory data; - uint256[] memory data2 = new uint256[](1); - data2[0] = 600972374956821603611096798192277940001591154517179782006087886208744463727; - this.testDynamicArrayCopyOrAllSlice(data, data2, 0); - } - - function testDynamicArrayCopyOrAllSlice( - uint256[] calldata data, - uint256[] calldata data2, - uint256 r - ) public { - DynamicArrayLib.DynamicArray memory a; - DynamicArrayLib.DynamicArray memory b; - DynamicArrayLib.DynamicArray memory aCopy; - for (uint256 i; i < data.length; ++i) { - a.p(data[i] & (2 ** 160 - 1)); - b.p(data[i]); - if (r & 2 == 0) { - _checkMemory(a.data); - _checkMemory(b.data); - } - } - bytes32 h = keccak256(abi.encodePacked(b.data)); - aCopy = r & 1 == 0 ? a.copy() : a.slice(0); - /// @solidity memory-safe-assembly - assembly { - log0(a, 0x20) - log0(b, 0x20) - log0(aCopy, 0x20) - } - for (uint256 i; i < data2.length; ++i) { - aCopy.p(data2[i]); - } - /// @solidity memory-safe-assembly - assembly { - log0(a, 0x20) - log0(b, 0x20) - log0(aCopy, 0x20) - } - for (uint256 i; i < data2.length; ++i) { - a.p(data2[i]); - } - /// @solidity memory-safe-assembly - assembly { - log0(a, 0x20) - log0(b, 0x20) - log0(aCopy, 0x20) - } - assertEq(a.data, aCopy.data); - assertEq(keccak256(abi.encodePacked(b.data)), h); - } - - function testDynamicArrayCopy(uint256[] memory data, uint256 r) public { - if (r & 0xff00 == 0) { - /// @solidity memory-safe-assembly - assembly { - data := 0x60 - } - } - DynamicArrayLib.DynamicArray memory a; - a.data = data; - DynamicArrayLib.DynamicArray memory b = a.copy(); - if (r & 2 == 0) { - _checkMemory(a.data); - _checkMemory(b.data); - } - assertEq(a.data, b.data); - a.p(1); - assertNotEq(a.data, b.data); - b.p(1); - assertEq(a.data, b.data); - } - - function testUint256Contains() public { - uint256 n = 50; - uint256[] memory a; - assertEq(DynamicArrayLib.contains(a, 0), false); - assertEq(DynamicArrayLib.contains(a, 1), false); - assertEq(DynamicArrayLib.contains(a, 2), false); - a = new uint256[](0); - assertEq(DynamicArrayLib.contains(a, 0), false); - assertEq(DynamicArrayLib.contains(a, 1), false); - assertEq(DynamicArrayLib.contains(a, 2), false); - a = new uint256[](1); - assertEq(DynamicArrayLib.contains(a, 0), true); - assertEq(DynamicArrayLib.contains(a, 1), false); - assertEq(DynamicArrayLib.contains(a, 2), false); - a = DynamicArrayLib.malloc(n); - unchecked { - for (uint256 i; i != n; ++i) { - a.set(i, i); - } - } - assertEq(DynamicArrayLib.contains(a, 0), true); - assertEq(DynamicArrayLib.contains(a, 1), true); - assertEq(DynamicArrayLib.contains(a, 10), true); - assertEq(DynamicArrayLib.contains(a, 31), true); - assertEq(DynamicArrayLib.contains(a, 32), true); - assertEq(DynamicArrayLib.contains(a, 49), true); - assertEq(DynamicArrayLib.contains(a, 50), false); - assertEq(DynamicArrayLib.contains(a, 100), false); - } - - function testUint256ArrayIndexOf() public { - uint256 n = 50; - uint256[] memory a; - assertEq(DynamicArrayLib.indexOf(a, 0), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.indexOf(a, 1), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.indexOf(a, 2), DynamicArrayLib.NOT_FOUND); - a = new uint256[](0); - assertEq(DynamicArrayLib.indexOf(a, 0), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.indexOf(a, 1), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.indexOf(a, 2), DynamicArrayLib.NOT_FOUND); - a = new uint256[](1); - assertEq(DynamicArrayLib.indexOf(a, 0), 0); - assertEq(DynamicArrayLib.indexOf(a, 1), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.indexOf(a, 2), DynamicArrayLib.NOT_FOUND); - a = DynamicArrayLib.malloc(n); - unchecked { - for (uint256 i; i != n; ++i) { - a.set(i, i); - } - } - assertEq(DynamicArrayLib.indexOf(a, 0), 0); - assertEq(DynamicArrayLib.indexOf(a, 1), 1); - assertEq(DynamicArrayLib.indexOf(a, 10), 10); - assertEq(DynamicArrayLib.indexOf(a, 31), 31); - assertEq(DynamicArrayLib.indexOf(a, 32), 32); - assertEq(DynamicArrayLib.indexOf(a, 49), 49); - assertEq(DynamicArrayLib.indexOf(a, 50), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.indexOf(a, 100), DynamicArrayLib.NOT_FOUND); - } - - function testUint256ArrayIndexOfDifferential( - uint256[] memory array, - uint256 needle, - uint256 from - ) public { - if (_randomChance(2)) _misalignFreeMemoryPointer(); - if (_randomChance(8)) _brutalizeMemory(); - from = _bound(from, 0, array.length + 10); - uint256 computed = DynamicArrayLib.indexOf(array, needle, from); - assertEq(computed, _indexOfOriginal(array, needle, from)); - if (_randomChance(16)) { - computed = DynamicArrayLib.indexOf(array, needle); - assertEq(computed, _indexOfOriginal(array, needle)); - computed = DynamicArrayLib.indexOf(DynamicArrayLib.DynamicArray(array), needle); - assertEq(computed, _indexOfOriginal(array, needle)); - } - } - - function _indexOfOriginal(uint256[] memory array, uint256 needle) - internal - pure - returns (uint256) - { - return _indexOfOriginal(array, needle, 0); - } - - function _indexOfOriginal(uint256[] memory array, uint256 needle, uint256 from) - internal - pure - returns (uint256) - { - unchecked { - uint256 n = array.length; - for (uint256 i = from; i < n; ++i) { - if (array[i] == needle) return i; - } - } - return type(uint256).max; - } - - function testUint256ArrayLastIndexOf() public { - uint256 n = 50; - uint256[] memory a; - assertEq(DynamicArrayLib.lastIndexOf(a, 0), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.lastIndexOf(a, 1), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.lastIndexOf(a, 2), DynamicArrayLib.NOT_FOUND); - a = new uint256[](0); - assertEq(DynamicArrayLib.lastIndexOf(a, 0), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.lastIndexOf(a, 1), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.lastIndexOf(a, 2), DynamicArrayLib.NOT_FOUND); - a = new uint256[](1); - assertEq(DynamicArrayLib.lastIndexOf(a, 0), 0); - assertEq(DynamicArrayLib.lastIndexOf(a, 1), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.lastIndexOf(a, 2), DynamicArrayLib.NOT_FOUND); - a = DynamicArrayLib.malloc(n); - unchecked { - for (uint256 i; i != n; ++i) { - a.set(i, i); - } - } - assertEq(DynamicArrayLib.lastIndexOf(a, 0), 0); - assertEq(DynamicArrayLib.lastIndexOf(a, 1), 1); - assertEq(DynamicArrayLib.lastIndexOf(a, 10), 10); - assertEq(DynamicArrayLib.lastIndexOf(a, 31), 31); - assertEq(DynamicArrayLib.lastIndexOf(a, 32), 32); - assertEq(DynamicArrayLib.lastIndexOf(a, 49), 49); - assertEq(DynamicArrayLib.lastIndexOf(a, 50), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.lastIndexOf(a, 100), DynamicArrayLib.NOT_FOUND); - - // edge case - assertEq(DynamicArrayLib.lastIndexOf(a, 0, 0), 0); - assertEq(DynamicArrayLib.lastIndexOf(a, 1, 1), 1); - assertEq(DynamicArrayLib.lastIndexOf(a, 10, 10), 10); - assertEq(DynamicArrayLib.lastIndexOf(a, 31, 31), 31); - assertEq(DynamicArrayLib.lastIndexOf(a, 32, 32), 32); - assertEq(DynamicArrayLib.lastIndexOf(a, 49, 49), 49); - assertEq(DynamicArrayLib.lastIndexOf(a, 50, 50), DynamicArrayLib.NOT_FOUND); - assertEq(DynamicArrayLib.lastIndexOf(a, 100, 100), DynamicArrayLib.NOT_FOUND); - } - - function testUint256ArrayLastIndexOfDifferential( - uint256[] memory array, - uint256 needle, - uint256 from - ) public { - if (_randomChance(2)) _misalignFreeMemoryPointer(); - if (_randomChance(8)) _brutalizeMemory(); - from = _bound(from, 0, array.length + 10); - uint256 computed = DynamicArrayLib.lastIndexOf(array, needle, from); - assertEq(computed, _lastIndexOfOriginal(array, needle, from)); - if (_randomChance(16)) { - computed = DynamicArrayLib.lastIndexOf(array, needle); - assertEq(computed, _lastIndexOfOriginal(array, needle)); - computed = DynamicArrayLib.lastIndexOf(DynamicArrayLib.DynamicArray(array), needle); - assertEq(computed, _lastIndexOfOriginal(array, needle)); - } - } - - function _lastIndexOfOriginal(uint256[] memory array, uint256 needle) - internal - pure - returns (uint256) - { - return _lastIndexOfOriginal(array, needle, type(uint256).max); - } - - function _lastIndexOfOriginal(uint256[] memory array, uint256 needle, uint256 from) - internal - pure - returns (uint256) - { - unchecked { - uint256 n = array.length; - if (n > 0) { - if (from >= n) from = (n - 1); - for (uint256 i = (from + 1); i != 0;) { - --i; - if (array[i] == needle) return i; - } - } - } - return type(uint256).max; - } - - function testUint256ArrayPopulate() public { - unchecked { - uint256 n = 100; - uint256[] memory a = DynamicArrayLib.malloc(n); - for (uint256 i; i != n; ++i) { - a.set(i, i); - } - uint256 sum; - for (uint256 i; i != n; ++i) { - sum += a.get(i); - } - assertEq(sum, 4950); - } - } - - function testUint256ArrayPopulateOriginal() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = i; - } - uint256 sum; - for (uint256 i; i != n; ++i) { - sum += a[i]; - } - assertEq(sum, 4950); - } - } - - function testUint256ArrayOperations(uint256 n, uint256 r) public { - unchecked { - n = _bound(n, 0, 50); - uint256[] memory a = DynamicArrayLib.malloc(n); - assertEq(a.length, n); - _checkMemory(a); - for (uint256 i; i != n; ++i) { - a.set(i, i ^ r); - } - for (uint256 i; i != n; ++i) { - assertEq(a.get(i), i ^ r); - } - if (_randomChance(32)) { - DynamicArrayLib.DynamicArray memory b; - for (uint256 i; i != n; ++i) { - b.p(i ^ r); - } - assertEq(b.hash(), a.hash()); - if (_randomChance(2)) { - assertEq(b.resize(0).resize(n).hash(), a.zeroize().hash()); - } - } - if (n > 5 && _randomChance(8)) { - a.set(0, 1).set(1, 2); - assertEq(a.get(0), 1); - assertEq(a.get(1), 2); - } - uint256 lengthBefore = n; - n = _bound(_random(), 0, 50); - if (n < lengthBefore) { - assertEq(a.truncate(n).length, n); - } else { - assertEq(a.truncate(n).length, lengthBefore); - } - if (_randomChance(2)) { - assertEq(a.free().length, 0); - _checkMemory(a); - } - } - } - - function testUint256ArrayMisc() public { - uint256[] memory a = DynamicArrayLib.malloc(1); - assertEq(a.set(0, address(3)).get(0), 3); - assertEq(a.set(0, bytes32(uint256(9))).get(0), 9); - assertEq(a.set(0, bytes32(uint256(9))).getUint256(0), 9); - assertEq(a.set(0, bytes32(uint256(9))).getAddress(0), address(9)); - assertEq(a.set(0, bytes32(uint256(9))).getBool(0), true); - assertEq(a.set(0, true).get(0), 1); - } - - function testDynamicArraySetAndGet(bytes32, uint256 i, uint256 n) public { - DynamicArrayLib.DynamicArray memory a; - n = _bound(n, 1, 5); - a.resize(n); - { - i = _bound(i, 0, n - 1); - address data = _randomHashedAddress(); - assertEq(a.set(i, data).getAddress(i), data); - } - { - i = _bound(i, 0, n - 1); - bool data = _randomChance(2); - assertEq(a.set(i, data).getBool(i), data); - } - { - i = _bound(i, 0, n - 1); - bytes32 data = bytes32(_random()); - assertEq(a.set(i, data).getBytes32(i), data); - } - { - i = _bound(i, 0, n - 1); - uint256 data = _random(); - assertEq(a.set(i, data).get(i), data); - } - } - - function testDynamicArrayFree(uint256 n) public { - DynamicArrayLib.DynamicArray memory a; - uint256 m = _freeMemoryPointer(); - n = _bound(n, 0, 50); - if (_randomChance(16)) a.reserve(n); - a.free(); - assertEq(m, _freeMemoryPointer()); - } - - function testUint256ArrayDirectReturn(uint256 seed) public { - unchecked { - uint256[] memory a = this.uint256ArrayDirectReturn(seed); - assertEq(a[0], seed + 0); - assertEq(a[1], seed + 1); - assertEq(a[2], seed + 2); - assertEq(a.length, 3); - _checkMemory(a); - } - } - - function uint256ArrayDirectReturn(uint256 seed) external pure returns (uint256[] memory) { - unchecked { - uint256[] memory result = DynamicArrayLib.malloc(3); - result.set(0, seed + 0); - result.set(1, seed + 1); - result.set(2, seed + 2); - DynamicArrayLib.directReturn(result); - } - } - - function testDynamicArrayDirectReturn(uint256 seed) public { - unchecked { - uint256[] memory a = this.dynamicArrayDirectReturn(seed); - assertEq(a[0], seed + 0); - assertEq(a[1], seed + 1); - assertEq(a[2], seed + 2); - assertEq(a.length, 3); - _checkMemory(a); - } - } - - function dynamicArrayDirectReturn(uint256 seed) external pure returns (uint256[] memory) { - unchecked { - DynamicArrayLib.p(seed + 0).p(seed + 1).p(seed + 2).directReturn(); - } - } - - function _sliceOriginal(uint256[] memory a, uint256 start, uint256 end) - internal - pure - returns (uint256[] memory result) - { - if (start > a.length) start = a.length; - if (end > a.length) end = a.length; - unchecked { - if (start < end) { - uint256 n = end - start; - result = new uint256[](n); - for (uint256 i; i != n; ++i) { - result[i] = a[start + i]; - } - } - } - } -} diff --git a/grouperBot/lib/solady/test/DynamicBufferLib.t.sol b/grouperBot/lib/solady/test/DynamicBufferLib.t.sol deleted file mode 100644 index a608290..0000000 --- a/grouperBot/lib/solady/test/DynamicBufferLib.t.sol +++ /dev/null @@ -1,505 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {DynamicBufferLib} from "../src/utils/DynamicBufferLib.sol"; - -contract DynamicBufferLibTest is SoladyTest { - using DynamicBufferLib for DynamicBufferLib.DynamicBuffer; - - function testDynamicBufferPushSingles(uint256 x, uint256 y, uint256 z) public { - if (_randomChance(32)) _brutalizeMemory(); - DynamicBufferLib.DynamicBuffer memory buffer; - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } - buffer.pUint256(x); - assertEq(buffer.data, abi.encodePacked(uint256(x))); - buffer.pUint256(y).pUint256(z); - assertEq(buffer.data, abi.encodePacked(uint256(x), uint256(y), uint256(z))); - } - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } else { - buffer.clear(); - } - buffer.pUint32(uint32(x)); - assertEq(buffer.data, abi.encodePacked(uint32(x))); - buffer.pUint32(uint32(y)).pUint32(uint32(z)); - assertEq(buffer.data, abi.encodePacked(uint32(x), uint32(y), uint32(z))); - } - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } else { - buffer.clear(); - } - buffer.pUint8(uint8(x)); - assertEq(buffer.data, abi.encodePacked(uint8(x))); - buffer.pUint8(uint8(y)).pUint8(uint8(z)); - assertEq(buffer.data, abi.encodePacked(uint8(x), uint8(y), uint8(z))); - } - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } else { - buffer.clear(); - } - buffer.pBytes32(bytes32(x)); - assertEq(buffer.data, abi.encodePacked(bytes32(x))); - buffer.pBytes32(bytes32(y)).pBytes32(bytes32(z)); - assertEq(buffer.data, abi.encodePacked(bytes32(x), bytes32(y), bytes32(z))); - } - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } else { - buffer.clear(); - } - buffer.pBytes3(bytes3(bytes32(x))); - assertEq(buffer.data, abi.encodePacked(bytes3(bytes32(x)))); - buffer.pBytes3(bytes3(bytes32(y))).pBytes3(bytes3(bytes32(z))); - assertEq( - buffer.data, - abi.encodePacked(bytes3(bytes32(x)), bytes3(bytes32(y)), bytes3(bytes32(z))) - ); - } - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } else { - buffer.clear(); - } - buffer.pBytes1(bytes1(bytes32(x))); - assertEq(buffer.data, abi.encodePacked(bytes1(bytes32(x)))); - buffer.pBytes1(bytes1(bytes32(y))).pBytes1(bytes1(bytes32(z))); - assertEq( - buffer.data, - abi.encodePacked(bytes1(bytes32(x)), bytes1(bytes32(y)), bytes1(bytes32(z))) - ); - } - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } else { - buffer.clear(); - } - buffer.pBool(x % 2 == 0); - assertEq(buffer.data, abi.encodePacked(x % 2 == 0)); - buffer.pBool(y % 2 == 0).pBool(z % 2 == 0); - assertEq(buffer.data, abi.encodePacked(x % 2 == 0, y % 2 == 0, z % 2 == 0)); - } - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(4)) { - if (_randomChance(2)) { - DynamicBufferLib.DynamicBuffer memory newBuffer; - buffer = newBuffer; - } else { - buffer.clear(); - } - buffer.pAddress(address(uint160(x))); - assertEq(buffer.data, abi.encodePacked(address(uint160(x)))); - buffer.pAddress(address(uint160(y))).pAddress(address(uint160(z))); - assertEq( - buffer.data, - abi.encodePacked(address(uint160(x)), address(uint160(y)), address(uint160(z))) - ); - } - } - - function testDynamicBufferPushSinglesReinterpretCast() public { - uint256 n = 32; - DynamicBufferLib.DynamicBuffer memory buffer; - uint256[] memory expected = new uint256[](n); - unchecked { - for (uint256 i; i != n; ++i) { - uint256 v = (i << 128) | 1; - buffer.pUint256(v); - expected[i] = v; - } - } - uint256[] memory computed; - /// @solidity memory-safe-assembly - assembly { - computed := mload(buffer) - let nBytes := mload(computed) - mstore(computed, shr(5, nBytes)) - } - assertEq(computed, expected); - } - - function testClear(uint256) public { - DynamicBufferLib.DynamicBuffer memory buffer; - bytes memory b0 = _generateRandomBytes(128, _random()); - bytes memory b1 = _generateRandomBytes(256, _random()); - bytes memory emptyBytes; - assertEq(buffer.data.length, 0); - assertEq(emptyBytes.length, 0); - if (_random() & 1 == 0) buffer.clear(); - assertEq(buffer.data.length, 0); - assertEq(emptyBytes.length, 0); - buffer.clear().p(b0); - assertEq(buffer.data, b0); - assertEq(emptyBytes.length, 0); - uint256 n0 = _bound(_random(), 0, 1024); - uint256 n1 = _bound(_random(), 0, 4096); - buffer.reserve(n0).p(b1).clear().reserve(n1); - assertEq(buffer.data.length, 0); - assertEq(emptyBytes.length, 0); - buffer.p(b1); - assertEq(buffer.data, b1); - assertEq(emptyBytes.length, 0); - buffer.p(b0); - assertEq(buffer.data, abi.encodePacked(b1, b0)); - assertEq(emptyBytes.length, 0); - buffer.clear(); - } - - function testDynamicBufferReserveFromEmpty() public { - uint256 m = _freeMemoryPointer(); - DynamicBufferLib.DynamicBuffer memory buffer; - assertEq(_freeMemoryPointer(), m + 0x20); - buffer.reserve(0x200); - assertTrue(_freeMemoryPointer() > m + 0x20); - assertTrue(_freeMemoryPointer() < 0xffff); - m = _freeMemoryPointer(); - buffer.reserve(0x200); - assertEq(_freeMemoryPointer(), m); - buffer.reserve(0x200); - assertEq(_freeMemoryPointer(), m); - } - - function testDynamicBufferReserveFromEmpty2() public { - DynamicBufferLib.DynamicBuffer memory buffer; - _incrementFreeMemoryPointer(); - buffer.reserve(0x200); - uint256 m = _freeMemoryPointer(); - buffer.reserve(0x200); - assertEq(_freeMemoryPointer(), m); - buffer.reserve(0x200); - assertEq(_freeMemoryPointer(), m); - } - - function testDynamicBufferReserveFromEmpty3(bytes calldata b, uint256 t) public { - DynamicBufferLib.DynamicBuffer memory buffer; - if (t & 1 == 0) _incrementFreeMemoryPointer(); - if (t & 2 == 0) buffer.p(_generateRandomBytes((t >> 32) & 0xff, 1)); - if (t & 4 == 0) buffer.p(b); - assertTrue(_freeMemoryPointer() < 0xffffff); - uint256 r = t >> 240; - buffer.reserve(r); - assertTrue(_freeMemoryPointer() < 0xffffff); - uint256 m = _freeMemoryPointer(); - buffer.reserve(r); - assertEq(_freeMemoryPointer(), m); - buffer.reserve(r); - assertEq(_freeMemoryPointer(), m); - } - - function _bufferLocation(DynamicBufferLib.DynamicBuffer memory buffer) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(buffer) - } - } - - function testDynamicBuffer(uint256) public brutalizeMemory { - unchecked { - if (_random() & 7 == 0) _misalignFreeMemoryPointer(); - DynamicBufferLib.DynamicBuffer memory bufferA; - DynamicBufferLib.DynamicBuffer memory bufferB; - uint256 z = _bound(_random(), 32, 4096); - if (_random() & 7 == 0) bufferA.reserve(_random() % z); - if (_random() & 7 == 0) bufferB.reserve(_random() % z); - uint256 r = _random() % 3; - uint256 o = _bound(_random(), 0, 32); - uint256 n = _bound(_random(), 5, _random() & 7 == 0 ? 64 : 8); - z = z + z; - - if (r == 0) { - for (uint256 i; i != n; ++i) { - if (_random() & 7 == 0) bufferA.reserve(_random() % z); - bufferA.p(_generateRandomBytes(i + o, i + z)); - } - for (uint256 i; i != n; ++i) { - if (_random() & 7 == 0) bufferB.reserve(_random() % z); - bufferB.p(_generateRandomBytes(i + o, i + z)); - } - } else if (r == 1) { - for (uint256 i; i != n; ++i) { - if (_random() & 7 == 0) bufferB.reserve(_random() % z); - bufferB.p(_generateRandomBytes(i + o, i + z)); - } - for (uint256 i; i != n; ++i) { - if (_random() & 7 == 0) bufferA.reserve(_random() % z); - bufferA.p(_generateRandomBytes(i + o, i + z)); - } - } else { - uint256 mode; - for (uint256 i; i != n; ++i) { - if (_random() & 7 == 0) mode ^= 1; - if (mode == 0) { - if (_random() & 7 == 0) bufferA.reserve(_random() % z); - bufferA.p(_generateRandomBytes(i + o, i + z)); - if (_random() & 7 == 0) bufferB.reserve(_random() % z); - bufferB.p(_generateRandomBytes(i + o, i + z)); - } else { - if (_random() & 7 == 0) bufferB.reserve(_random() % z); - bufferB.p(_generateRandomBytes(i + o, i + z)); - if (_random() & 7 == 0) bufferA.reserve(_random() % z); - bufferA.p(_generateRandomBytes(i + o, i + z)); - } - } - } - - bytes memory expected; - for (uint256 i; i != n; ++i) { - expected = bytes.concat(expected, _generateRandomBytes(i + o, i + z)); - } - assertEq(bufferA.data, expected); - assertEq(bufferB.data, expected); - } - } - - function _generateRandomBytes(uint256 n, uint256 seed) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - if n { - result := mload(0x40) - mstore(result, n) - mstore(0x00, seed) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(0x20, i) - mstore(add(add(result, 0x20), i), keccak256(0x00, 0x40)) - } - mstore(0x40, add(add(result, 0x20), n)) - } - } - } - - function testDynamicBuffer(bytes[] memory inputs, uint256 t) public brutalizeMemory { - _boundInputs(inputs); - - uint256 sharedLocation; - if ((t >> 128) & 1 == 0) { - bytes memory first = _generateRandomBytes((t & 0xff | 1), t); - bytes memory expectedResult = first; - for (uint256 i; i < inputs.length; ++i) { - expectedResult = bytes.concat(expectedResult, inputs[i]); - } - DynamicBufferLib.DynamicBuffer memory buffer; - buffer.p(first); - uint256 location = _bufferLocation(buffer); - for (uint256 i; i < inputs.length; ++i) { - buffer.p(inputs[i]); - assertEq(_bufferLocation(buffer), location); - _checkMemory(buffer.data); - } - assertEq(buffer.data, expectedResult); - sharedLocation = _bufferLocation(buffer); - } - - if ((t >> 129) & 1 == 0) { - if ((t >> 16) & 7 == 0) _misalignFreeMemoryPointer(); - DynamicBufferLib.DynamicBuffer memory buffer; - if ((t >> 160) & 3 == 0) _incrementFreeMemoryPointer(); - if ((t >> 130) & 1 == 0 && sharedLocation != 0) { - /// @solidity memory-safe-assembly - assembly { - mstore(buffer, sharedLocation) - } - buffer.clear(); - } - if ((t >> 162) & 3 == 0) _incrementFreeMemoryPointer(); - if ((t >> 32) & 3 == 0) { - buffer.reserve((t >> 128) % 1024); - } - - unchecked { - uint256 expectedLength; - uint256 start; - if (t & 1 == 0) { - if (inputs.length > 0) { - expectedLength = inputs[0].length; - buffer.data = inputs[0]; - start = 1; - } - } - for (uint256 i = start; i < inputs.length; ++i) { - expectedLength += inputs[i].length; - // Manually store the t in the next free memory word, - // and then check if p will corrupt it - // (in the case of insufficient memory allocation). - uint256 corruptCheckSlot; - /// @solidity memory-safe-assembly - assembly { - corruptCheckSlot := mload(0x40) - mstore(corruptCheckSlot, t) - mstore(0x40, add(corruptCheckSlot, 0x20)) - } - buffer.p(inputs[i]); - if ((t >> 48) & 7 == 0 && expectedLength != 0) { - buffer.reserve((t >> 160) % (expectedLength * 2)); - } - assertEq(buffer.data.length, expectedLength); - _checkMemory(buffer.data); - bool isCorrupted; - /// @solidity memory-safe-assembly - assembly { - isCorrupted := iszero(eq(t, mload(corruptCheckSlot))) - } - assertFalse(isCorrupted); - } - } - - bytes memory expectedResult; - unchecked { - for (uint256 i; i < inputs.length; ++i) { - expectedResult = bytes.concat(expectedResult, inputs[i]); - } - } - - assertEq(keccak256(buffer.data), keccak256(expectedResult)); - } - } - - function testJoinWithConcat() public { - bytes memory expectedResult; - (bytes[] memory chunks, bytes32 joinedHash) = _getChunks(); - unchecked { - for (uint256 i; i < chunks.length; ++i) { - expectedResult = bytes.concat(expectedResult, chunks[i]); - } - } - assertEq(keccak256(expectedResult), joinedHash); - } - - function testJoinWithDynamicBuffer() public { - DynamicBufferLib.DynamicBuffer memory buffer; - (bytes[] memory chunks, bytes32 joinedHash) = _getChunks(); - unchecked { - for (uint256 i; i < chunks.length; ++i) { - buffer.p(chunks[i]); - } - } - assertEq(keccak256(buffer.data), joinedHash); - } - - function testDynamicBufferChaining() public { - DynamicBufferLib.DynamicBuffer memory bufferA; - DynamicBufferLib.DynamicBuffer memory bufferB; - bufferA = bufferB.p("0", "1"); - _checkSamePointers(bufferA, bufferB); - bufferA = bufferB.p("0", "1", "2"); - _checkSamePointers(bufferA, bufferB); - bufferA = bufferB.p("0", "1", "2", "3"); - _checkSamePointers(bufferA, bufferB); - bufferA = bufferB.p("0", "1", "2", "3", "4"); - _checkSamePointers(bufferA, bufferB); - bufferA = bufferB.p("0", "1", "2", "3", "4", "5"); - _checkSamePointers(bufferA, bufferB); - bufferA = bufferB.p("0", "1", "2", "3", "4", "5", "6"); - _checkSamePointers(bufferA, bufferB); - assertEq(bufferA.data, "010120123012340123450123456"); - assertEq(bufferB.data, "010120123012340123450123456"); - } - - function testDynamicBufferShorthands() public { - assertEq(DynamicBufferLib.p().s(), ""); - assertEq(DynamicBufferLib.p("0").s(), "0"); - assertEq(DynamicBufferLib.p("0", "1").s(), "01"); - assertEq(DynamicBufferLib.p("0", "1", "2").s(), "012"); - assertEq(DynamicBufferLib.p("0", "1", "2", "3").s(), "0123"); - assertEq(DynamicBufferLib.p("0", "1", "2", "3", "4").s(), "01234"); - assertEq(DynamicBufferLib.p("0", "1", "2", "3", "4", "5").s(), "012345"); - assertEq(DynamicBufferLib.p("0", "1", "2", "3", "4", "5", "6").s(), "0123456"); - assertEq(DynamicBufferLib.pBool(true).s(), DynamicBufferLib.p().pBool(true).s()); - assertEq(DynamicBufferLib.pBool(false).s(), DynamicBufferLib.p().pBool(false).s()); - assertEq( - DynamicBufferLib.pAddress(address(this)).s(), - DynamicBufferLib.p().pAddress(address(this)).s() - ); - assertEq(DynamicBufferLib.pUint8(11).s(), DynamicBufferLib.p().pUint8(11).s()); - assertEq(DynamicBufferLib.pUint256(11).s(), DynamicBufferLib.p().pUint256(11).s()); - assertEq( - DynamicBufferLib.pBytes1(bytes1(uint8(2))).s(), - DynamicBufferLib.p().pBytes1(bytes1(uint8(2))).s() - ); - assertEq( - DynamicBufferLib.pBytes32(bytes32(uint256(2))).s(), - DynamicBufferLib.p().pBytes32(bytes32(uint256(2))).s() - ); - } - - function _checkSamePointers( - DynamicBufferLib.DynamicBuffer memory a, - DynamicBufferLib.DynamicBuffer memory b - ) internal { - bool isSamePointer; - assembly { - isSamePointer := eq(a, b) - } - assertTrue(isSamePointer); - } - - function _getChunks() internal pure returns (bytes[] memory chunks, bytes32 joinedHash) { - chunks = new bytes[](20); - chunks[0] = bytes( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." - ); - chunks[1] = bytes("Vitae suscipit tellus mauris a diam maecenas sed enim ut."); - chunks[2] = bytes("Nisl nisi scelerisque eu ultrices vitae auctor eu augue."); - chunks[3] = bytes("Et pharetra pharetra massa massa ultricies mi quis."); - chunks[4] = bytes("Ullamcorper malesuada proin libero nunc."); - chunks[5] = bytes("Tempus imperdiet nulla malesuada pellentesque."); - chunks[6] = bytes("Nunc congue nisi vitae suscipit tellus mauris."); - chunks[7] = bytes("Eu augue ut lectus arcu."); - chunks[8] = bytes("Natoque penatibus et magnis dis parturient montes nascetur."); - chunks[9] = bytes("Convallis posuere morbi leo urna."); - - chunks[15] = bytes("Hehe"); - - joinedHash = 0x166b0e99fea53034ed188896344996efc141b922127f90922905e478cb26b312; - } - - function _boundInputs(bytes[] memory inputs) internal pure { - // Limit the total number of inputs. - /// @solidity memory-safe-assembly - assembly { - if gt(mload(inputs), 16) { mstore(inputs, 16) } - } - unchecked { - // Limit the lengths of the inputs. - for (uint256 i; i < inputs.length; ++i) { - bytes memory x = inputs[i]; - /// @solidity memory-safe-assembly - assembly { - if gt(mload(x), 128) { mstore(x, 128) } - } - } - } - } -} diff --git a/grouperBot/lib/solady/test/ECDSA.t.sol b/grouperBot/lib/solady/test/ECDSA.t.sol deleted file mode 100644 index 799b798..0000000 --- a/grouperBot/lib/solady/test/ECDSA.t.sol +++ /dev/null @@ -1,667 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {ECDSA} from "../src/utils/ECDSA.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract ECDSATest is SoladyTest { - using ECDSA for bytes32; - using ECDSA for bytes; - - bytes32 constant TEST_MESSAGE = - 0x7dbaf558b0a1a5dc7a67202117ab143c1d8605a983e4a743bc06fcc03162dc0d; - - bytes32 constant WRONG_MESSAGE = - 0x2d0828dd7c97cff316356da3c16c68ba2316886a0e05ebafb8291939310d51a3; - - address constant SIGNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; - - address constant V0_SIGNER = 0x2cc1166f6212628A0deEf2B33BEFB2187D35b86c; - - address constant V1_SIGNER = 0x1E318623aB09Fe6de3C9b8672098464Aeda9100E; - - function testTryRecoverWithInvalidShortSignatureReturnsZero() public { - bytes memory signature = hex"1234"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == address(0)); - } - - function testTryRecoverWithInvalidLongSignatureReturnsZero() public { - bytes memory signature = - hex"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == address(0)); - } - - function testTryRecoverWithValidSignature() public { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - assertTrue(this.tryRecover(TEST_MESSAGE.toEthSignedMessageHash(), signature) == SIGNER); - } - - function testTryRecoverWithWrongSigner() public { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - assertTrue(this.tryRecover(WRONG_MESSAGE.toEthSignedMessageHash(), signature) != SIGNER); - } - - function testTryRecoverWithInvalidSignature() public { - bytes memory signature = - hex"332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c"; - assertTrue(this.tryRecover(TEST_MESSAGE.toEthSignedMessageHash(), signature) != SIGNER); - } - - function testTryRecoverWithV0SignatureWithVersion00ReturnsZero() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be89200"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == address(0)); - } - - function testTryRecoverWithV0SignatureWithVersion27() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be8921b"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == V0_SIGNER); - } - - function testTryRecoverWithV0SignatureWithWrongVersionReturnsZero() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be89202"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == address(0)); - } - - function testTryRecoverWithV0SignatureWithShortEIP2098Format() public { - bytes32 r = 0x5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f; - bytes32 vs = 0x3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892; - assertTrue(this.tryRecover(TEST_MESSAGE, r, vs) == V0_SIGNER); - } - - function testTryRecoverWithV0SignatureWithShortEIP2098FormatAsCalldata() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == V0_SIGNER); - } - - function testTryRecoverWithV1SignatureWithVersion01ReturnsZero() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e001"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == address(0)); - } - - function testTryRecoverWithV1SignatureWithVersion28() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == V1_SIGNER); - } - - function testTryRecoverWithV1SignatureWithWrongVersionReturnsZero() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e002"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == address(0)); - } - - function testTryRecoverWithV1SignatureWithShortEIP2098Format() public { - bytes32 r = 0x331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff; - bytes32 vs = 0xc8e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e0; - assertTrue(this.tryRecover(TEST_MESSAGE, r, vs) == V1_SIGNER); - } - - function testTryRecoverWithV1SignatureWithShortEIP2098FormatAsCalldata() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feffc8e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e0"; - assertTrue(this.tryRecover(TEST_MESSAGE, signature) == V1_SIGNER); - } - - function testRecoverWithInvalidShortSignatureReturnsZero() public { - bytes memory signature = hex"1234"; - vm.expectRevert(ECDSA.InvalidSignature.selector); - this.recover(TEST_MESSAGE, signature); - } - - function testRecoverWithInvalidLongSignatureReverts() public { - bytes memory signature = - hex"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; - vm.expectRevert(ECDSA.InvalidSignature.selector); - this.recover(TEST_MESSAGE, signature); - } - - function testRecoverWithValidSignature() public { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - address recovered = this.recover(TEST_MESSAGE.toEthSignedMessageHash(), signature); - assertTrue(recovered == SIGNER); - } - - function testRecoverWithWrongSigner() public { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - assertTrue(this.recover(WRONG_MESSAGE.toEthSignedMessageHash(), signature) != SIGNER); - } - - function testRecoverWithInvalidSignatureReverts() public { - bytes memory signature = - hex"332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c"; - vm.expectRevert(ECDSA.InvalidSignature.selector); - this.recover(TEST_MESSAGE.toEthSignedMessageHash(), signature); - } - - function testRecoverWithV0SignatureWithVersion00Reverts() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be89200"; - vm.expectRevert(ECDSA.InvalidSignature.selector); - this.recover(TEST_MESSAGE, signature); - } - - function testRecoverWithV0SignatureWithVersion27() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be8921b"; - assertTrue(this.recover(TEST_MESSAGE, signature) == V0_SIGNER); - } - - function testRecoverWithV0SignatureWithWrongVersionReverts() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be89202"; - vm.expectRevert(ECDSA.InvalidSignature.selector); - this.recover(TEST_MESSAGE, signature); - } - - function testRecoverWithV0SignatureWithShortEIP2098Format() public { - bytes32 r = 0x5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f; - bytes32 vs = 0x3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892; - assertTrue(this.recover(TEST_MESSAGE, r, vs) == V0_SIGNER); - } - - function testRecoverWithV0SignatureWithShortEIP2098FormatAsCalldata() public { - bytes memory signature = - hex"5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892"; - this.recover(TEST_MESSAGE, signature); - } - - function testRecoverWithV1SignatureWithVersion01Reverts() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e001"; - vm.expectRevert(ECDSA.InvalidSignature.selector); - this.recover(TEST_MESSAGE, signature); - } - - function testRecoverWithV1SignatureWithVersion28() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c"; - assertTrue(this.recover(TEST_MESSAGE, signature) == V1_SIGNER); - } - - function testRecoverWithV1SignatureWithWrongVersionReverts() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e002"; - vm.expectRevert(ECDSA.InvalidSignature.selector); - this.recover(TEST_MESSAGE, signature); - } - - function testRecoverWithV1SignatureWithShortEIP2098Format() public { - bytes32 r = 0x331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff; - bytes32 vs = 0xc8e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e0; - assertTrue(this.recover(TEST_MESSAGE, r, vs) == V1_SIGNER); - } - - function testRecoverWithV1SignatureWithShortEIP2098FormatAsCalldata() public { - bytes memory signature = - hex"331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feffc8e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e0"; - this.recover(TEST_MESSAGE, signature); - } - - struct _CheckSignatureTestTemps { - bytes argsSignature; - bytes encodedCalldataArgs; - address signer; - bool expected; - bool[2] success; - bytes[2] result; - bytes4 s; - address recovered; - } - - function _checkSignature( - address signer, - bytes32 digest, - uint8 v, - bytes32 r, - bytes32 s, - bool expected - ) internal { - _CheckSignatureTestTemps memory t; - t.signer = signer; - t.expected = expected; - - t.argsSignature = "(bytes32,uint8,bytes32,bytes32)"; - t.encodedCalldataArgs = abi.encode(digest, v, r, s); - _checkSignature(t); - - if (v == 27 || v == 28) { - bytes32 vs = bytes32((v == 28 ? 1 << 255 : 0) | uint256(s)); - t.argsSignature = "(bytes32,bytes32,bytes32)"; - t.encodedCalldataArgs = abi.encode(digest, r, vs); - _checkSignature(t); - } - - if (_random() & 1 == 0) { - t.argsSignature = "(bytes32,bytes)"; - t.encodedCalldataArgs = abi.encode(digest, abi.encodePacked(r, s, v)); - _checkSignature(t); - } - } - - function _checkSignature(_CheckSignatureTestTemps memory t) internal { - t.s = bytes4(keccak256(abi.encodePacked("tryRecover", t.argsSignature))); - (t.success[0], t.result[0]) = - address(this).call(abi.encodePacked(t.s, t.encodedCalldataArgs)); - t.recovered = t.success[0] ? abi.decode(t.result[0], (address)) : address(0); - assertEq(t.recovered == t.signer, t.expected); - - t.s = bytes4(keccak256(abi.encodePacked("tryRecoverBrutalized", t.argsSignature))); - (t.success[1], t.result[1]) = - address(this).call(abi.encodePacked(t.s, t.encodedCalldataArgs)); - t.recovered = t.success[1] ? abi.decode(t.result[1], (address)) : address(0); - assertEq(t.recovered == t.signer, t.expected); - - t.s = bytes4(keccak256(abi.encodePacked("recover", t.argsSignature))); - (t.success[0], t.result[0]) = - address(this).call(abi.encodePacked(t.s, t.encodedCalldataArgs)); - - t.s = bytes4(keccak256(abi.encodePacked("recoverBrutalized", t.argsSignature))); - (t.success[1], t.result[1]) = - address(this).call(abi.encodePacked(t.s, t.encodedCalldataArgs)); - - assertEq(t.success[0], t.success[1]); - assertEq(t.result[0], t.result[1]); - - if (t.success[0]) { - t.recovered = abi.decode(t.result[0], (address)); - assertEq(t.recovered == t.signer, t.expected); - } - } - - function testRecoverAndTryRecover(bytes32 digest) public { - (address signer, uint256 privateKey) = _randomSigner(); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - if (_random() & 7 == 0) { - _checkSignature(signer, digest, v, r, s, true); - } - - uint8 vc = v ^ uint8(_random() & 0xff); - bytes32 rc = bytes32(uint256(r) ^ _random()); - bytes32 sc = bytes32(uint256(s) ^ _random()); - bool anyCorrupted = vc != v || rc != r || sc != s; - _checkSignature(signer, digest, vc, rc, sc, !anyCorrupted); - } - - function testBytes32ToEthSignedMessageHash() public { - assertEq( - TEST_MESSAGE.toEthSignedMessageHash(), - bytes32(0x7d768af957ef8cbf6219a37e743d5546d911dae3e46449d8a5810522db2ef65e) - ); - } - - function testBytesToEthSignedMessageHashShort() public { - bytes memory message = hex"61626364"; - assertEq( - message.toEthSignedMessageHash(), - bytes32(0xefd0b51a9c4e5f3449f4eeacb195bf48659fbc00d2f4001bf4c088ba0779fb33) - ); - } - - function testBytesToEthSignedMessageHashEmpty() public { - bytes memory message = hex""; - assertEq( - message.toEthSignedMessageHash(), - bytes32(0x5f35dce98ba4fba25530a026ed80b2cecdaa31091ba4958b99b52ea1d068adad) - ); - } - - function testBytesToEthSignedMessageHashLong() public { - bytes memory message = - hex"4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a3031323334353637383921402324255e262a28292d3d5b5d7b7d"; - assertEq( - message.toEthSignedMessageHash(), - bytes32(0xa46dbedd405cff161b6e80c17c8567597621d9f4c087204201097cb34448e71b) - ); - } - - function testBytesToEthSignedMessageHash() public { - _testBytesToEthSignedMessageHash(999999); - _testBytesToEthSignedMessageHash(135790); - _testBytesToEthSignedMessageHash(99999); - _testBytesToEthSignedMessageHash(88888); - _testBytesToEthSignedMessageHash(3210); - _testBytesToEthSignedMessageHash(111); - _testBytesToEthSignedMessageHash(22); - _testBytesToEthSignedMessageHash(1); - _testBytesToEthSignedMessageHash(0); - } - - function testBytesToEthSignedMessageHashExceedsMaxLengthReverts() public { - vm.expectRevert(); - this._testBytesToEthSignedMessageHash(999999 + 1); - } - - function _testBytesToEthSignedMessageHash(uint256 n) public brutalizeMemory { - bytes memory message; - /// @solidity memory-safe-assembly - assembly { - message := mload(0x40) - mstore(message, n) - mstore(0x40, add(add(message, 0x20), n)) - } - assertEq( - message.toEthSignedMessageHash(), - keccak256( - abi.encodePacked("\x19Ethereum Signed Message:\n", LibString.toString(n), message) - ) - ); - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, message) - } - } - - function tryRecover(bytes32 hash, bytes calldata signature) external returns (address result) { - result = ECDSA.tryRecoverCalldata(hash, signature); - assertEq(ECDSA.tryRecover(hash, signature), result); - } - - function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) - external - view - returns (address) - { - return ECDSA.tryRecover(hash, v, r, s); - } - - function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) external view returns (address) { - return ECDSA.tryRecover(hash, r, vs); - } - - function tryRecoverBrutalized(bytes32 hash, bytes calldata signature) - external - brutalizeMemory - returns (address result) - { - result = ECDSA.tryRecoverCalldata(hash, signature); - assertEq(ECDSA.tryRecover(hash, signature), result); - } - - function tryRecoverBrutalized(bytes32 hash, uint8 v, bytes32 r, bytes32 s) - external - view - brutalizeMemory - returns (address) - { - return ECDSA.tryRecover(hash, v, r, s); - } - - function tryRecoverBrutalized(bytes32 hash, bytes32 r, bytes32 vs) - external - view - brutalizeMemory - returns (address) - { - return ECDSA.tryRecover(hash, r, vs); - } - - function recover(bytes32 hash, bytes calldata signature) external returns (address result) { - result = ECDSA.recoverCalldata(hash, signature); - assertEq(ECDSA.recover(hash, signature), result); - } - - function recover(bytes32 hash, bytes32 r, bytes32 vs) external view returns (address) { - return ECDSA.recover(hash, r, vs); - } - - function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) external view returns (address) { - return ECDSA.recover(hash, v, r, s); - } - - function recoverBrutalized(bytes32 hash, bytes calldata signature) - external - brutalizeMemory - returns (address result) - { - result = ECDSA.recoverCalldata(hash, signature); - assertEq(ECDSA.recover(hash, signature), result); - } - - function recoverBrutalized(bytes32 hash, bytes32 r, bytes32 vs) - external - view - brutalizeMemory - returns (address) - { - return ECDSA.recover(hash, r, vs); - } - - function recoverBrutalized(bytes32 hash, uint8 v, bytes32 r, bytes32 s) - external - view - brutalizeMemory - returns (address) - { - return ECDSA.recover(hash, v, r, s); - } - - function testCanonicalHashWithRegularSignature() public brutalizeMemory { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - assertEq(ECDSA.canonicalHash(signature), keccak256(signature)); - bytes memory signature_malleable = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe265281a24fe3d37b4f138b91e48b268b8a3a6506db9b47083084edbdf3fbcca4c426571c"; - assertEq(ECDSA.canonicalHash(signature_malleable), keccak256(signature)); - } - - function testCanonicalHashWith64bytesSignature() public brutalizeMemory { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - bytes memory shortSignature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea"; - - assertEq(ECDSA.canonicalHash(shortSignature), keccak256(signature)); - } - - function testCanonicalHashCalldataWithRegularSignature() public { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - assertEq(this.canonicalHashCalldata(signature), keccak256(signature)); - assertEq(this.canonicalHashCalldataBrutalizeMemory(signature), keccak256(signature)); - - bytes memory signature_malleable = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe265281a24fe3d37b4f138b91e48b268b8a3a6506db9b47083084edbdf3fbcca4c426571c"; - - assertEq(this.canonicalHashCalldata(signature_malleable), keccak256(signature)); - assertEq( - this.canonicalHashCalldataBrutalizeMemory(signature_malleable), keccak256(signature) - ); - } - - function testCanonicalHashCalldataWith64bytesSignature() public { - bytes memory signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - bytes memory shortSignature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea"; - - assertEq(this.canonicalHashCalldata(shortSignature), keccak256(signature)); - assertEq(this.canonicalHashCalldataBrutalizeMemory(shortSignature), keccak256(signature)); - signature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1c"; - shortSignature = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe265281ddb01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea"; - - assertEq(this.canonicalHashCalldata(shortSignature), keccak256(signature)); - assertEq(this.canonicalHashCalldataBrutalizeMemory(shortSignature), keccak256(signature)); - } - - function testCanonicalHash(bytes32 digest) public { - bytes memory signature; - bytes32 cHash; - address signer; - { - uint256 privateKey; - (signer, privateKey) = _randomSigner(); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - v = _brutalizedUint8(v); - signature = abi.encodePacked(r, s, v); - cHash = ECDSA.canonicalHash(signature); - assertEq(keccak256(signature), cHash); - assertEq(ECDSA.canonicalHash(r, _vs(v, s)), cHash); - - if (_randomChance(2)) { - s = bytes32(uint256(ECDSA.N) - uint256(s)); - v = v ^ 7; - } - - if (_randomChance(8)) { - assertEq(ECDSA.canonicalHash(v, r, s), cHash); - assertEq(ECDSA.canonicalHash(abi.encodePacked(r, s, v)), cHash); - assertEq(ECDSA.canonicalHash(_shortSignature(abi.encodePacked(r, s, v))), cHash); - _checkMemory(); - } - - if (_randomChance(2)) { - bytes memory shortSignature = _shortSignature(signature); - assertEq(ECDSA.canonicalHash(shortSignature), cHash); - if (_randomChance(8)) { - assertEq(this.canonicalHashCalldataBrutalizeMemory(shortSignature), cHash); - } - } - - if (_randomChance(4)) { - uint8 corruptedV = _brutalizedUint8(uint8(_random())); - assertEq( - ECDSA.canonicalHash(abi.encodePacked(r, s, corruptedV)), - ECDSA.canonicalHash(corruptedV, r, s) - ); - if (corruptedV == 27 || corruptedV == 28) { - assertEq( - ECDSA.canonicalHash(abi.encodePacked(r, s, corruptedV)), - ECDSA.canonicalHash(r, _vs(corruptedV, s)) - ); - } - _checkMemory(); - } - } - - bytes memory corruptedSignature = _corruptedSignature(signature); - bytes32 corruptedCHash = ECDSA.canonicalHash(corruptedSignature); - if (_randomChance(8)) { - assertEq(this.canonicalHashCalldata(corruptedSignature), corruptedCHash); - if (_randomChance(2)) { - assertEq( - this.canonicalHashCalldataBrutalizeMemory(corruptedSignature), corruptedCHash - ); - } - } - - if (ECDSA.tryRecover(digest, corruptedSignature) == signer) { - assertEq(corruptedCHash, cHash); - } else { - assertNotEq(corruptedCHash, cHash); - if (_randomChance(2)) { - bytes memory corruptedSignature2 = _corruptedSignature(signature); - if (ECDSA.tryRecover(digest, corruptedSignature2) != signer) { - if (keccak256(corruptedSignature) != keccak256(corruptedSignature2)) { - assertNotEq(corruptedCHash, ECDSA.canonicalHash(corruptedSignature2)); - } - } - } - } - } - - function _shortSignature(bytes memory signature) internal pure returns (bytes memory) { - require(signature.length == 65, "Wrong length"); - bytes32 r; - bytes32 s; - uint8 v; - /// @solidity memory-safe-assembly - assembly { - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := and(0xff, mload(add(signature, 0x41))) - } - return abi.encodePacked(r, _vs(v, s)); - } - - function _vs(uint8 v, bytes32 s) internal pure returns (bytes32 vs) { - uint256 n = uint256(ECDSA.N); - /// @solidity memory-safe-assembly - assembly { - v := and(0xff, v) - if lt(shr(1, n), s) { - v := xor(v, 7) - s := sub(n, s) - } - vs := or(s, shl(255, eq(v, 28))) - } - } - - function _corruptedSignature(bytes memory signature) internal returns (bytes memory result) { - if (_randomChance(2)) { - result = abi.encodePacked(signature, uint8(_random()), _random()); - } else { - result = abi.encodePacked(_shortSignature(signature), uint8(_random()), _random()); - } - unchecked { - uint256 corruptedLength = _random() % (result.length + 1); - /// @solidity memory-safe-assembly - assembly { - mstore(result, corruptedLength) - } - if (corruptedLength == 0 && _randomChance(2)) { - /// @solidity memory-safe-assembly - assembly { - result := 0x60 - } - } - } - } - - function canonicalHashCalldata(bytes calldata signature) external pure returns (bytes32) { - return ECDSA.canonicalHashCalldata(signature); - } - - function canonicalHashCalldataBrutalizeMemory(bytes calldata signature) - external - view - brutalizeMemory - returns (bytes32) - { - return ECDSA.canonicalHashCalldata(signature); - } - - function testEmptyCalldataHelpers() public { - assertFalse(ECDSA.tryRecover(bytes32(0), ECDSA.emptySignature()) == address(1)); - } - - function testMalleabilityTrick(uint256 s) public { - unchecked { - uint256 n = uint256(ECDSA.N); - uint256 halfN = n >> 1; - uint256 halfNPlus1 = halfN + 1; - - uint256 expected = s; - if (expected > halfN) { - expected = n - expected; - } - - uint256 computed = s; - if (!(computed < halfNPlus1)) { - computed = (halfNPlus1 + halfNPlus1) - (computed + 1); - } - assertEq(computed, expected); - } - } - - function testMalleabilityTrick() public { - unchecked { - uint256 s = (uint256(ECDSA.N) >> 1) - 5; - for (uint256 i; i < 10; ++i) { - testMalleabilityTrick(s + i); - } - } - } -} diff --git a/grouperBot/lib/solady/test/EIP712.t.sol b/grouperBot/lib/solady/test/EIP712.t.sol deleted file mode 100644 index e39b77a..0000000 --- a/grouperBot/lib/solady/test/EIP712.t.sol +++ /dev/null @@ -1,344 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MockEIP712} from "./utils/mocks/MockEIP712.sol"; -import {MockEIP712Dynamic} from "./utils/mocks/MockEIP712Dynamic.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; - -contract EIP712Test is SoladyTest { - MockEIP712 mock; - MockEIP712 mockClone; - MockEIP712Dynamic mockDynamic; - MockEIP712Dynamic mockDynamicClone; - - function setUp() public { - mock = new MockEIP712(); - mockClone = MockEIP712(LibClone.clone(address(mock))); - mockDynamic = new MockEIP712Dynamic("Milady", "1"); - mockDynamicClone = MockEIP712Dynamic(LibClone.clone(address(mockDynamic))); - } - - function testHashTypedData() public { - _testHashTypedDataOnClone(mock); - } - - function testHashTypedDataOnClone() public { - _testHashTypedDataOnClone(mockClone); - } - - function testHashTypedDataOnDynamic() public { - _testHashTypedDataOnClone(MockEIP712(address(mockDynamic))); - } - - function testHashTypedDataOnCloneDynamic() public { - _testHashTypedDataOnClone(MockEIP712(address(mockDynamicClone))); - } - - function testHashTypedDataWithChaindIdChange() public { - _testHashTypedDataOnClone(mock); - vm.chainId(32123); - _testHashTypedDataOnClone(mock); - } - - function testHashTypedDataOnCloneWithChaindIdChange() public { - _testHashTypedDataOnClone(mockClone); - vm.chainId(32123); - _testHashTypedDataOnClone(mockClone); - } - - function testHashTypedDataOnDynamicWithChaindIdChange() public { - _testHashTypedDataOnClone(MockEIP712(address(mockDynamic))); - vm.chainId(32123); - _testHashTypedDataOnClone(MockEIP712(address(mockDynamic))); - } - - function testHashTypedDataOnCloneDynamicWithChaindIdChange() public { - _testHashTypedDataOnClone(MockEIP712(address(mockDynamicClone))); - vm.chainId(32123); - _testHashTypedDataOnClone(MockEIP712(address(mockDynamicClone))); - } - - struct _TestTemps { - string name; - string version; - address signer; - address to; - uint256 privateKey; - bytes32 structHash; - bytes32 expectedDigest; - string message; - uint8 v; - bytes32 r; - bytes32 s; - address recoveredAddress; - } - - function _testHashTypedDataOnClone(MockEIP712 mockToTest) internal { - _TestTemps memory t; - (t.signer, t.privateKey) = _randomSigner(); - - (t.to,) = _randomSigner(); - - t.message = "Hello Milady!"; - - t.structHash = keccak256(abi.encode("Message(address to,string message)", t.to, t.message)); - t.expectedDigest = - keccak256(abi.encodePacked("\x19\x01", mockToTest.DOMAIN_SEPARATOR(), t.structHash)); - - assertEq(mockToTest.hashTypedData(t.structHash), t.expectedDigest); - - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.expectedDigest); - - t.recoveredAddress = ecrecover(t.expectedDigest, t.v, t.r, t.s); - - assertEq(t.recoveredAddress, t.signer); - } - - function testDomainSeparator() public { - _testDomainSeparator(mock); - } - - function testDomainSeparatorOnClone() public { - _testDomainSeparator(mockClone); - } - - function testDomainSeparatorWithChainIdChange() public { - _testDomainSeparator(mock); - vm.chainId(32123); - _testDomainSeparator(mock); - } - - function testDomainSeparatorOnCloneWithChainIdChange() public { - _testDomainSeparator(mockClone); - vm.chainId(32123); - _testDomainSeparator(mockClone); - } - - function testDomainSeparatorOnDynamicWithChainIdChange() public { - _testDomainSeparator(MockEIP712(address(mockDynamic))); - vm.chainId(32123); - _testDomainSeparator(MockEIP712(address(mockDynamic))); - mockDynamic.setDomainNameAndVersion("Remilio", "2"); - _testDomainSeparator(MockEIP712(address(mockDynamic)), "Remilio", "2"); - } - - function testDomainSeparatorOnCloneDynamicWithChainIdChange() public { - mockDynamicClone.setDomainNameAndVersion("Milady", "1"); - _testDomainSeparator(MockEIP712(address(mockDynamicClone))); - vm.chainId(32123); - _testDomainSeparator(MockEIP712(address(mockDynamicClone))); - mockDynamicClone.setDomainNameAndVersion("Remilio", "2"); - _testDomainSeparator(MockEIP712(address(mockDynamicClone)), "Remilio", "2"); - } - - function _testDomainSeparator(MockEIP712 mockToTest, bytes memory name, bytes memory version) - internal - { - bytes32 expectedDomainSeparator = keccak256( - abi.encode( - keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" - ), - keccak256(name), - keccak256(version), - block.chainid, - address(mockToTest) - ) - ); - - assertEq(mockToTest.DOMAIN_SEPARATOR(), expectedDomainSeparator); - } - - function _testDomainSeparator(MockEIP712 mockToTest) internal { - _testDomainSeparator(mockToTest, "Milady", "1"); - } - - function testEIP5267() public { - _testEIP5267(mock); - _testEIP5267(mockClone); - vm.chainId(32123); - _testEIP5267(mock); - _testEIP5267(mockClone); - } - - struct _testEIP5267Variables { - bytes1 fields; - string name; - string version; - uint256 chainId; - address verifyingContract; - bytes32 salt; - uint256[] extensions; - } - - function _testEIP5267(MockEIP712 mockToTest) public { - _testEIP5267Variables memory t; - (t.fields, t.name, t.version, t.chainId, t.verifyingContract, t.salt, t.extensions) = - mockToTest.eip712Domain(); - - assertEq(t.fields, hex"0f"); - assertEq(t.name, "Milady"); - assertEq(t.version, "1"); - assertEq(t.chainId, block.chainid); - assertEq(t.verifyingContract, address(mockToTest)); - assertEq(t.salt, bytes32(0)); - assertEq(t.extensions, new uint256[](0)); - } - - function _testHashTypedDataSansChainId(MockEIP712 mockToTest) public { - _TestTemps memory t; - (, t.name, t.version,,,,) = mockToTest.eip712Domain(); - - (t.signer, t.privateKey) = _randomSigner(); - - (t.to,) = _randomSigner(); - - t.message = "Hello Milady!"; - - t.structHash = keccak256(abi.encode("Message(address to,string message)", t.to, t.message)); - t.expectedDigest = keccak256( - abi.encodePacked( - "\x19\x01", - keccak256( - abi.encode( - keccak256( - "EIP712Domain(string name,string version,address verifyingContract)" - ), - keccak256(bytes(t.name)), - keccak256(bytes(t.version)), - address(mockToTest) - ) - ), - t.structHash - ) - ); - - assertEq(mockToTest.hashTypedDataSansChainId(t.structHash), t.expectedDigest); - - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.expectedDigest); - - t.recoveredAddress = ecrecover(t.expectedDigest, t.v, t.r, t.s); - - assertEq(t.recoveredAddress, t.signer); - } - - function testHashTypedDataSansChainId() public { - _testHashTypedDataSansChainId(mock); - } - - function testHashTypedDataSansChainIdOnClone() public { - _testHashTypedDataSansChainId(mockClone); - } - - function testHashTypedDataSansChainIdOnDynamic() public { - _testHashTypedDataSansChainId(MockEIP712(address(mockDynamic))); - } - - function testHashTypedDataSansChainIdOnDynamicClone() public { - _testHashTypedDataSansChainId(MockEIP712(address(mockDynamicClone))); - } - - function _testHashTypedDataSansChainIdAndVerifyingContract(MockEIP712 mockToTest) public { - _TestTemps memory t; - (, t.name, t.version,,,,) = mockToTest.eip712Domain(); - - (t.signer, t.privateKey) = _randomSigner(); - - (t.to,) = _randomSigner(); - - t.message = "Hello Milady!"; - - t.structHash = keccak256(abi.encode("Message(address to,string message)", t.to, t.message)); - t.expectedDigest = keccak256( - abi.encodePacked( - "\x19\x01", - keccak256( - abi.encode( - keccak256("EIP712Domain(string name,string version)"), - keccak256(bytes(t.name)), - keccak256(bytes(t.version)) - ) - ), - t.structHash - ) - ); - - assertEq( - mockToTest.hashTypedDataSansChainIdAndVerifyingContract(t.structHash), t.expectedDigest - ); - - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.expectedDigest); - - t.recoveredAddress = ecrecover(t.expectedDigest, t.v, t.r, t.s); - - assertEq(t.recoveredAddress, t.signer); - } - - function testHashTypedDataSansChainIdAndVerifyingContract() public { - _testHashTypedDataSansChainIdAndVerifyingContract(mock); - } - - function testHashTypedDataSansChainIdAndVerifyingContractOnClone() public { - _testHashTypedDataSansChainIdAndVerifyingContract(mockClone); - } - - function testHashTypedDataSansChainIdAndVerifyingContractOnDynamic() public { - _testHashTypedDataSansChainIdAndVerifyingContract(MockEIP712(address(mockDynamic))); - } - - function testHashTypedDataSansChainIdAndVerifyingContractOnDynamicClone() public { - _testHashTypedDataSansChainIdAndVerifyingContract(MockEIP712(address(mockDynamicClone))); - } - - function _testHashTypedDataSansVerifyingContract(MockEIP712 mockToTest) public { - _TestTemps memory t; - (, t.name, t.version,,,,) = mockToTest.eip712Domain(); - - (t.signer, t.privateKey) = _randomSigner(); - - (t.to,) = _randomSigner(); - - t.message = "Hello Milady!"; - - t.structHash = keccak256(abi.encode("Message(address to,string message)", t.to, t.message)); - t.expectedDigest = keccak256( - abi.encodePacked( - "\x19\x01", - keccak256( - abi.encode( - keccak256("EIP712Domain(string name,string version,uint256 chainId)"), - keccak256(bytes(t.name)), - keccak256(bytes(t.version)), - block.chainid - ) - ), - t.structHash - ) - ); - - assertEq(mockToTest.hashTypedDataSansVerifyingContract(t.structHash), t.expectedDigest); - - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.expectedDigest); - - t.recoveredAddress = ecrecover(t.expectedDigest, t.v, t.r, t.s); - - assertEq(t.recoveredAddress, t.signer); - } - - function testHashTypedDataSansVerifyingContract() public { - _testHashTypedDataSansVerifyingContract(mock); - } - - function testHashTypedDataSansVerifyingContractOnClone() public { - _testHashTypedDataSansVerifyingContract(mockClone); - } - - function testHashTypedDataSansVerifyingContractOnDynamic() public { - _testHashTypedDataSansVerifyingContract(MockEIP712(address(mockDynamic))); - } - - function testHashTypedDataSansVerifyingContractOnDynamicClone() public { - _testHashTypedDataSansVerifyingContract(MockEIP712(address(mockDynamicClone))); - } -} diff --git a/grouperBot/lib/solady/test/EIP7702Proxy.t.sol b/grouperBot/lib/solady/test/EIP7702Proxy.t.sol deleted file mode 100644 index 7b0261f..0000000 --- a/grouperBot/lib/solady/test/EIP7702Proxy.t.sol +++ /dev/null @@ -1,293 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibEIP7702} from "../src/accounts/LibEIP7702.sol"; - -interface IEIP7702ProxyWithAdminABI { - function implementation() external view returns (address); - function admin() external view returns (address); - function changeAdmin(address) external returns (bool); - function upgrade(address) external returns (bool); - function bad() external; -} - -contract Implementation2 { - uint256 public value; - - function version() external pure returns (uint256) { - return 2; - } - - function setValue(uint256 value_) public { - value = value_; - LibEIP7702.requestProxyDelegationInitialization(); - } - - function upgradeProxyDelegation(address newImplementation) public { - LibEIP7702.upgradeProxyDelegation(newImplementation); - } -} - -contract EIP7702ProxyTest is SoladyTest { - error CustomError(uint256 currentValue); - - uint256 public value; - - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - bytes32 internal constant _ERC1967_ADMIN_SLOT = - 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - function setValue(uint256 value_) public { - value = value_; - LibEIP7702.requestProxyDelegationInitialization(); - } - - function revertWithError() public view { - revert CustomError(value); - } - - function version() external pure returns (uint256) { - return 1; - } - - function unsetProxyDelegation() public { - LibEIP7702.upgradeProxyDelegation(address(0)); - } - - function _checkBehavesLikeProxy(address instance) internal { - assertTrue(instance != address(0)); - - assertEq(EIP7702ProxyTest(instance).version(), 1); - - uint256 v = _randomUniform(); - uint256 thisValue = this.value(); - if (thisValue == v) { - v ^= 1; - } - EIP7702ProxyTest(instance).setValue(v); - assertEq(v, EIP7702ProxyTest(instance).value()); - - assertEq(thisValue, this.value()); - vm.expectRevert(abi.encodeWithSelector(CustomError.selector, v)); - EIP7702ProxyTest(instance).revertWithError(); - } - - function upgradeProxyDelegation(address newImplementation) public { - LibEIP7702.upgradeProxyDelegation(newImplementation); - } - - function testEIP7702Proxy(bytes32, bool f) public { - vm.pauseGasMetering(); - - address admin = _randomUniqueHashedAddress(); - IEIP7702ProxyWithAdminABI eip7702Proxy = - IEIP7702ProxyWithAdminABI(LibEIP7702.deployProxy(address(this), admin)); - assertEq(eip7702Proxy.admin(), admin); - assertEq(LibEIP7702.proxyAdmin(address(eip7702Proxy)), admin); - assertEq(eip7702Proxy.implementation(), address(this)); - assertEq(LibEIP7702.implementationOf(address(eip7702Proxy)), address(this)); - - if (!f && _randomChance(16)) { - address newAdmin = _randomUniqueHashedAddress(); - vm.startPrank(admin); - if (_randomChance(2)) { - eip7702Proxy.changeAdmin(newAdmin); - } else { - LibEIP7702.changeProxyAdmin(address(eip7702Proxy), newAdmin); - } - assertEq(eip7702Proxy.admin(), newAdmin); - vm.stopPrank(); - admin = newAdmin; - vm.startPrank(_randomUniqueHashedAddress()); - vm.expectRevert(); - eip7702Proxy.changeAdmin(newAdmin); - vm.stopPrank(); - } - - if (!f && _randomChance(16)) { - address newImplementation = _randomUniqueHashedAddress(); - vm.startPrank(admin); - if (_randomChance(2)) { - eip7702Proxy.upgrade(newImplementation); - } else { - LibEIP7702.upgradeProxy(address(eip7702Proxy), newImplementation); - } - assertEq(eip7702Proxy.implementation(), newImplementation); - eip7702Proxy.upgrade(address(this)); - assertEq(eip7702Proxy.implementation(), address(this)); - vm.stopPrank(); - } - - if (!f && _randomChance(16)) { - vm.startPrank(admin); - vm.expectRevert(); - eip7702Proxy.bad(); - vm.stopPrank(); - } - - // Generate some random value that has the lower 160 bits zeroized, - // to test if the proxy can handle dirty bits. - uint256 r = (_random() >> 160) << 160; - vm.store(address(this), _ERC1967_IMPLEMENTATION_SLOT, bytes32(r)); - - if (!f && _randomChance(16)) { - address newImplementation = _randomUniqueHashedAddress(); - LibEIP7702.upgradeProxyDelegation(newImplementation); - uint256 loaded = uint256(vm.load(address(this), _ERC1967_IMPLEMENTATION_SLOT)); - assertEq(address(uint160(loaded)), newImplementation); - assertEq(loaded >> 160, r >> 160); - } - - address authority = _randomUniqueHashedAddress(); - assertEq(LibEIP7702.delegationOf(authority), address(0)); - vm.etch(authority, abi.encodePacked(hex"ef0100", address(eip7702Proxy))); - - vm.store(authority, _ERC1967_IMPLEMENTATION_SLOT, bytes32(r)); - - emit LogAddress("authority", authority); - emit LogAddress("proxy", address(eip7702Proxy)); - emit LogAddress("address(this)", address(this)); - - // Runtime REVM detection. - // If this check fails, then we are not ready to test it in CI. - // The exact length is 23 at the time of writing as of the EIP7702 spec, - // but we give our heuristic some leeway. - if (authority.code.length > 0x20) return; - - vm.resumeGasMetering(); - - _checkBehavesLikeProxy(authority); - - vm.pauseGasMetering(); - - if (!f) assertEq(LibEIP7702.delegationOf(authority), address(eip7702Proxy)); - - // Check that upgrading the proxy won't cause the authority's implementation to change. - if (!f && _randomChance(2)) { - vm.startPrank(admin); - eip7702Proxy.upgrade(address(1)); - } - - _checkBehavesLikeProxy(authority); - - if (!f && _randomChance(2)) { - EIP7702ProxyTest(authority).upgradeProxyDelegation(address(new Implementation2())); - assertEq(Implementation2(authority).version(), 2); - Implementation2(authority).upgradeProxyDelegation(address(this)); - } - - if (!f && _randomChance(2) && (r >> 160) > 0) { - vm.startPrank(admin); - eip7702Proxy.upgrade(address(new Implementation2())); - vm.stopPrank(); - EIP7702ProxyTest(authority).unsetProxyDelegation(); - assertEq(Implementation2(authority).version(), 2); - - uint256 loaded = uint256(vm.load(authority, _ERC1967_IMPLEMENTATION_SLOT)); - assertEq(address(uint160(loaded)), address(0)); - assertEq(loaded >> 160, r >> 160); - - EIP7702ProxyTest(authority).setValue(123); - assertEq(Implementation2(authority).version(), 2); - - loaded = uint256(vm.load(authority, _ERC1967_IMPLEMENTATION_SLOT)); - assertEq(address(uint160(loaded)), eip7702Proxy.implementation()); - assertEq(loaded >> 160, r >> 160); - } - - vm.resumeGasMetering(); - } - - function testEIP7702Proxy() public { - testEIP7702Proxy(0, true); - } - - function testEIP7702DelegationAndImplementationOf(bytes32) public { - address defaultImplementation = _randomUniqueHashedAddress(); - address defaultAdmin = _randomUniqueHashedAddress(); - - if (_randomChance(2)) { - defaultImplementation = address(this); - } - if (_randomChance(2)) { - defaultAdmin = address(0); - } - address proxy = LibEIP7702.deployProxy(defaultImplementation, defaultAdmin); - address authority = _randomUniqueHashedAddress(); - vm.etch(authority, abi.encodePacked(hex"ef0100", proxy)); - if (authority.code.length > 0x20) return; - - (address accountDelegation, address implementation) = - LibEIP7702.delegationAndImplementationOf(authority); - assertEq(accountDelegation, proxy); - assertEq(implementation, defaultImplementation); - - if (defaultAdmin != address(0)) { - address newImplementation = address(new Implementation2()); - vm.startPrank(defaultAdmin); - IEIP7702ProxyWithAdminABI(proxy).upgrade(newImplementation); - vm.stopPrank(); - (accountDelegation, implementation) = - LibEIP7702.delegationAndImplementationOf(authority); - assertEq(accountDelegation, proxy); - assertEq(implementation, newImplementation); - vm.startPrank(defaultAdmin); - IEIP7702ProxyWithAdminABI(proxy).upgrade(address(this)); - vm.stopPrank(); - } - - if (defaultImplementation == address(this)) { - address newImplementation = address(new Implementation2()); - EIP7702ProxyTest(authority).upgradeProxyDelegation(newImplementation); - (accountDelegation, implementation) = - LibEIP7702.delegationAndImplementationOf(authority); - assertEq(accountDelegation, proxy); - assertEq(implementation, newImplementation); - Implementation2(authority).upgradeProxyDelegation(address(this)); - } - } - - function testEIP7702ProxyWithDefaultImplementation(bytes32, bool f) public { - vm.pauseGasMetering(); - - IEIP7702ProxyWithAdminABI eip7702Proxy = - IEIP7702ProxyWithAdminABI(LibEIP7702.deployProxy(address(this), address(0))); - - assertEq(eip7702Proxy.admin(), address(0)); - assertEq(LibEIP7702.proxyAdmin(address(eip7702Proxy)), address(0)); - assertEq(eip7702Proxy.implementation(), address(this)); - assertEq(LibEIP7702.implementationOf(address(eip7702Proxy)), address(this)); - - address authority = _randomUniqueHashedAddress(); - assertEq(LibEIP7702.delegationOf(authority), address(0)); - vm.etch(authority, abi.encodePacked(hex"ef0100", address(eip7702Proxy))); - - // Generate some random value that has the lower 160 bits zeroized, - // to test if the proxy can handle dirty bits. - uint256 r = (_random() >> 160) << 160; - vm.store(authority, _ERC1967_IMPLEMENTATION_SLOT, bytes32(r)); - - if (authority.code.length > 0x20) return; - - vm.resumeGasMetering(); - - _checkBehavesLikeProxy(authority); - - vm.pauseGasMetering(); - - if (!f && _randomChance(2)) { - EIP7702ProxyTest(authority).upgradeProxyDelegation(address(new Implementation2())); - assertEq(Implementation2(authority).version(), 2); - Implementation2(authority).upgradeProxyDelegation(address(this)); - } - - vm.resumeGasMetering(); - } - - function testEIP7702ProxyWithDefaultImplementation() public { - testEIP7702ProxyWithDefaultImplementation(0, true); - } -} diff --git a/grouperBot/lib/solady/test/ERC1155.t.sol b/grouperBot/lib/solady/test/ERC1155.t.sol deleted file mode 100644 index 06e3854..0000000 --- a/grouperBot/lib/solady/test/ERC1155.t.sol +++ /dev/null @@ -1,1221 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; - -import {ERC1155, MockERC1155} from "./utils/mocks/MockERC1155.sol"; - -abstract contract ERC1155TokenReceiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - external - virtual - returns (bytes4) - { - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual returns (bytes4) { - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} - -contract ERC1155Recipient is ERC1155TokenReceiver { - address public operator; - address public from; - uint256 public id; - uint256 public amount; - bytes public mintData; - - function onERC1155Received( - address _operator, - address _from, - uint256 _id, - uint256 _amount, - bytes calldata _data - ) public override returns (bytes4) { - operator = _operator; - from = _from; - id = _id; - amount = _amount; - mintData = _data; - - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - address public batchOperator; - address public batchFrom; - uint256[] internal _batchIds; - uint256[] internal _batchAmounts; - bytes public batchData; - - function batchIds() external view returns (uint256[] memory) { - return _batchIds; - } - - function batchAmounts() external view returns (uint256[] memory) { - return _batchAmounts; - } - - function onERC1155BatchReceived( - address _operator, - address _from, - uint256[] calldata _ids, - uint256[] calldata _amounts, - bytes calldata _data - ) external override returns (bytes4) { - batchOperator = _operator; - batchFrom = _from; - _batchIds = _ids; - _batchAmounts = _amounts; - batchData = _data; - - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} - -contract RevertingERC1155Recipient is ERC1155TokenReceiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - public - pure - override - returns (bytes4) - { - revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector))); - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external pure override returns (bytes4) { - revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector))); - } -} - -contract WrongReturnDataERC1155Recipient is ERC1155TokenReceiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - public - pure - override - returns (bytes4) - { - return 0xCAFEBEEF; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external pure override returns (bytes4) { - return 0xCAFEBEEF; - } -} - -contract NonERC1155Recipient {} - -contract MockERC1155WithHooks is MockERC1155 { - uint256 public beforeCounter; - uint256 public afterCounter; - - function _useBeforeTokenTransfer() internal view virtual override returns (bool) { - return true; - } - - function _useAfterTokenTransfer() internal view virtual override returns (bool) { - return true; - } - - function _beforeTokenTransfer( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) internal virtual override { - beforeCounter++; - } - - function _afterTokenTransfer(address, address, uint256[] memory, uint256[] memory, bytes memory) - internal - virtual - override - { - afterCounter++; - } -} - -contract ERC1155HooksTest is SoladyTest, ERC1155TokenReceiver { - uint256 public expectedBeforeCounter; - uint256 public expectedAfterCounter; - - function _checkCounters() internal view { - require( - expectedBeforeCounter == MockERC1155WithHooks(msg.sender).beforeCounter(), - "Before counter mismatch." - ); - require( - expectedAfterCounter == MockERC1155WithHooks(msg.sender).afterCounter(), - "After counter mismatch." - ); - } - - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - external - virtual - override - returns (bytes4) - { - _checkCounters(); - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual override returns (bytes4) { - _checkCounters(); - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } - - function _testHooks(MockERC1155WithHooks token) internal { - address from = _randomNonZeroAddress(); - expectedBeforeCounter++; - expectedAfterCounter++; - token.mint(address(this), 1, 1000, ""); - - expectedBeforeCounter++; - expectedAfterCounter++; - token.safeTransferFrom(address(this), from, 1, 1000, ""); - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.safeTransferFrom(from, address(this), 1, 1, ""); - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.directSafeTransferFrom(from, address(this), 1, 1, ""); - - uint256[] memory ids = new uint256[](1); - uint256[] memory amounts = new uint256[](1); - ids[0] = 1; - amounts[0] = 1; - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.safeBatchTransferFrom(from, address(this), ids, amounts, ""); - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.directSafeBatchTransferFrom(from, address(this), ids, amounts, ""); - } - - function testERC1155Hooks() public { - MockERC1155WithHooks token = new MockERC1155WithHooks(); - - for (uint256 i; i < 32; ++i) { - _testHooks(token); - } - } -} - -contract ERC1155Test is SoladyTest, ERC1155TokenReceiver { - MockERC1155 token; - - event TransferSingle( - address indexed operator, - address indexed from, - address indexed to, - uint256 id, - uint256 amount - ); - - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] amounts - ); - - event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); - - mapping(address => mapping(uint256 => uint256)) public userMintAmounts; - mapping(address => mapping(uint256 => uint256)) public userTransferOrBurnAmounts; - - struct _TestTemps { - address from; - address to; - uint256 n; - uint256[] ids; - uint256[] mintAmounts; - uint256[] transferAmounts; - uint256[] burnAmounts; - uint256 id; - uint256 mintAmount; - uint256 transferAmount; - uint256 burnAmount; - bytes mintData; - bytes burnData; - bytes transferData; - } - - function _randomArray(uint256 n) internal returns (uint256[] memory a) { - /// @solidity memory-safe-assembly - assembly { - a := mload(0x40) - mstore(a, n) - mstore(0x40, add(add(a, 0x20), shl(5, n))) - } - unchecked { - for (uint256 i; i != n; ++i) { - a[i] = _random(); - } - } - } - - function _testTemps() internal returns (_TestTemps memory t) { - unchecked { - t.from = _randomNonZeroAddress(); - do { - t.to = _randomNonZeroAddress(); - } while (t.from == t.to); - uint256 n = _random() % 4; - t.n = n; - t.ids = _randomArray(n); - t.mintAmounts = _randomArray(n); - t.transferAmounts = _randomArray(n); - t.burnAmounts = _randomArray(n); - t.mintData = _randomBytes(); - t.burnData = _randomBytes(); - t.transferData = _randomBytes(); - t.id = _random(); - t.transferAmount = _random(); - t.burnAmount = _random(); - t.mintAmount = _random(); - } - } - - function _safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal { - if (_randomChance(2)) { - token.safeTransferFrom(from, to, id, amount, data); - } else { - token.directSafeTransferFrom(from, to, id, amount, data); - } - } - - function _safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal { - if (_randomChance(2)) { - token.safeBatchTransferFrom(from, to, ids, amounts, data); - } else { - token.directSafeBatchTransferFrom(from, to, ids, amounts, data); - } - } - - function _setApprovalForAll(address operator, bool approved) internal { - if (_randomChance(2)) { - token.setApprovalForAll(operator, approved); - } else { - token.directSetApprovalForAll(operator, approved); - } - } - - function _expectMintEvent(address to, uint256 id, uint256 amount) internal { - _expectMintEvent(address(this), to, id, amount); - } - - function _expectMintEvent(address operator, address to, uint256 id, uint256 amount) internal { - _expectTransferEvent(operator, address(0), to, id, amount); - } - - function _expectBurnEvent(address from, uint256 id, uint256 amount) internal { - _expectBurnEvent(address(this), from, id, amount); - } - - function _expectBurnEvent(address operator, address from, uint256 id, uint256 amount) - internal - { - _expectTransferEvent(operator, from, address(0), id, amount); - } - - function _expectTransferEvent(address from, address to, uint256 id, uint256 amount) internal { - _expectTransferEvent(address(this), from, to, id, amount); - } - - function _expectTransferEvent( - address operator, - address from, - address to, - uint256 id, - uint256 amount - ) internal { - vm.expectEmit(true, true, true, true); - emit TransferSingle(operator, from, to, id, amount); - } - - function _expectMintEvent(address to, uint256[] memory ids, uint256[] memory amounts) - internal - { - _expectMintEvent(address(this), to, ids, amounts); - } - - function _expectMintEvent( - address operator, - address to, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - _expectTransferEvent(operator, address(0), to, ids, amounts); - } - - function _expectBurnEvent(address from, uint256[] memory ids, uint256[] memory amounts) - internal - { - _expectBurnEvent(address(this), from, ids, amounts); - } - - function _expectBurnEvent( - address operator, - address from, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - _expectTransferEvent(operator, from, address(0), ids, amounts); - } - - function _expectTransferEvent( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - _expectTransferEvent(address(this), from, to, ids, amounts); - } - - function _expectTransferEvent( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - vm.expectEmit(true, true, true, true); - emit TransferBatch(operator, from, to, ids, amounts); - } - - function _expectApprovalForAllEvent(address operator, bool isApproved) internal { - _expectApprovalForAllEvent(address(this), operator, isApproved); - } - - function _expectApprovalForAllEvent(address owner, address operator, bool isApproved) - internal - { - vm.expectEmit(true, true, true, true); - emit ApprovalForAll(owner, operator, isApproved); - } - - function setUp() public { - token = new MockERC1155(); - } - - function testDirectSetApprovalForAll(address by, address operator, bool approved) public { - _expectApprovalForAllEvent(by, operator, approved); - vm.prank(by); - token.directSetApprovalForAll(operator, approved); - } - - function testAuthorizedEquivalence(address by, address from, bool isApprovedAccount) public { - bool a = true; - bool b = true; - /// @solidity memory-safe-assembly - assembly { - if by { if iszero(eq(by, from)) { a := isApprovedAccount } } - if iszero(or(iszero(by), eq(by, from))) { b := isApprovedAccount } - } - assertEq(a, b); - } - - function testMintToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - _expectMintEvent(t.to, t.id, t.mintAmount); - token.mint(t.to, t.id, t.mintAmount, t.mintData); - - assertEq(token.balanceOf(t.to, t.id), t.mintAmount); - } - - function testMintToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - - ERC1155Recipient to = new ERC1155Recipient(); - - _expectMintEvent(address(to), t.id, t.mintAmount); - token.mint(address(to), t.id, t.mintAmount, t.mintData); - - assertEq(token.balanceOf(address(to), t.id), t.mintAmount); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), t.id); - assertEq(to.mintData(), t.mintData); - } - - function testBatchMintToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.to][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[t.to][id] += mintAmount; - } - - _expectMintEvent(t.to, t.ids, t.mintAmounts); - token.batchMint(t.to, t.ids, t.mintAmounts, t.mintData); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - assertEq(token.balanceOf(t.to, id), userMintAmounts[t.to][id]); - } - } - - function testBatchMintToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - - ERC1155Recipient to = new ERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - _expectMintEvent(address(to), t.ids, t.mintAmounts); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), address(0)); - assertEq(to.batchIds(), t.ids); - assertEq(to.batchAmounts(), t.mintAmounts); - assertEq(to.batchData(), t.mintData); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - assertEq(token.balanceOf(address(to), id), userMintAmounts[address(to)][id]); - } - } - - function testBurn(uint256) public { - _TestTemps memory t = _testTemps(); - - t.burnAmount = _bound(t.burnAmount, 0, t.mintAmount); - - _expectMintEvent(t.to, t.id, t.mintAmount); - token.mint(t.to, t.id, t.mintAmount, t.mintData); - - if (_randomChance(2)) { - _expectBurnEvent(t.to, t.id, t.burnAmount); - token.uncheckedBurn(t.to, t.id, t.burnAmount); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - token.burn(t.to, t.id, t.burnAmount); - return; - } else { - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - _expectBurnEvent(t.to, t.id, t.burnAmount); - token.burn(t.to, t.id, t.burnAmount); - } - - assertEq(token.balanceOf(t.to, t.id), t.mintAmount - t.burnAmount); - } - - function testBatchBurn(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.to][id]; - - t.mintAmounts[i] = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - t.burnAmounts[i] = _bound(t.burnAmounts[i], 0, t.mintAmounts[i]); - - userMintAmounts[t.to][id] += t.mintAmounts[i]; - userTransferOrBurnAmounts[t.to][id] += t.burnAmounts[i]; - } - - _expectMintEvent(t.to, t.ids, t.mintAmounts); - token.batchMint(t.to, t.ids, t.mintAmounts, t.mintData); - - if (_randomChance(2)) { - _expectBurnEvent(t.to, t.ids, t.burnAmounts); - token.uncheckedBatchBurn(t.to, t.ids, t.burnAmounts); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - token.batchBurn(t.to, t.ids, t.burnAmounts); - return; - } else { - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - _expectBurnEvent(t.to, t.ids, t.burnAmounts); - token.batchBurn(t.to, t.ids, t.burnAmounts); - } - - for (uint256 i = 0; i < t.ids.length; i++) { - uint256 id = t.ids[i]; - - assertEq( - token.balanceOf(t.to, id), - userMintAmounts[t.to][id] - userTransferOrBurnAmounts[t.to][id] - ); - } - } - - function testApproveAll(address to, bool approved) public { - _expectApprovalForAllEvent(to, approved); - _setApprovalForAll(to, approved); - assertEq(token.isApprovedForAll(address(this), to), approved); - } - - function testSafeTransferFromToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - _expectMintEvent(t.from, t.id, t.mintAmount); - token.mint(t.from, t.id, t.mintAmount, t.mintData); - - if (_randomChance(2)) { - _expectTransferEvent(t.from, t.to, t.id, t.transferAmount); - token.uncheckedSafeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - _safeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - return; - } else { - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, t.to, t.id, t.transferAmount); - _safeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - } - - if (t.to == t.from) { - assertEq(token.balanceOf(t.to, t.id), t.mintAmount); - } else { - assertEq(token.balanceOf(t.to, t.id), t.transferAmount); - assertEq(token.balanceOf(t.from, t.id), t.mintAmount - t.transferAmount); - } - } - - function testSafeTransferFromToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - ERC1155Recipient to = new ERC1155Recipient(); - - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - _expectMintEvent(t.from, t.id, t.mintAmount); - token.mint(t.from, t.id, t.mintAmount, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, address(to), t.id, t.transferAmount); - _safeTransferFrom(t.from, address(to), t.id, t.transferAmount, t.transferData); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), t.from); - assertEq(to.id(), t.id); - assertEq(to.mintData(), t.transferData); - - assertEq(token.balanceOf(address(to), t.id), t.transferAmount); - assertEq(token.balanceOf(t.from, t.id), t.mintAmount - t.transferAmount); - } - - function testSafeTransferFromSelf(uint256) public { - _TestTemps memory t = _testTemps(); - - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - _expectMintEvent(address(this), t.id, t.mintAmount); - token.mint(address(this), t.id, t.mintAmount, t.mintData); - - _expectTransferEvent(address(this), t.to, t.id, t.transferAmount); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - - assertEq(token.balanceOf(t.to, t.id), t.transferAmount); - assertEq(token.balanceOf(address(this), t.id), t.mintAmount - t.transferAmount); - } - - function testSafeBatchTransfer() public { - for (uint256 i; i != 8; ++i) { - testSafeTransferFromToEOA(_random()); - testSafeBatchTransferFromToERC1155Recipient(_random()); - } - } - - function testSafeBatchTransferFromToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - userTransferOrBurnAmounts[t.from][id] += transferAmount; - } - _expectMintEvent(t.from, t.ids, t.mintAmounts); - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - if (_randomChance(2)) { - _expectTransferEvent(t.from, t.to, t.ids, t.transferAmounts); - token.uncheckedSafeBatchTransferFrom( - t.from, t.to, t.ids, t.transferAmounts, t.transferData - ); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - return; - } else { - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, t.to, t.ids, t.transferAmounts); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - assertEq(token.balanceOf(t.to, id), userTransferOrBurnAmounts[t.from][id]); - assertEq( - token.balanceOf(t.from, id), - userMintAmounts[t.from][id] - userTransferOrBurnAmounts[t.from][id] - ); - } - } - - function testSafeBatchTransferFromToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - - ERC1155Recipient to = new ERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - userTransferOrBurnAmounts[t.from][id] += transferAmount; - } - - _expectMintEvent(t.from, t.ids, t.mintAmounts); - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, address(to), t.ids, t.transferAmounts); - _safeBatchTransferFrom(t.from, address(to), t.ids, t.transferAmounts, t.transferData); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), t.from); - assertEq(to.batchIds(), t.ids); - assertEq(to.batchAmounts(), t.transferAmounts); - assertEq(to.batchData(), t.transferData); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - uint256 transferAmount = userTransferOrBurnAmounts[t.from][id]; - - assertEq(token.balanceOf(address(to), id), transferAmount); - assertEq(token.balanceOf(t.from, id), userMintAmounts[t.from][id] - transferAmount); - } - } - - function testBatchBalanceOf(uint256) public { - _TestTemps memory t = _testTemps(); - - address[] memory tos = new address[](t.n); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - address to = _randomNonZeroAddress(); - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id]; - - tos[i] = to; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - token.mint(to, id, mintAmount, t.mintData); - - userMintAmounts[to][id] += mintAmount; - } - - uint256[] memory balances = token.balanceOfBatch(tos, t.ids); - - for (uint256 i = 0; i != t.n; i++) { - assertEq(balances[i], token.balanceOf(tos[i], t.ids[i])); - } - } - - function testMintToZeroReverts(uint256) public { - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - token.mint(address(0), _random(), _random(), _randomBytes()); - } - - function testMintToNonERC155RecipientReverts(uint256) public { - address to = address(new NonERC1155Recipient()); - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.mint(to, _random(), _random(), _randomBytes()); - } - - function testMintToRevertingERC155RecipientReverts(uint256) public { - address to = address(new RevertingERC1155Recipient()); - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector)); - token.mint(to, _random(), _random(), _randomBytes()); - } - - function testMintToWrongReturnDataERC155RecipientReverts(uint256) public { - address to = address(new WrongReturnDataERC1155Recipient()); - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.mint(to, _random(), _random(), _randomBytes()); - } - - function testBurnInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - while (t.mintAmount == type(uint256).max) t.mintAmount = _random(); - t.burnAmount = _bound(t.burnAmount, t.mintAmount + 1, type(uint256).max); - - token.mint(t.to, t.id, t.mintAmount, t.mintData); - - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - token.burn(t.to, t.id, t.burnAmount); - } - - function testSafeTransferFromInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - while (t.mintAmount == type(uint256).max) t.mintAmount = _random(); - - t.transferAmount = _bound(t.transferAmount, t.mintAmount + 1, type(uint256).max); - - token.mint(t.from, t.id, t.mintAmount, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - _safeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromSelfInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - while (t.mintAmount == type(uint256).max) t.mintAmount = _random(); - - t.transferAmount = _bound(t.transferAmount, t.mintAmount + 1, type(uint256).max); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToZeroReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - _safeTransferFrom(address(this), address(0), t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToNonERC155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - t.to = address(new NonERC1155Recipient()); - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToRevertingERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - t.to = address(new RevertingERC1155Recipient()); - - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector)); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToWrongReturnDataERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - t.to = address(new WrongReturnDataERC1155Recipient()); - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeBatchTransferInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - while (t.n == 0) t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - if (mintAmount == type(uint256).max) return; - uint256 transferAmount = _bound(t.transferAmounts[i], mintAmount + 1, type(uint256).max); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToZeroReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - _safeBatchTransferFrom(t.from, address(0), t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToNonERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - t.to = address(new NonERC1155Recipient()); - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToRevertingERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - t.to = address(new RevertingERC1155Recipient()); - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector)); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToWrongReturnDataERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - t.to = address(new WrongReturnDataERC1155Recipient()); - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromWithArrayLengthMismatchReverts(uint256) public { - uint256[] memory ids = new uint256[](_random() % 4); - uint256[] memory mintAmounts = new uint256[](_random() % 4); - - if (ids.length == mintAmounts.length) return; - - address from = address(0xABCD); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.batchMint(from, ids, mintAmounts, _randomBytes()); - - uint256[] memory transferAmounts = new uint256[](_random() % 4); - if (ids.length == transferAmounts.length) return; - - vm.prank(from); - _setApprovalForAll(address(this), true); - - address to = _randomNonZeroAddress(); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - _safeBatchTransferFrom(from, to, ids, transferAmounts, _randomBytes()); - } - - function testBatchMintToZeroReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(0)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(0)][id] += mintAmount; - } - - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - token.batchMint(address(0), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintToNonERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - NonERC1155Recipient to = new NonERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintToRevertingERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - RevertingERC1155Recipient to = new RevertingERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector)); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintToWrongReturnDataERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintWithArrayMismatchReverts(uint256) public { - uint256[] memory ids = new uint256[](_random() % 4); - uint256[] memory amounts = new uint256[](_random() % 4); - - if (ids.length == amounts.length) return; - - address to = _randomNonZeroAddress(); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.batchMint(to, ids, amounts, _randomBytes()); - } - - function testBatchBurnInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - while (t.n == 0) t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.to][id]; - - t.mintAmounts[i] = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - if (t.mintAmounts[i] == type(uint256).max) return; - t.burnAmounts[i] = _bound(t.burnAmounts[i], t.mintAmounts[i] + 1, type(uint256).max); - - userMintAmounts[t.to][id] += t.mintAmounts[i]; - } - - token.batchMint(t.to, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - token.batchBurn(t.to, t.ids, t.burnAmounts); - } - - function testBatchBurnWithArrayLengthMismatchReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - if (t.ids.length == t.burnAmounts.length) t.burnAmounts = _randomArray(t.n + 1); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.batchBurn(t.to, t.ids, t.burnAmounts); - } - - function testBalanceOfBatchWithArrayMismatchReverts(uint256) public { - address[] memory tos = new address[](_random() % 4); - uint256[] memory ids = new uint256[](_random() % 4); - if (tos.length == ids.length) return; - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.balanceOfBatch(tos, ids); - } -} diff --git a/grouperBot/lib/solady/test/ERC1271.t.sol b/grouperBot/lib/solady/test/ERC1271.t.sol deleted file mode 100644 index 839f210..0000000 --- a/grouperBot/lib/solady/test/ERC1271.t.sol +++ /dev/null @@ -1,386 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {SignatureCheckerLib} from "../src/utils/SignatureCheckerLib.sol"; -import {ERC6551Proxy} from "../src/accounts/ERC6551Proxy.sol"; -import {EIP712} from "../src/utils/EIP712.sol"; -import {ERC6551, MockERC6551, MockERC6551V2} from "./utils/mocks/MockERC6551.sol"; -import {MockERC6551Registry} from "./utils/mocks/MockERC6551Registry.sol"; -import {MockERC721} from "./utils/mocks/MockERC721.sol"; -import {MockERC1155} from "./utils/mocks/MockERC1155.sol"; -import {LibZip} from "../src/utils/LibZip.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract ERC1271Test is SoladyTest { - MockERC6551Registry internal _registry; - - address internal _erc6551; - - address internal _erc6551V2; - - address internal _erc721; - - address internal _proxy; - - bool internal _fixChance; - - // By right, this should be the keccak256 of some long-ass string: - // (e.g. `keccak256("Parent(bytes32 childHash,Mail child)Mail(Person from,Person to,string contents)Person(string name,address wallet)")`). - // But I'm lazy and will use something randomish here. - bytes32 internal constant _PARENT_TYPEHASH = - 0xd61db970ec8a2edc5f9fd31d876abe01b785909acb16dcd4baaf3b434b4c439b; - - // By right, this should be a proper domain separator, but I'm lazy. - bytes32 internal constant _DOMAIN_SEP_B = - 0xa1a044077d7677adbbfa892ded5390979b33993e0e2a457e3f974bbcda53821b; - - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - struct _TestTemps { - address owner; - uint256 chainId; - uint256 tokenId; - bytes32 salt; - MockERC6551 account; - address signer; - uint256 privateKey; - uint8 v; - bytes32 r; - bytes32 s; - bytes32 contents; - bytes contentsDescription; - bytes signature; - } - - function setUp() public { - _registry = new MockERC6551Registry(); - _erc6551 = address(new MockERC6551()); - _erc721 = address(new MockERC721()); - _proxy = address(new ERC6551Proxy(_erc6551)); - _erc6551V2 = address(new MockERC6551V2()); - } - - function _etchBasefeeContract(bytes32 salt, bytes memory initcode) internal { - _nicksCreate2(0, salt, initcode); - } - - function _etchBasefeeContract() internal { - bytes memory initcode = hex"65483d52593df33d526006601af3"; - emit LogBytes32(keccak256(initcode)); - bytes32 salt = 0x00000000000000000000000000000000000000003c6f8b80e9be740191d2e48f; - _etchBasefeeContract(salt, initcode); - } - - function testBasefeeBytecodeContract() public { - address deployment = 0x000000000000378eDCD5B5B0A24f5342d8C10485; - vm.fee(11); - assertEq(_basefee(deployment), 0); - assertEq(deployment.code.length, 0); - _etchBasefeeContract(); - assertEq(deployment.code.length, 6); - assertEq(_basefee(deployment), 11); - vm.fee(12); - assertEq(_basefee(deployment), 12); - } - - function _basefee(address deployment) internal view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x00) - pop(staticcall(0xffff, deployment, codesize(), 0x00, 0x00, 0x20)) - result := mload(0x00) - } - } - - function _testTempsMint(address owner) internal returns (uint256 tokenId) { - while (true) { - tokenId = _randomChance(8) ? _random() % 32 : _random(); - (bool success,) = - _erc721.call(abi.encodeWithSignature("mint(address,uint256)", owner, tokenId)); - if (success) return tokenId; - } - } - - function _testTemps() internal returns (_TestTemps memory t) { - t.owner = _randomNonZeroAddress(); - t.tokenId = _testTempsMint(t.owner); - t.chainId = block.chainid; - t.salt = bytes32(_random()); - address account = _registry.createAccount(_proxy, t.salt, t.chainId, _erc721, t.tokenId); - t.account = MockERC6551(payable(account)); - } - - struct _TestIsValidSignatureTemps { - string uppercased; - string lowercased; - string rest; - string banned; - bytes contentsType; - } - - function _wrongContentsName(_TestIsValidSignatureTemps memory t) - internal - returns (bytes memory result) - { - bytes32 h = keccak256(_contentsName(t.contentsType)); - do { - if (_randomChance(2)) { - result = abi.encodePacked( - _randomString(t.uppercased, true), _randomString(t.rest, false) - ); - } else if (_randomChance(2)) { - result = bytes(_randomString(t.rest, true)); - } else { - result = - abi.encodePacked(_randomString(t.rest, true), _randomString(t.banned, false)); - } - } while (h == keccak256(result)); - } - - function testIsValidSignature(uint256 x) public { - vm.txGasPrice(10); - if (_randomChance(8)) { - _testIsValidSignature(abi.encodePacked(uint8(x)), false); - } - if (_randomChance(32)) { - _etchBasefeeContract(); - } - _TestIsValidSignatureTemps memory t; - t.uppercased = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - t.lowercased = "abcdefghijklmnopqrstuvwxyz"; - t.rest = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; - t.banned = "\x00 ,)"; - if (_randomChance(4)) { - t.contentsType = abi.encodePacked( - _randomString(t.uppercased, true), _randomString(t.rest, false), "(bytes32 stuff)" - ); - _testIsValidSignature(t.contentsType, true); - if (_randomChance(2)) { - _testIsValidSignature(t.contentsType, _wrongContentsName(t), false, false); - } - } - if (_randomChance(4)) { - t.contentsType = abi.encodePacked( - _randomString(t.uppercased, false), - _randomString(t.banned, true), - _randomString(t.rest, false), - "(bytes32 stuff)" - ); - _testIsValidSignature(t.contentsType, false); - } - if (_randomChance(4)) { - t.contentsType = abi.encodePacked( - _randomString(t.lowercased, true), _randomString(t.rest, false), "(bytes32 stuff)" - ); - _testIsValidSignature(t.contentsType, false); - } - if (_randomChance(4)) { - t.contentsType = - abi.encodePacked(_randomString(t.uppercased, true), _randomString(t.rest, false)); - _testIsValidSignature(t.contentsType, false); - } - if (_randomChance(16)) { - _testIsValidSignatureWontOutOfGas(); - } - } - - function _randomString(string memory byteChoices, bool nonEmpty) - internal - returns (string memory result) - { - uint256 randomness = _random(); - uint256 resultLength = _bound(_random(), nonEmpty ? 1 : 0, !_randomChance(32) ? 4 : 128); - /// @solidity memory-safe-assembly - assembly { - if mload(byteChoices) { - result := mload(0x40) - mstore(0x00, randomness) - mstore(0x40, and(add(add(result, 0x40), resultLength), not(31))) - mstore(result, resultLength) - - // forgefmt: disable-next-item - for { let i := 0 } lt(i, resultLength) { i := add(i, 1) } { - mstore(0x20, gas()) - mstore8( - add(add(result, 0x20), i), - mload(add(add(byteChoices, 1), mod(keccak256(0x00, 0x40), mload(byteChoices)))) - ) - } - } - } - } - - function testIsValidSignature() public { - vm.txGasPrice(10); - _fixChance = true; - - _testIsValidSignature("Contents(bytes32 stuff)", true); - _testIsValidSignature("ABC(bytes32 stuff)", true); - _testIsValidSignature("C(bytes32 stuff)", true); - - _testIsValidSignature("A(B b)B(bytes32 stuff)", "C", true, true); - _testIsValidSignature("A(B b)B(bytes32 stuff)", "B", true, true); - _testIsValidSignature("A(B b)B(bytes32 stuff)", "", true, false); - _testIsValidSignature("A(B b)B(bytes32 stuff)", "c", true, false); - - _testIsValidSignature("(bytes32 stuff)", false); - _testIsValidSignature("contents(bytes32 stuff)", false); - - _testIsValidSignature("ABC,(bytes32 stuff)", false); - _testIsValidSignature("ABC (bytes32 stuff)", false); - _testIsValidSignature("ABC)(bytes32 stuff)", false); - _testIsValidSignature("ABC\x00(bytes32 stuff)", false); - - _testIsValidSignature("X(", false); - _testIsValidSignature("X)", false); - _testIsValidSignature("X(bytes32 stuff)", true); - _testIsValidSignature("TheQuickBrownFoxJumpsOverTheLazyDog(bytes32 stuff)", true); - - _testIsValidSignature("bytes32", false); - _testIsValidSignature("()", false); - } - - function _testIsValidSignature( - bytes memory contentsType, - bytes memory contentsName, - bool isExplicit, - bool success - ) internal { - _TestTemps memory t = _testTemps(); - - t.contents = keccak256(abi.encode(_random(), contentsType)); - - (t.signer, t.privateKey) = _randomSigner(); - if (isExplicit) { - (t.v, t.r, t.s) = vm.sign( - t.privateKey, - _toERC1271Hash(address(t.account), t.contents, contentsType, contentsName) - ); - } else { - (t.v, t.r, t.s) = vm.sign( - t.privateKey, - _toERC1271Hash( - address(t.account), t.contents, contentsType, _contentsName(contentsType) - ) - ); - } - - vm.prank(t.owner); - MockERC721(_erc721).safeTransferFrom(t.owner, t.signer, t.tokenId); - - t.contentsDescription = abi.encodePacked(contentsType, contentsName); - - t.signature = abi.encodePacked( - t.r, - t.s, - t.v, - _DOMAIN_SEP_B, - t.contents, - t.contentsDescription, - uint16(t.contentsDescription.length) - ); - if (!_fixChance && _randomChance(4)) t.signature = _erc6492Wrap(t.signature); - - assertEq( - t.account.isValidSignature(_toContentsHash(t.contents), t.signature), - success ? bytes4(0x1626ba7e) : bytes4(0xffffffff) - ); - } - - function _testIsValidSignature(bytes memory contentsType, bool success) internal { - if (_fixChance || _randomChance(2)) { - _testIsValidSignature(contentsType, "", false, success); - } else { - _testIsValidSignature(contentsType, _contentsName(contentsType), false, success); - } - } - - function _testIsValidSignatureWontOutOfGas() internal { - _TestTemps memory t = _testTemps(); - assertEq( - t.account.isValidSignature(keccak256("hehe"), bytes(_randomString("abc", false))), - bytes4(0xffffffff) - ); - } - - function _erc6492Wrap(bytes memory signature) internal returns (bytes memory) { - return abi.encodePacked( - abi.encode(_randomNonZeroAddress(), bytes(_randomString("12345", false)), signature), - bytes32(0x6492649264926492649264926492649264926492649264926492649264926492) - ); - } - - struct _AccountDomainStruct { - string name; - string version; - uint256 chainId; - address verifyingContract; - bytes32 salt; - } - - function _accountDomainStructFields(address account) internal view returns (bytes memory) { - _AccountDomainStruct memory t; - (, t.name, t.version, t.chainId, t.verifyingContract, t.salt,) = - EIP712(account).eip712Domain(); - - return abi.encode( - keccak256(bytes(t.name)), - keccak256(bytes(t.version)), - t.chainId, - t.verifyingContract, - t.salt - ); - } - - function _contentsName(bytes memory contentsType) internal pure returns (bytes memory) { - string memory ct = string(contentsType); - return bytes(LibString.slice(ct, 0, LibString.indexOf(ct, "(", 0))); - } - - function _typedDataSignTypeHash(bytes memory contentsType, bytes memory contentsName) - internal - pure - returns (bytes32) - { - return keccak256( - abi.encodePacked( - "TypedDataSign(", - contentsName, - " contents,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)", - contentsType - ) - ); - } - - function _toERC1271Hash( - address account, - bytes32 contents, - bytes memory contentsType, - bytes memory contentsName - ) internal view returns (bytes32) { - bytes32 parentStructHash = keccak256( - abi.encodePacked( - abi.encode(_typedDataSignTypeHash(contentsType, contentsName), contents), - _accountDomainStructFields(account) - ) - ); - return keccak256(abi.encodePacked("\x19\x01", _DOMAIN_SEP_B, parentStructHash)); - } - - function _toContentsHash(bytes32 contents) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(hex"1901", _DOMAIN_SEP_B, contents)); - } - - function testSupportsERC7739() public { - _TestTemps memory t = _testTemps(); - assertEq( - t.account.isValidSignature( - 0x7739773977397739773977397739773977397739773977397739773977397739, "" - ), - bytes4(0x77390001) - ); - } -} diff --git a/grouperBot/lib/solady/test/ERC1967Factory.t.sol b/grouperBot/lib/solady/test/ERC1967Factory.t.sol deleted file mode 100644 index 687b112..0000000 --- a/grouperBot/lib/solady/test/ERC1967Factory.t.sol +++ /dev/null @@ -1,304 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MockImplementation} from "./utils/mocks/MockImplementation.sol"; -import {ERC1967Factory} from "../src/utils/ERC1967Factory.sol"; -import {ERC1967FactoryConstants} from "../src/utils/ERC1967FactoryConstants.sol"; - -contract ERC1967FactoryTest is SoladyTest { - event AdminChanged(address indexed proxy, address indexed admin); - - event Upgraded(address indexed proxy, address indexed implementation); - - event Deployed(address indexed proxy, address indexed implementation, address indexed admin); - - ERC1967Factory factory; - address implementation0; - address implementation1; - - struct _TestTemps { - uint256 key; - uint256 value; - uint256 msgValue; - bytes32 salt; - address predictedProxy; - address proxy; - } - - function _testTemps() internal returns (_TestTemps memory t) { - t.key = _random(); - t.value = _random(); - t.msgValue = _bound(_random(), 0, uint256(type(uint96).max)); - t.salt = bytes32(_random() & uint256(type(uint96).max)); - } - - function setUp() public { - factory = new ERC1967Factory(); - implementation0 = address(new MockImplementation()); - implementation1 = address(new MockImplementation()); - } - - modifier withFactories() { - _; - { - address minedFactoryAddress = 0x0000000000001122334455667788990011223344; - vm.etch(minedFactoryAddress, address(factory).code); - factory = ERC1967Factory(minedFactoryAddress); - } - _; - } - - function testDeploy() public withFactories { - (address admin,) = _randomSigner(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - _checkProxyBytecode(proxy); - - assertEq(factory.adminOf(proxy), admin); - assertTrue(proxy != address(0)); - assertTrue(proxy.code.length > 0); - _checkImplementationSlot(proxy, implementation0); - } - - function testDeployBrutalized(uint256) public withFactories { - (address admin,) = _randomSigner(); - admin = _cleaned(admin); - address implementation = implementation0; - bool brutalized; - bool success; - address f = address(factory); - /// @solidity memory-safe-assembly - assembly { - calldatacopy(0x00, 0x00, 0x40) - brutalized := eq(and(mload(0x00), 1), 0) - if brutalized { - // Extremely unlikely that all 96 upper bits will be zero. - admin := or(shl(160, keccak256(0x00, 0x20)), admin) - implementation := or(shl(160, keccak256(0x00, 0x40)), implementation) - } - let m := mload(0x40) - mstore(m, 0x545e7c61) // `deploy(address, address)`. - mstore(add(m, 0x20), implementation) - mstore(add(m, 0x40), admin) - mstore(0x00, 0) - // Basically, we want to demonstrate that Solidity has checks - // to reject dirty upper bits for addresses. - success := call(gas(), f, 0, add(m, 0x1c), 0x44, 0x00, 0x20) - // If the call is successful, there will be a deployment. - if and(success, iszero(mload(0x00))) { revert(0, 0) } - } - assertEq(brutalized, !success); - } - - function testDeployAndCall(uint256) public withFactories { - (address admin,) = _randomSigner(); - _TestTemps memory t = _testTemps(); - - bytes memory data = abi.encodeWithSignature("setValue(uint256,uint256)", t.key, t.value); - vm.deal(admin, type(uint128).max); - vm.prank(admin); - address proxy = factory.deployAndCall{value: t.msgValue}(implementation0, admin, data); - - assertEq(factory.adminOf(proxy), admin); - assertTrue(proxy != address(0)); - assertTrue(proxy.code.length > 0); - _checkImplementationSlot(proxy, implementation0); - assertEq(MockImplementation(proxy).getValue(t.key), t.value); - assertEq(proxy.balance, t.msgValue); - } - - function testDeployDeterministicAndCall(uint256) public withFactories { - (address admin,) = _randomSigner(); - _TestTemps memory t = _testTemps(); - - t.predictedProxy = factory.predictDeterministicAddress(t.salt); - bytes memory data = abi.encodeWithSignature("setValue(uint256,uint256)", t.key, t.value); - vm.deal(admin, type(uint128).max); - vm.prank(admin); - if (_randomChance(8)) { - t.salt = keccak256(abi.encode(_random())); - vm.expectRevert(ERC1967Factory.SaltDoesNotStartWithCaller.selector); - t.proxy = factory.deployDeterministicAndCall{value: t.msgValue}( - implementation0, admin, t.salt, data - ); - return; - } else { - vm.expectEmit(true, true, true, true); - emit Deployed(t.predictedProxy, implementation0, _cleaned(admin)); - t.proxy = factory.deployDeterministicAndCall{value: t.msgValue}( - implementation0, admin, t.salt, data - ); - assertEq(t.proxy, t.predictedProxy); - } - - assertEq(factory.adminOf(t.proxy), admin); - assertTrue(t.proxy != address(0)); - assertTrue(t.proxy.code.length > 0); - _checkImplementationSlot(t.proxy, implementation0); - assertEq(MockImplementation(t.proxy).getValue(t.key), t.value); - assertEq(t.proxy.balance, t.msgValue); - } - - function testDeployAndCallWithRevert() public withFactories { - (address admin,) = _randomSigner(); - - bytes memory data = abi.encodeWithSignature("fails()"); - vm.expectRevert(MockImplementation.Fail.selector); - factory.deployAndCall(implementation0, admin, data); - } - - function testProxySucceeds() public withFactories { - (address admin,) = _randomSigner(); - uint256 a = 1; - - MockImplementation proxy = MockImplementation(factory.deploy(implementation0, admin)); - - assertEq(proxy.succeeds(a), a); - } - - function testProxyFails() public withFactories { - (address admin,) = _randomSigner(); - - address proxy = factory.deploy(implementation0, admin); - - vm.expectRevert(MockImplementation.Fail.selector); - MockImplementation(proxy).fails(); - } - - function testChangeAdmin() public withFactories { - (address admin, address newAdmin) = _randomAccounts(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - - vm.expectEmit(true, true, true, true, address(factory)); - emit AdminChanged(proxy, _cleaned(newAdmin)); - - vm.prank(admin); - factory.changeAdmin(proxy, newAdmin); - - assertEq(factory.adminOf(proxy), newAdmin); - } - - function testChangeAdminUnauthorized() public withFactories { - (address admin, address sussyAccount) = _randomAccounts(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - - vm.expectRevert(ERC1967Factory.Unauthorized.selector); - - vm.prank(sussyAccount); - factory.changeAdmin(proxy, sussyAccount); - } - - function testUpgrade() public withFactories { - (address admin,) = _randomSigner(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - - vm.expectEmit(true, true, true, true, address(factory)); - emit Upgraded(proxy, implementation1); - - vm.prank(admin); - factory.upgrade(proxy, implementation1); - - _checkImplementationSlot(proxy, implementation1); - } - - function testUpgradeAndCall() public withFactories { - (address admin,) = _randomSigner(); - _TestTemps memory t = _testTemps(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - - vm.expectEmit(true, true, true, true, address(factory)); - emit Upgraded(proxy, implementation1); - - vm.prank(admin); - vm.deal(admin, type(uint128).max); - bytes memory data = abi.encodeWithSignature("setValue(uint256,uint256)", t.key, t.value); - factory.upgradeAndCall{value: t.msgValue}(proxy, implementation1, data); - - _checkImplementationSlot(proxy, implementation1); - uint256 gasBefore = gasleft(); - uint256 storedValue = MockImplementation(proxy).getValue(t.key); - unchecked { - uint256 gasUsed = gasBefore - gasleft(); - emit LogUint("gasUsed", gasUsed); - } - assertEq(storedValue, t.value); - assertEq(proxy.balance, t.msgValue); - } - - function testUpgradeAndCallWithRevert() public withFactories { - (address admin,) = _randomSigner(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - - vm.prank(admin); - vm.expectRevert(MockImplementation.Fail.selector); - factory.upgradeAndCall(proxy, implementation1, abi.encodeWithSignature("fails()")); - } - - function testUpgradeUnauthorized() public withFactories { - (address admin, address sussyAccount) = _randomAccounts(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - - vm.expectRevert(ERC1967Factory.Unauthorized.selector); - vm.prank(sussyAccount); - factory.upgrade(proxy, implementation1); - - vm.expectRevert(ERC1967Factory.Unauthorized.selector); - vm.prank(address(uint160(admin) ^ 1)); - factory.upgrade(proxy, implementation1); - - vm.prank(admin); - factory.upgrade(proxy, implementation1); - } - - function testUpgradeWithCorruptedProxy() public withFactories { - (address admin,) = _randomSigner(); - - vm.prank(admin); - address proxy = factory.deploy(implementation0, admin); - - vm.expectRevert(ERC1967Factory.Unauthorized.selector); - vm.prank(admin); - factory.upgrade(address(uint160(proxy) ^ 1), implementation1); - - _checkImplementationSlot(proxy, implementation0); - } - - function testFactoryDeployment() public { - address deployment = - _safeCreate2(ERC1967FactoryConstants.SALT, ERC1967FactoryConstants.INITCODE); - assertEq(deployment, ERC1967FactoryConstants.ADDRESS); - assertEq(deployment.code, ERC1967FactoryConstants.BYTECODE); - } - - function _randomAccounts() internal returns (address a, address b) { - (a,) = _randomSigner(); - do { - (b,) = _randomSigner(); - } while (a == b); - } - - function _checkImplementationSlot(address proxy, address implementation) internal { - bytes32 slot = bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1); - assertEq(vm.load(proxy, slot), bytes32(uint256(uint160(implementation)))); - } - - function _checkProxyBytecode(address proxy) internal { - bytes memory code = address(proxy).code; - assertEq(uint8(bytes1(code[code.length - 1])), 0xfd); - assertTrue(code.length == 127 || code.length == 121); - } -} diff --git a/grouperBot/lib/solady/test/ERC20.t.sol b/grouperBot/lib/solady/test/ERC20.t.sol deleted file mode 100644 index aff0ff9..0000000 --- a/grouperBot/lib/solady/test/ERC20.t.sol +++ /dev/null @@ -1,571 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import "./utils/InvariantTest.sol"; - -import {ERC20, MockERC20} from "./utils/mocks/MockERC20.sol"; -import {MockERC20ForPermit2} from "./utils/mocks/MockERC20ForPermit2.sol"; - -contract ERC20ForPermit2Test is SoladyTest { - MockERC20ForPermit2 token; - - address internal constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; - - function setUp() public { - token = new MockERC20ForPermit2("Token", "TKN", 18); - } - - function testApproveToPermit2(address owner, uint256 amount) public { - vm.prank(owner); - if (amount != type(uint256).max) { - vm.expectRevert(ERC20.Permit2AllowanceIsFixedAtInfinity.selector); - } - token.approve(_PERMIT2, amount); - } - - function testPermitToPermit2(address owner, uint256 amount) public { - vm.prank(owner); - if (amount != type(uint256).max) { - vm.expectRevert(ERC20.Permit2AllowanceIsFixedAtInfinity.selector); - } else { - vm.expectRevert(ERC20.InvalidPermit.selector); - } - token.permit(owner, _PERMIT2, amount, block.timestamp, 0, bytes32(0), bytes32(0)); - } - - function testTransferFrom(address owner, uint256 amount) public { - assertEq(token.allowance(owner, _PERMIT2), type(uint256).max); - token.mint(owner, amount); - uint256 amountToTransfer = _bound(_random(), 0, amount); - address notPermit2 = _randomHashedAddress(); - address recipient = _randomHashedAddress(); - vm.prank(notPermit2); - if (amountToTransfer != 0) { - vm.expectRevert(ERC20.InsufficientAllowance.selector); - } - token.transferFrom(owner, recipient, amountToTransfer); - - vm.prank(_PERMIT2); - token.transferFrom(owner, recipient, amountToTransfer); - if (recipient != owner) { - assertEq(token.balanceOf(recipient), amountToTransfer); - assertEq(token.balanceOf(owner), amount - amountToTransfer); - } else { - assertEq(token.balanceOf(owner), amount); - } - assertEq(token.allowance(owner, _PERMIT2), type(uint256).max); - } - - function check_IsNotUint256MaxTrickEquivalence(uint256 x) public pure { - bool expected; - bool optimized; - /// @solidity memory-safe-assembly - assembly { - if add(x, 1) { expected := 1 } - if not(x) { optimized := 1 } - } - assert(optimized == expected); - expected = x != type(uint256).max; - assert(optimized == expected); - } - - function check_IsPermit2AndValueIsNotInfinityTrickEquivalence(address spender, uint256 amount) - public - pure - { - bool expected = spender == _PERMIT2 && amount != type(uint256).max; - bool optimized; - /// @solidity memory-safe-assembly - assembly { - if iszero(or(xor(shr(96, shl(96, spender)), _PERMIT2), iszero(not(amount)))) { - optimized := 1 - } - } - assert(optimized == expected); - } -} - -contract ERC20Test is SoladyTest { - MockERC20 token; - - address internal constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; - - bytes32 constant PERMIT_TYPEHASH = keccak256( - "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" - ); - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - struct _TestTemps { - address owner; - address to; - uint256 amount; - uint256 deadline; - uint8 v; - bytes32 r; - bytes32 s; - uint256 privateKey; - uint256 nonce; - } - - function _testTemps() internal returns (_TestTemps memory t) { - (t.owner, t.privateKey) = _randomSigner(); - t.to = _randomNonZeroAddress(); - t.amount = _random(); - t.deadline = _random(); - } - - function setUp() public { - token = new MockERC20("Token", "TKN", 18); - } - - function testMetadata() public { - assertEq(token.name(), "Token"); - assertEq(token.symbol(), "TKN"); - assertEq(token.decimals(), 18); - } - - function testMint() public { - vm.expectEmit(true, true, true, true); - emit Transfer(address(0), address(0xBEEF), 1e18); - token.mint(address(0xBEEF), 1e18); - - assertEq(token.totalSupply(), 1e18); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testBurn() public { - token.mint(address(0xBEEF), 1e18); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(0xBEEF), address(0), 0.9e18); - token.burn(address(0xBEEF), 0.9e18); - - assertEq(token.totalSupply(), 1e18 - 0.9e18); - assertEq(token.balanceOf(address(0xBEEF)), 0.1e18); - } - - function testApprove() public { - vm.expectEmit(true, true, true, true); - emit Approval(address(this), address(0xBEEF), 1e18); - assertTrue(token.approve(address(0xBEEF), 1e18)); - - assertEq(token.allowance(address(this), address(0xBEEF)), 1e18); - } - - function testTransfer() public { - token.mint(address(this), 1e18); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), address(0xBEEF), 1e18); - assertTrue(token.transfer(address(0xBEEF), 1e18)); - assertEq(token.totalSupply(), 1e18); - - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testTransferFrom() public { - address from = address(0xABCD); - - token.mint(from, 1e18); - - vm.prank(from); - token.approve(address(this), 1e18); - - vm.expectEmit(true, true, true, true); - emit Transfer(from, address(0xBEEF), 1e18); - assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); - assertEq(token.totalSupply(), 1e18); - - assertEq(token.allowance(from, address(this)), 0); - - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testInfiniteApproveTransferFrom() public { - address from = address(0xABCD); - - token.mint(from, 1e18); - - vm.prank(from); - token.approve(address(this), type(uint256).max); - - assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); - assertEq(token.totalSupply(), 1e18); - - assertEq(token.allowance(from, address(this)), type(uint256).max); - - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testPermit() public { - _TestTemps memory t = _testTemps(); - t.deadline = block.timestamp; - - _signPermit(t); - - _expectPermitEmitApproval(t); - _permit(t); - - _checkAllowanceAndNonce(t); - } - - function testMintOverMaxUintReverts() public { - token.mint(address(this), type(uint256).max); - vm.expectRevert(ERC20.TotalSupplyOverflow.selector); - token.mint(address(this), 1); - } - - function testTransferInsufficientBalanceReverts() public { - token.mint(address(this), 0.9e18); - vm.expectRevert(ERC20.InsufficientBalance.selector); - token.transfer(address(0xBEEF), 1e18); - } - - function testTransferFromInsufficientAllowanceReverts() public { - address from = address(0xABCD); - - token.mint(from, 1e18); - - vm.prank(from); - token.approve(address(this), 0.9e18); - - vm.expectRevert(ERC20.InsufficientAllowance.selector); - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testTransferFromInsufficientBalanceReverts() public { - address from = address(0xABCD); - - token.mint(from, 0.9e18); - - vm.prank(from); - token.approve(address(this), 1e18); - - vm.expectRevert(ERC20.InsufficientBalance.selector); - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testMint(address to, uint256 amount) public { - vm.expectEmit(true, true, true, true); - emit Transfer(address(0), to, amount); - token.mint(to, amount); - - assertEq(token.totalSupply(), amount); - assertEq(token.balanceOf(to), amount); - } - - function testBurn(address from, uint256 mintAmount, uint256 burnAmount) public { - burnAmount = _bound(burnAmount, 0, mintAmount); - - token.mint(from, mintAmount); - vm.expectEmit(true, true, true, true); - emit Transfer(from, address(0), burnAmount); - token.burn(from, burnAmount); - - assertEq(token.totalSupply(), mintAmount - burnAmount); - assertEq(token.balanceOf(from), mintAmount - burnAmount); - } - - function testApprove(address to, uint256 amount) public { - if (to == _PERMIT2) { - amount = type(uint256).max; - } - assertTrue(token.approve(to, amount)); - assertEq(token.allowance(address(this), to), amount); - } - - function testTransfer(address to, uint256 amount) public { - token.mint(address(this), amount); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), to, amount); - assertTrue(token.transfer(to, amount)); - assertEq(token.totalSupply(), amount); - - if (address(this) == to) { - assertEq(token.balanceOf(address(this)), amount); - } else { - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.balanceOf(to), amount); - } - } - - function testTransferFrom( - address spender, - address from, - address to, - uint256 approval, - uint256 amount - ) public { - vm.assume(spender != _PERMIT2); - amount = _bound(amount, 0, approval); - - token.mint(from, amount); - assertEq(token.balanceOf(from), amount); - - vm.prank(from); - token.approve(spender, approval); - - vm.expectEmit(true, true, true, true); - emit Transfer(from, to, amount); - vm.prank(spender); - assertTrue(token.transferFrom(from, to, amount)); - assertEq(token.totalSupply(), amount); - - if (approval == type(uint256).max) { - assertEq(token.allowance(from, spender), approval); - } else { - assertEq(token.allowance(from, spender), approval - amount); - } - - if (from == to) { - assertEq(token.balanceOf(from), amount); - } else { - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(to), amount); - } - } - - function testDirectTransfer(uint256) public { - _TestTemps memory t = _testTemps(); - while (t.owner == t.to) (t.to,) = _randomSigner(); - - uint256 totalSupply = _random(); - token.mint(t.owner, totalSupply); - assertEq(token.balanceOf(t.owner), totalSupply); - assertEq(token.balanceOf(t.to), 0); - if (t.amount > totalSupply) { - vm.expectRevert(ERC20.InsufficientBalance.selector); - token.directTransfer(t.owner, t.to, t.amount); - } else { - vm.expectEmit(true, true, true, true); - emit Transfer(t.owner, t.to, t.amount); - token.directTransfer(t.owner, t.to, t.amount); - assertEq(token.balanceOf(t.owner), totalSupply - t.amount); - assertEq(token.balanceOf(t.to), t.amount); - } - } - - function testDirectSpendAllowance(uint256) public { - _TestTemps memory t = _testTemps(); - uint256 allowance = _random(); - vm.prank(t.owner); - token.approve(t.to, allowance); - assertEq(token.allowance(t.owner, t.to), allowance); - if (allowance == type(uint256).max) { - token.directSpendAllowance(t.owner, t.to, t.amount); - assertEq(token.allowance(t.owner, t.to), allowance); - } else if (t.amount > allowance) { - vm.expectRevert(ERC20.InsufficientAllowance.selector); - token.directSpendAllowance(t.owner, t.to, t.amount); - } else { - token.directSpendAllowance(t.owner, t.to, t.amount); - assertEq(token.allowance(t.owner, t.to), allowance - t.amount); - } - } - - function testPermit(uint256) public { - _TestTemps memory t = _testTemps(); - if (t.deadline < block.timestamp) t.deadline = block.timestamp; - - _signPermit(t); - - _expectPermitEmitApproval(t); - _permit(t); - - _checkAllowanceAndNonce(t); - } - - function _checkAllowanceAndNonce(_TestTemps memory t) internal { - assertEq(token.allowance(t.owner, t.to), t.amount); - assertEq(token.nonces(t.owner), t.nonce + 1); - } - - function testBurnInsufficientBalanceReverts(address to, uint256 mintAmount, uint256 burnAmount) - public - { - if (mintAmount == type(uint256).max) mintAmount--; - burnAmount = _bound(burnAmount, mintAmount + 1, type(uint256).max); - - token.mint(to, mintAmount); - vm.expectRevert(ERC20.InsufficientBalance.selector); - token.burn(to, burnAmount); - } - - function testTransferInsufficientBalanceReverts( - address to, - uint256 mintAmount, - uint256 sendAmount - ) public { - if (mintAmount == type(uint256).max) mintAmount--; - sendAmount = _bound(sendAmount, mintAmount + 1, type(uint256).max); - - token.mint(address(this), mintAmount); - vm.expectRevert(ERC20.InsufficientBalance.selector); - token.transfer(to, sendAmount); - } - - function testTransferFromInsufficientAllowanceReverts( - address to, - uint256 approval, - uint256 amount - ) public { - if (approval == type(uint256).max) approval--; - amount = _bound(amount, approval + 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, amount); - - vm.prank(from); - token.approve(address(this), approval); - - vm.expectRevert(ERC20.InsufficientAllowance.selector); - token.transferFrom(from, to, amount); - } - - function testTransferFromInsufficientBalanceReverts( - address to, - uint256 mintAmount, - uint256 sendAmount - ) public { - if (mintAmount == type(uint256).max) mintAmount--; - sendAmount = _bound(sendAmount, mintAmount + 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, mintAmount); - - vm.prank(from); - token.approve(address(this), sendAmount); - - vm.expectRevert(ERC20.InsufficientBalance.selector); - token.transferFrom(from, to, sendAmount); - } - - function testPermitBadNonceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - if (t.deadline < block.timestamp) t.deadline = block.timestamp; - while (t.nonce == 0) t.nonce = _random(); - - _signPermit(t); - - vm.expectRevert(ERC20.InvalidPermit.selector); - _permit(t); - } - - function testPermitBadDeadlineReverts(uint256) public { - _TestTemps memory t = _testTemps(); - if (t.deadline == type(uint256).max) t.deadline--; - if (t.deadline < block.timestamp) t.deadline = block.timestamp; - - _signPermit(t); - - vm.expectRevert(ERC20.InvalidPermit.selector); - t.deadline += 1; - _permit(t); - } - - function testPermitPastDeadlineReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.deadline = _bound(t.deadline, 0, block.timestamp - 1); - - _signPermit(t); - - vm.expectRevert(ERC20.PermitExpired.selector); - _permit(t); - } - - function testPermitReplayReverts(uint256) public { - _TestTemps memory t = _testTemps(); - if (t.deadline < block.timestamp) t.deadline = block.timestamp; - - _signPermit(t); - - _expectPermitEmitApproval(t); - _permit(t); - vm.expectRevert(ERC20.InvalidPermit.selector); - _permit(t); - } - - function _signPermit(_TestTemps memory t) internal view { - bytes32 innerHash = - keccak256(abi.encode(PERMIT_TYPEHASH, t.owner, t.to, t.amount, t.nonce, t.deadline)); - bytes32 domainSeparator = token.DOMAIN_SEPARATOR(); - bytes32 outerHash = keccak256(abi.encodePacked("\x19\x01", domainSeparator, innerHash)); - (t.v, t.r, t.s) = vm.sign(t.privateKey, outerHash); - } - - function _expectPermitEmitApproval(_TestTemps memory t) internal { - vm.expectEmit(true, true, true, true); - emit Approval(t.owner, t.to, t.amount); - } - - function _permit(_TestTemps memory t) internal { - address token_ = address(token); - /// @solidity memory-safe-assembly - assembly { - let m := mload(sub(t, 0x20)) - mstore(sub(t, 0x20), 0xd505accf) - let success := call(gas(), token_, 0, sub(t, 0x04), 0xe4, 0x00, 0x00) - if iszero(success) { - returndatacopy(0, 0, returndatasize()) - revert(0, returndatasize()) - } - mstore(sub(t, 0x20), m) - } - } -} - -contract ERC20Invariants is SoladyTest, InvariantTest { - BalanceSum balanceSum; - MockERC20 token; - - function setUp() public { - token = new MockERC20("Token", "TKN", 18); - balanceSum = new BalanceSum(token); - _addTargetContract(address(balanceSum)); - } - - function invariantBalanceSum() public { - assertEq(token.totalSupply(), balanceSum.sum()); - } -} - -contract BalanceSum { - MockERC20 token; - uint256 public sum; - - constructor(MockERC20 _token) { - token = _token; - } - - function mint(address from, uint256 amount) public { - token.mint(from, amount); - sum += amount; - } - - function burn(address from, uint256 amount) public { - token.burn(from, amount); - sum -= amount; - } - - function approve(address to, uint256 amount) public { - token.approve(to, amount); - } - - function transferFrom(address from, address to, uint256 amount) public { - token.transferFrom(from, to, amount); - } - - function transfer(address to, uint256 amount) public { - token.transfer(to, amount); - } -} diff --git a/grouperBot/lib/solady/test/ERC20Votes.t.sol b/grouperBot/lib/solady/test/ERC20Votes.t.sol deleted file mode 100644 index 19fa772..0000000 --- a/grouperBot/lib/solady/test/ERC20Votes.t.sol +++ /dev/null @@ -1,591 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {ERC20, ERC20Votes, MockERC20Votes} from "./utils/mocks/MockERC20Votes.sol"; -import {FixedPointMathLib} from "../src/utils/FixedPointMathLib.sol"; - -contract ERC20VotesTest is SoladyTest { - MockERC20Votes erc20Votes; - - event DelegateChanged(address indexed delegator, address indexed from, address indexed to); - event DelegateVotesChanged(address indexed delegate, uint256 oldValue, uint256 newValue); - - address internal constant _ALICE = address(111); - address internal constant _BOB = address(222); - address internal constant _CHARLIE = address(333); - address internal constant _DAVID = address(444); - - function setUp() public { - erc20Votes = new MockERC20Votes(); - } - - function testSetAndGetDelegate(address delegator, address delegatee) public { - erc20Votes.directDelegate(delegator, delegatee); - assertEq(erc20Votes.delegates(delegator), delegatee); - } - - function testMintTransferBurnDelegate() public { - uint256 initialBlockNumber = vm.getBlockNumber(); - erc20Votes.mint(_ALICE, 1 ether); - - // Minting does not automatically give one votes. - assertEq(erc20Votes.getVotes(_ALICE), 0); - assertEq(erc20Votes.getVotes(_BOB), 0); - assertEq(erc20Votes.getVotesTotalSupply(), 1 ether); - - vm.expectEmit(true, true, true, true); - emit DelegateChanged(_ALICE, address(0), _BOB); - vm.prank(_ALICE); - erc20Votes.delegate(_BOB); - - assertEq(erc20Votes.getVotes(_BOB), 1 ether); - assertEq(erc20Votes.getVotes(_DAVID), 0 ether); - - vm.expectEmit(true, true, true, true); - emit DelegateChanged(_CHARLIE, address(0), _DAVID); - vm.prank(_CHARLIE); - erc20Votes.delegate(_DAVID); - - vm.prank(_ALICE); - erc20Votes.transfer(_CHARLIE, 0.3 ether); - - assertEq(erc20Votes.getVotes(_BOB), 0.7 ether); - assertEq(erc20Votes.getVotes(_DAVID), 0.3 ether); - - vm.roll(initialBlockNumber + 1); - - erc20Votes.burn(_ALICE, 0.1 ether); - assertEq(erc20Votes.getVotes(_BOB), 0.6 ether); - assertEq(erc20Votes.getVotes(_DAVID), 0.3 ether); - - vm.roll(initialBlockNumber + 2); - - vm.expectEmit(true, true, true, true); - emit DelegateChanged(_CHARLIE, _DAVID, _BOB); - vm.expectEmit(true, true, true, true); - emit DelegateVotesChanged(_DAVID, 0.3 ether, 0 ether); - vm.expectEmit(true, true, true, true); - emit DelegateVotesChanged(_BOB, 0.6 ether, 0.9 ether); - vm.prank(_CHARLIE); - erc20Votes.delegate(_BOB); - - vm.roll(initialBlockNumber + 3); - - assertEq(erc20Votes.getVotes(_BOB), 0.9 ether); - assertEq(erc20Votes.getPastVotes(_BOB, initialBlockNumber + 0), 0.7 ether); - assertEq(erc20Votes.getPastVotes(_BOB, initialBlockNumber + 1), 0.6 ether); - _checkCheckpointAt(_BOB, 0, initialBlockNumber + 0, 0.7 ether); - _checkCheckpointAt(_BOB, 1, initialBlockNumber + 1, 0.6 ether); - assertEq(erc20Votes.getVotes(_DAVID), 0 ether); - assertEq(erc20Votes.getPastVotes(_DAVID, initialBlockNumber + 0), 0.3 ether); - assertEq(erc20Votes.getPastVotes(_DAVID, initialBlockNumber + 1), 0.3 ether); - _checkCheckpointAt(_DAVID, 0, initialBlockNumber + 0, 0.3 ether); - _checkCheckpointAt(_DAVID, 1, initialBlockNumber + 2, 0 ether); - - assertEq(erc20Votes.getVotesTotalSupply(), 0.9 ether); - assertEq(erc20Votes.getPastVotesTotalSupply(initialBlockNumber + 0), 1 ether); - assertEq(erc20Votes.getPastVotesTotalSupply(initialBlockNumber + 1), 0.9 ether); - - uint256 currentBlockNumber = vm.getBlockNumber(); - vm.expectRevert(ERC20Votes.ERC5805FutureLookup.selector); - erc20Votes.getPastVotesTotalSupply(currentBlockNumber); - } - - function _checkCheckpointAt( - address account, - uint256 i, - uint256 expectedClock, - uint256 expectedValue - ) internal { - (uint48 checkpointClock, uint256 checkpointValue) = erc20Votes.checkpointAt(account, i); - assertEq(checkpointClock, expectedClock); - assertEq(checkpointValue, expectedValue); - } - - function _advanceBlockNumber() internal { - vm.roll(vm.getBlockNumber() + (_randomUniform() & 3)); - } - - struct _TestVoteInvariantsTemps { - address[] accounts; - address[] delegates; - } - - function testVoteInvariants(bytes32) public { - vm.pauseGasMetering(); - unchecked { - _TestVoteInvariantsTemps memory t; - t.accounts = new address[](1 + (_randomUniform() & 3)); - t.delegates = new address[](t.accounts.length + 1); - for (uint256 i; i != t.accounts.length; ++i) { - address account = _randomUniqueHashedAddress(); - t.accounts[i] = account; - t.delegates[i + 1] = account; - if (!_randomChance(4)) { - erc20Votes.mint(account, _bound(_random(), 0, 2 ** 161 - 1)); - } - } - do { - if (_randomChance(2)) { - address delegator = t.accounts[_randomUniform() % t.accounts.length]; - address delegate = t.delegates[_randomUniform() % t.delegates.length]; - vm.prank(delegator); - erc20Votes.delegate(delegate); - if (erc20Votes.balanceOf(delegator) != 0 && delegate != address(0)) { - assertGt(erc20Votes.getVotes(delegate), 0); - } - } - if (_randomChance(4)) _advanceBlockNumber(); - if (_randomChance(2)) { - address from = t.accounts[_randomUniform() % t.accounts.length]; - address to = t.accounts[_randomUniform() % t.accounts.length]; - uint256 amount = _bound(_random(), 0, erc20Votes.balanceOf(from)); - vm.prank(from); - erc20Votes.transfer(to, amount); - } - if (_randomChance(4)) _advanceBlockNumber(); - if (_randomChance(4)) { - address account = t.accounts[_randomUniform() % t.accounts.length]; - uint256 amount = _bound(_random(), 0, erc20Votes.balanceOf(account)); - erc20Votes.burn(account, amount); - } - if (_randomChance(4)) _advanceBlockNumber(); - if (_randomChance(4)) { - address account = t.accounts[_randomUniform() % t.accounts.length]; - uint256 amount = _bound(_random(), 0, 2 ** 161 - 1); - erc20Votes.mint(account, amount); - } - if (_randomChance(4)) _advanceBlockNumber(); - if (_randomChance(8)) _checkVoteInvariants(t); - } while (!_randomChance(4)); - _checkVoteInvariants(t); - } - vm.resumeGasMetering(); - } - - function _checkVoteInvariants(_TestVoteInvariantsTemps memory t) internal { - unchecked { - uint256 totalVotes = 0; - for (uint256 j; j != t.delegates.length; ++j) { - totalVotes += erc20Votes.getVotes(t.delegates[j]); - } - for (uint256 j; j != t.delegates.length; ++j) { - uint256 totalBalanceForDelegate = 0; - for (uint256 i; i != t.accounts.length; ++i) { - if (erc20Votes.delegates(t.accounts[i]) == t.delegates[j]) { - totalBalanceForDelegate += erc20Votes.balanceOf(t.accounts[i]); - } - } - assertLe(erc20Votes.getVotes(t.delegates[j]), totalBalanceForDelegate); - } - assertLe(totalVotes, erc20Votes.getVotesTotalSupply()); - assertEq(erc20Votes.getVotesTotalSupply(), erc20Votes.totalSupply()); - } - unchecked { - for (uint256 j; j != t.delegates.length; ++j) { - uint256 checkpointCount = erc20Votes.checkpointCount(t.delegates[j]); - if (_randomChance(2) && checkpointCount != 0) { - uint256 i = _bound(_random(), 0, checkpointCount - 1); - erc20Votes.checkpointAt(t.delegates[j], i); - } else if (checkpointCount != 0) { - uint256 i = _bound(_random(), checkpointCount, checkpointCount + 10); - vm.expectRevert(ERC20Votes.ERC5805CheckpointIndexOutOfBounds.selector); - erc20Votes.checkpointAt(t.delegates[j], i); - } - } - } - } - - function testClockTrick(uint48 x) public pure { - /// @solidity memory-safe-assembly - assembly { - returndatacopy(returndatasize(), returndatasize(), sub(0, shr(48, x))) - } - } - - struct _TestDelegateBySigTemps { - address signer; - uint256 privateKey; - uint256 nonce; - uint256 expiry; - address delegatee; - uint8 v; - bytes32 r; - bytes32 s; - } - - bytes32 internal constant _ERC5805_DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - function _signDelegate(_TestDelegateBySigTemps memory t) internal view { - bytes32 innerHash = - keccak256(abi.encode(_ERC5805_DELEGATION_TYPEHASH, t.delegatee, t.nonce, t.expiry)); - bytes32 domainSeparator = keccak256( - abi.encode( - keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" - ), - keccak256(bytes(erc20Votes.name())), - keccak256("1"), - block.chainid, - address(erc20Votes) - ) - ); - bytes32 outerHash = keccak256(abi.encodePacked("\x19\x01", domainSeparator, innerHash)); - (t.v, t.r, t.s) = vm.sign(t.privateKey, outerHash); - } - - function _delegateBySig(_TestDelegateBySigTemps memory t) internal { - bytes memory data = abi.encodeWithSignature( - "delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32)", - t.delegatee, - t.nonce, - t.expiry, - t.v, - t.r, - t.s - ); - (bool success,) = address(erc20Votes).call(data); - assert(success); - } - - function testDelegateBySig(bytes32) public { - _TestDelegateBySigTemps memory t; - t.delegatee = _randomHashedAddress(); - (t.signer, t.privateKey) = _randomSigner(); - t.nonce = _randomUniform() & 7; - t.expiry = _bound(_randomUniform(), 10, 2 ** 32 - 1); - if (!_randomChance(32)) { - unchecked { - for (uint256 i; i != t.nonce; ++i) { - erc20Votes.directIncrementNonce(t.signer); - } - assertEq(t.nonce, erc20Votes.nonces(t.signer)); - } - } - _signDelegate(t); - uint256 timestamp = _bound(_randomUniform(), 10, 2 ** 32 - 1); - vm.warp(timestamp); - if (timestamp > t.expiry) { - vm.expectRevert(ERC20Votes.ERC5805DelegateSignatureExpired.selector); - _delegateBySig(t); - } else if (t.nonce != erc20Votes.nonces(t.signer)) { - vm.expectRevert(ERC20Votes.ERC5805DelegateInvalidSignature.selector); - _delegateBySig(t); - } else { - _delegateBySig(t); - assertEq(t.nonce + 1, erc20Votes.nonces(t.signer)); - assertEq(erc20Votes.delegates(t.signer), t.delegatee); - } - } - - struct Checkpoint { - uint256 key; - uint256 value; - } - - Checkpoint[] internal _trace; - - function testSmallSqrtApprox(uint32 n) public { - uint256 approx = _smallSqrtApprox(n); - uint256 groundTruth = FixedPointMathLib.sqrt(n); - assertGe(approx, groundTruth); - assertLe(FixedPointMathLib.dist(approx, groundTruth), 3); - } - - function _smallSqrtApprox(uint256 n) internal pure returns (uint256 m) { - /// @solidity memory-safe-assembly - assembly { - m := shl(4, lt(0xffff, n)) - m := shl(shr(1, or(shl(3, lt(0xff, shr(m, n))), m)), 16) - m := shr(1, add(m, div(n, m))) - m := shr(1, add(m, div(n, m))) - m := shr(1, add(m, div(n, m))) - m := shr(1, add(m, div(n, m))) - m := shr(1, add(m, div(n, m))) - m := shr(1, add(m, div(n, m))) - } - } - - struct _TestCheckpointTemps { - uint256 key; - uint256 amount; - bool isAdd; - uint256 oldValueOriginal; - uint256 oldValue; - uint256 newValueOriginal; - uint256 newValue; - } - - function testCheckpointPush(uint256 lengthSlot) public { - lengthSlot = uint256(keccak256(abi.encode(lengthSlot, "hehe"))); - uint256 key = _randomUniform() & 0xf; - if (_randomChance(2)) { - this.checkpointPushDiff(lengthSlot, key, type(uint256).max - 10, true); - key += _randomUniform() & 0xf; - uint256 amount = _randomUniform() % 20; - if (amount <= 10) { - this.checkpointPushDiff(lengthSlot, key, amount, true); - assertEq(_checkpointLatest(lengthSlot), type(uint256).max - 10 + amount); - } else { - vm.expectRevert(ERC20Votes.ERC5805CheckpointValueOverflow.selector); - this.checkpointPushDiff(lengthSlot, key, amount, true); - } - } else { - this.checkpointPushDiff(lengthSlot, key, 10, true); - key += _randomUniform() & 0xf; - uint256 amount = _randomUniform() % 20; - if (amount <= 10) { - this.checkpointPushDiff(lengthSlot, key, amount, false); - assertEq(_checkpointLatest(lengthSlot), 10 - amount); - } else { - vm.expectRevert(ERC20Votes.ERC5805CheckpointValueUnderflow.selector); - this.checkpointPushDiff(lengthSlot, key, amount, false); - } - } - } - - function testCheckpointDifferential(uint256 lengthSlot, uint256 n) public { - vm.pauseGasMetering(); - lengthSlot = uint256(keccak256(abi.encode(lengthSlot, "hehe"))); - - n = _bound(n, 1, _randomChance(32) ? 70 : 8); - _TestCheckpointTemps memory t; - do { - t.key += _randomUniform() & 0xf; - t.isAdd = _randomChance(2); - if (t.isAdd) { - t.amount = _bound(_random(), 0, type(uint256).max - _checkpointLatestOriginal()); - } else { - t.amount = _bound(_random(), 0, _checkpointLatestOriginal()); - } - - (t.oldValueOriginal, t.newValueOriginal) = - _checkpointPushDiffOriginal(t.key, t.amount, t.isAdd); - - (t.oldValue, t.newValue) = _checkpointPushDiff(lengthSlot, t.key, t.amount, t.isAdd); - - assertEq(t.oldValue, t.oldValueOriginal); - assertEq(t.newValue, t.newValueOriginal); - assertEq(t.key, _checkpointLatestKeyOriginal()); - assertEq(t.key, _checkpointLatestKey(lengthSlot)); - assertEq(_checkpointLatestOriginal(), _checkpointLatest(lengthSlot)); - - if (_randomChance(8)) _checkCheckpoints(lengthSlot); - if (_randomChance(8)) _checkCheckpointUpperLookupRecent(lengthSlot); - } while (!_randomChance(n)); - - _checkCheckpoints(lengthSlot); - _checkCheckpointUpperLookupRecent(lengthSlot); - vm.resumeGasMetering(); - } - - function _checkCheckpoints(uint256 lengthSlot) internal tempMemory { - unchecked { - uint256 n = _trace.length; - for (uint256 i; i != n; ++i) { - (uint256 key, uint256 value) = _checkpointAt(lengthSlot, i); - Checkpoint storage c = _trace[i]; - assertEq(key, c.key); - assertEq(value, c.value); - } - } - } - - function _checkCheckpointUpperLookupRecent(uint256 lengthSlot) internal tempMemory { - uint256 key = _bound(_randomUniform(), 0, _checkpointLatestKeyOriginal() + 3); - uint256 expected = _checkpointUpperLookupRecentOriginal(key); - assertEq(_checkpointUpperLookupRecent(lengthSlot, key), expected); - } - - function _checkpointUpperLookupRecentOriginal(uint256 key) - private - view - tempMemory - returns (uint256 result) - { - unchecked { - uint256 n = _trace.length; - for (uint256 i; i != n; ++i) { - Checkpoint storage c = _trace[i]; - if (c.key > key) break; - result = c.value; - } - } - } - - function _checkpointPushDiffOriginal(uint256 key, uint256 amount, bool isAdd) - private - tempMemory - returns (uint256 oldValue, uint256 newValue) - { - if (_trace.length == 0) { - newValue = isAdd ? oldValue + amount : oldValue - amount; - _trace.push(Checkpoint(key, newValue)); - } else { - Checkpoint storage last = _trace[_trace.length - 1]; - oldValue = last.value; - newValue = isAdd ? oldValue + amount : oldValue - amount; - if (last.key > key) revert("Unordered insertion"); - if (last.key == key) { - last.value = newValue; - } else { - _trace.push(Checkpoint(key, newValue)); - } - } - } - - function _checkpointLatestKeyOriginal() private view returns (uint256) { - return _trace.length == 0 ? 0 : _trace[_trace.length - 1].key; - } - - function _checkpointLatestOriginal() private view returns (uint256) { - return _trace.length == 0 ? 0 : _trace[_trace.length - 1].value; - } - - function _checkpointLatestKey(uint256 lengthSlot) private view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(208, shl(160, sload(lengthSlot))) - if result { result := and(0xffffffffffff, sload(add(sub(result, 1), lengthSlot))) } - } - } - - function _checkpointAt(uint256 lengthSlot, uint256 i) - private - view - returns (uint48 checkpointClock, uint256 checkpointValue) - { - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(i, shr(208, shl(160, sload(lengthSlot))))) { - mstore(0x00, 0x86df9d10) // `ERC5805CheckpointIndexOutOfBounds()`. - revert(0x1c, 0x04) - } - let checkpointPacked := sload(add(i, lengthSlot)) - checkpointClock := and(0xffffffffffff, checkpointPacked) - checkpointValue := shr(96, checkpointPacked) - if eq(checkpointValue, address()) { checkpointValue := sload(not(add(i, lengthSlot))) } - } - } - - function checkpointPushDiff(uint256 lengthSlot, uint256 key, uint256 amount, bool isAdd) - public - returns (uint256 oldValue, uint256 newValue) - { - return _checkpointPushDiff(lengthSlot, key, amount, isAdd); - } - - /// @dev Pushes a checkpoint. - function _checkpointPushDiff(uint256 lengthSlot, uint256 key, uint256 amount, bool isAdd) - private - returns (uint256 oldValue, uint256 newValue) - { - /// @solidity memory-safe-assembly - assembly { - let lengthSlotPacked := sload(lengthSlot) - for { let n := shr(208, shl(160, lengthSlotPacked)) } 1 {} { - if iszero(n) { - if iszero(or(isAdd, iszero(amount))) { - mstore(0x00, 0x5915f686) // `ERC5805CheckpointValueUnderflow()`. - revert(0x1c, 0x04) - } - newValue := amount - if iszero(or(eq(newValue, address()), shr(160, newValue))) { - sstore(lengthSlot, or(or(key, shl(48, 1)), shl(96, newValue))) - break - } - sstore(lengthSlot, or(or(key, shl(48, 1)), shl(96, address()))) - sstore(not(lengthSlot), newValue) - break - } - let checkpointSlot := add(sub(n, 1), lengthSlot) - let lastPacked := sload(checkpointSlot) - oldValue := shr(96, lastPacked) - if eq(oldValue, address()) { oldValue := sload(not(checkpointSlot)) } - for {} 1 {} { - if iszero(isAdd) { - newValue := sub(oldValue, amount) - if iszero(gt(newValue, oldValue)) { break } - mstore(0x00, 0x5915f686) // `ERC5805CheckpointValueUnderflow()`. - revert(0x1c, 0x04) - } - newValue := add(oldValue, amount) - if iszero(lt(newValue, oldValue)) { break } - mstore(0x00, 0x9dbbeb75) // `ERC5805CheckpointValueOverflow()`. - revert(0x1c, 0x04) - } - let lastKey := and(0xffffffffffff, lastPacked) - if iszero(eq(lastKey, key)) { - n := add(1, n) - checkpointSlot := add(1, checkpointSlot) - sstore(lengthSlot, add(shl(48, 1), lengthSlotPacked)) - } - if or(gt(lastKey, key), shr(48, n)) { invalid() } - if iszero(or(eq(newValue, address()), shr(160, newValue))) { - sstore(checkpointSlot, or(or(key, shl(48, n)), shl(96, newValue))) - break - } - sstore(checkpointSlot, or(or(key, shl(48, n)), shl(96, address()))) - sstore(not(checkpointSlot), newValue) - break - } - } - } - - /// @dev Returns the latest value in the checkpoints. - function _checkpointLatest(uint256 lengthSlot) private view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(208, shl(160, sload(lengthSlot))) - if result { - lengthSlot := add(sub(result, 1), lengthSlot) // Reuse for `checkpointSlot`. - result := shr(96, sload(lengthSlot)) - if eq(result, address()) { result := sload(not(lengthSlot)) } - } - } - } - - /// @dev Returns the value in the checkpoints with the largest key that is less than `key`. - function _checkpointUpperLookupRecent(uint256 lengthSlot, uint256 key) - private - view - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - let l := 0 // Low. - let h := shr(208, shl(160, sload(lengthSlot))) // High. - // Start the binary search nearer to the right to optimize for recent checkpoints. - for {} iszero(lt(h, 6)) {} { - let m := shl(4, lt(0xffff, h)) - m := shl(shr(1, or(m, shl(3, lt(0xff, shr(m, h))))), 16) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := shr(1, add(m, div(h, m))) - m := sub(h, shr(1, add(m, div(h, m)))) // Approx `h - sqrt(h)`. - if iszero(lt(key, and(sload(add(m, lengthSlot)), 0xffffffffffff))) { - l := add(1, m) - break - } - h := m - break - } - // Binary search. - for {} lt(l, h) {} { - let m := shr(1, add(l, h)) // Won't overflow in practice. - if iszero(lt(key, and(sload(add(m, lengthSlot)), 0xffffffffffff))) { - l := add(1, m) - continue - } - h := m - } - let checkpointSlot := add(sub(h, 1), lengthSlot) - result := mul(iszero(iszero(h)), shr(96, sload(checkpointSlot))) - if eq(result, address()) { result := sload(not(checkpointSlot)) } - } - } -} diff --git a/grouperBot/lib/solady/test/ERC2981.t.sol b/grouperBot/lib/solady/test/ERC2981.t.sol deleted file mode 100644 index d0d90b4..0000000 --- a/grouperBot/lib/solady/test/ERC2981.t.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; - -import {ERC2981, MockERC2981} from "./utils/mocks/MockERC2981.sol"; - -contract ERC2981Test is SoladyTest { - MockERC2981 token; - - function setUp() public { - token = new MockERC2981(); - } - - struct _TestTemps { - uint256 feeDenominator; - address[2] receivers; - uint256[2] tokenIds; - uint256[2] salePrices; - uint256[2] royaltyFractions; - address defaultReceiver; - uint256 defaultRoyaltyFraction; - } - - function _testTemps() internal returns (_TestTemps memory t) { - t.feeDenominator = token.feeDenominator(); - t.tokenIds[0] = _random(); - do { - t.tokenIds[1] = _random(); - } while (t.tokenIds[0] == t.tokenIds[1]); - t.receivers[0] = _randomNonZeroAddress(); - do { - t.receivers[1] = _randomNonZeroAddress(); - } while (t.receivers[0] == t.receivers[1]); - t.salePrices[0] = _bound(_random(), 0, type(uint160).max); - t.salePrices[1] = _bound(_random(), 0, type(uint160).max); - t.defaultReceiver = _randomNonZeroAddress(); - t.defaultRoyaltyFraction = _bound(_random(), 0, t.feeDenominator); - t.royaltyFractions[0] = _bound(_random(), 0, t.feeDenominator); - t.royaltyFractions[1] = _bound(_random(), 0, t.feeDenominator); - } - - function testRoyaltyOverflowCheckDifferential(uint256 x, uint256 y) public { - unchecked { - bool expected = x != 0 && (x * y) / x != y; - bool computed; - /// @solidity memory-safe-assembly - assembly { - computed := mul(y, gt(x, div(not(0), y))) - } - assertEq(computed, expected); - } - } - - function testSetAndGetRoyaltyInfo(uint256) public { - _TestTemps memory t = _testTemps(); - - if (_randomChance(16)) _checkReverts(t); - - _checkRoyaltyInfoIsZero(t); - - token.setDefaultRoyalty(t.defaultReceiver, uint96(t.defaultRoyaltyFraction)); - _checkRoyaltyInfoIsDefault(t, 0); - _checkRoyaltyInfoIsDefault(t, 1); - - token.setTokenRoyalty(t.tokenIds[0], t.receivers[0], uint96(t.royaltyFractions[0])); - _checkRoyaltyInfo(t, 0); - _checkRoyaltyInfoIsDefault(t, 1); - token.setTokenRoyalty(t.tokenIds[1], t.receivers[1], uint96(t.royaltyFractions[1])); - _checkRoyaltyInfo(t, 0); - _checkRoyaltyInfo(t, 1); - - if (_randomChance(16)) _checkReverts(t); - - token.resetTokenRoyalty(t.tokenIds[0]); - _checkRoyaltyInfoIsDefault(t, 0); - _checkRoyaltyInfo(t, 1); - token.resetTokenRoyalty(t.tokenIds[1]); - _checkRoyaltyInfoIsDefault(t, 0); - _checkRoyaltyInfoIsDefault(t, 1); - - if (_randomChance(16)) _checkReverts(t); - - token.deleteDefaultRoyalty(); - - _checkRoyaltyInfoIsZero(t); - - if (_randomChance(16)) _checkReverts(t); - } - - function _getInvalidFeeNumerator(_TestTemps memory t) internal returns (uint96 r) { - while (true) { - r = uint96(_random()); - if (r > t.feeDenominator) break; - } - } - - function _checkReverts(_TestTemps memory t) internal { - vm.expectRevert(ERC2981.RoyaltyReceiverIsZeroAddress.selector); - token.setDefaultRoyalty(address(0), 1); - vm.expectRevert(ERC2981.RoyaltyOverflow.selector); - token.setDefaultRoyalty(t.defaultReceiver, _getInvalidFeeNumerator(t)); - - vm.expectRevert(ERC2981.RoyaltyReceiverIsZeroAddress.selector); - token.setTokenRoyalty(t.tokenIds[0], address(0), 1); - vm.expectRevert(ERC2981.RoyaltyOverflow.selector); - token.setTokenRoyalty(t.tokenIds[0], t.receivers[0], _getInvalidFeeNumerator(t)); - - vm.expectRevert(ERC2981.RoyaltyReceiverIsZeroAddress.selector); - token.setTokenRoyalty(t.tokenIds[1], address(0), 1); - vm.expectRevert(ERC2981.RoyaltyOverflow.selector); - token.setTokenRoyalty(t.tokenIds[1], t.receivers[1], _getInvalidFeeNumerator(t)); - } - - function _checkRoyaltyInfoIsZero(_TestTemps memory t) internal { - _checkRoyaltyInfo(t, 0, address(0), 0); - _checkRoyaltyInfo(t, 1, address(0), 0); - } - - function _checkRoyaltyInfoIsDefault(_TestTemps memory t, uint256 i) internal { - uint256 expected = t.salePrices[i] * t.defaultRoyaltyFraction / t.feeDenominator; - _checkRoyaltyInfo(t, i, t.defaultReceiver, expected); - } - - function _checkRoyaltyInfo(_TestTemps memory t, uint256 i) internal { - uint256 expected = t.salePrices[i] * t.royaltyFractions[i] / t.feeDenominator; - _checkRoyaltyInfo(t, i, t.receivers[i], expected); - } - - function _checkRoyaltyInfo( - _TestTemps memory t, - uint256 i, - address expectedReceiver, - uint256 expectedAmount - ) internal { - (address receiver, uint256 amount) = token.royaltyInfo(t.tokenIds[i], t.salePrices[i]); - assertEq(receiver, expectedReceiver); - assertEq(amount, expectedAmount); - } -} diff --git a/grouperBot/lib/solady/test/ERC4337.t.sol b/grouperBot/lib/solady/test/ERC4337.t.sol deleted file mode 100644 index ed20808..0000000 --- a/grouperBot/lib/solady/test/ERC4337.t.sol +++ /dev/null @@ -1,626 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {Ownable, SignatureCheckerLib} from "../src/accounts/ERC4337.sol"; -import {ERC4337, MockERC4337} from "./utils/mocks/MockERC4337.sol"; -import {MockEntryPoint} from "./utils/mocks/MockEntryPoint.sol"; -import {MockERC721} from "./utils/mocks/MockERC721.sol"; -import {MockERC1155} from "./utils/mocks/MockERC1155.sol"; -import {MockERC1271Wallet} from "./utils/mocks/MockERC1271Wallet.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {LibString} from "../src/utils/LibString.sol"; -import {LibZip} from "../src/utils/LibZip.sol"; - -contract Target { - error TargetError(bytes data); - - bytes32 public datahash; - - bytes public data; - - function setData(bytes memory data_) public payable returns (bytes memory) { - data = data_; - datahash = keccak256(data_); - return data_; - } - - function revertWithTargetError(bytes memory data_) public payable { - revert TargetError(data_); - } - - function changeOwnerSlotValue(bool change) public payable { - /// @solidity memory-safe-assembly - assembly { - if change { sstore(not(0x8b78c6d8), 0x112233) } - } - } -} - -contract ERC4337Test is SoladyTest { - event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); - - // By right, this should be the keccak256 of some long-ass string: - // (e.g. `keccak256("Parent(bytes32 childHash,Mail child)Mail(Person from,Person to,string contents)Person(string name,address wallet)")`). - // But I'm lazy and will use something randomish here. - bytes32 internal constant _PARENT_TYPEHASH = - 0xd61db970ec8a2edc5f9fd31d876abe01b785909acb16dcd4baaf3b434b4c439b; - - // By right, this should be a proper domain separator, but I'm lazy. - bytes32 internal constant _DOMAIN_SEP_B = - 0xa1a044077d7677adbbfa892ded5390979b33993e0e2a457e3f974bbcda53821b; - - address internal constant _ENTRY_POINT = 0x0000000071727De22E5E9d8BAf0edAc6f37da032; - - address erc4337; - - MockERC4337 account; - - function setUp() public { - // Etch something onto `_ENTRY_POINT` such that we can deploy the account implementation. - vm.etch(_ENTRY_POINT, hex"00"); - erc4337 = address(new MockERC4337()); - account = MockERC4337(payable(LibClone.deployERC1967(erc4337))); - } - - function testDisableInitializerForImplementation() public { - MockERC4337 mock = new MockERC4337(); - assertEq(mock.owner(), address(1)); - vm.expectRevert(Ownable.AlreadyInitialized.selector); - mock.initialize(address(this)); - } - - function testInitializer() public { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(0), address(this)); - account.initialize(address(this)); - assertEq(account.owner(), address(this)); - vm.expectRevert(Ownable.AlreadyInitialized.selector); - account.initialize(address(this)); - - address newOwner = _cleaned(_randomNonZeroAddress()); - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), newOwner); - account.transferOwnership(newOwner); - assertEq(account.owner(), newOwner); - - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(newOwner, address(this)); - vm.prank(newOwner); - account.transferOwnership(address(this)); - - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), address(0)); - account.renounceOwnership(); - assertEq(account.owner(), address(0)); - - vm.expectRevert(Ownable.AlreadyInitialized.selector); - account.initialize(address(this)); - assertEq(account.owner(), address(0)); - - account = MockERC4337(payable(LibClone.deployERC1967(erc4337))); - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(0), address(0)); - account.initialize(address(0)); - assertEq(account.owner(), address(0)); - - vm.expectRevert(Ownable.AlreadyInitialized.selector); - account.initialize(address(this)); - assertEq(account.owner(), address(0)); - - account = MockERC4337(payable(LibClone.deployERC1967(erc4337))); - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(0), address(1)); - account.initialize(address(1)); - assertEq(account.owner(), address(1)); - - vm.expectRevert(Ownable.AlreadyInitialized.selector); - account.initialize(address(this)); - assertEq(account.owner(), address(1)); - } - - function testExecute() public { - vm.deal(address(account), 1 ether); - account.initialize(address(this)); - - address target = address(new Target()); - bytes memory data = _randomBytes(111); - account.execute(target, 123, abi.encodeWithSignature("setData(bytes)", data)); - assertEq(Target(target).datahash(), keccak256(data)); - assertEq(target.balance, 123); - - vm.prank(_randomNonZeroAddress()); - vm.expectRevert(Ownable.Unauthorized.selector); - account.execute(target, 123, abi.encodeWithSignature("setData(bytes)", data)); - - vm.expectRevert(abi.encodeWithSignature("TargetError(bytes)", data)); - account.execute(target, 123, abi.encodeWithSignature("revertWithTargetError(bytes)", data)); - } - - function testExecuteBatch() public { - vm.deal(address(account), 1 ether); - account.initialize(address(this)); - - ERC4337.Call[] memory calls = new ERC4337.Call[](2); - calls[0].target = address(new Target()); - calls[1].target = address(new Target()); - calls[0].value = 123; - calls[1].value = 456; - calls[0].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(111)); - calls[1].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(222)); - - account.executeBatch(calls); - assertEq(Target(calls[0].target).datahash(), keccak256(_randomBytes(111))); - assertEq(Target(calls[1].target).datahash(), keccak256(_randomBytes(222))); - assertEq(calls[0].target.balance, 123); - assertEq(calls[1].target.balance, 456); - - calls[1].data = abi.encodeWithSignature("revertWithTargetError(bytes)", _randomBytes(111)); - vm.expectRevert(abi.encodeWithSignature("TargetError(bytes)", _randomBytes(111))); - account.executeBatch(calls); - } - - function testExecuteBatch(uint256 r) public { - vm.deal(address(account), 1 ether); - account.initialize(address(this)); - - unchecked { - uint256 n = r & 3; - ERC4337.Call[] memory calls = new ERC4337.Call[](n); - - for (uint256 i; i != n; ++i) { - uint256 v = _random() & 0xff; - calls[i].target = address(new Target()); - calls[i].value = v; - calls[i].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(v)); - } - - bytes[] memory results; - if (_random() & 1 == 0) { - results = account.executeBatch(_random(), calls); - } else { - results = account.executeBatch(calls); - } - - assertEq(results.length, n); - for (uint256 i; i != n; ++i) { - uint256 v = calls[i].value; - assertEq(Target(calls[i].target).datahash(), keccak256(_randomBytes(v))); - assertEq(calls[i].target.balance, v); - assertEq(abi.decode(results[i], (bytes)), _randomBytes(v)); - } - } - } - - function testDelegateExecute() public { - testDelegateExecute(123); - } - - function testDelegateExecute(uint256 r) public { - vm.deal(address(account), 1 ether); - account.initialize(address(this)); - - address delegate = address(new Target()); - - bytes memory data; - data = abi.encodeWithSignature("setData(bytes)", _randomBytes(r)); - data = account.delegateExecute(delegate, data); - assertEq(abi.decode(data, (bytes)), _randomBytes(r)); - data = account.delegateExecute(delegate, abi.encodeWithSignature("datahash()")); - assertEq(abi.decode(data, (bytes32)), keccak256(_randomBytes(r))); - data = account.delegateExecute(delegate, abi.encodeWithSignature("data()")); - assertEq(abi.decode(data, (bytes)), _randomBytes(r)); - } - - function testDelegateExecuteRevertsIfOwnerSlotValueChanged() public { - account.initialize(address(this)); - - address delegate = address(new Target()); - - bytes memory data; - data = abi.encodeWithSignature("changeOwnerSlotValue(bool)", false); - account.delegateExecute(delegate, data); - vm.expectRevert(); - data = abi.encodeWithSignature("changeOwnerSlotValue(bool)", true); - account.delegateExecute(delegate, data); - data = abi.encodeWithSignature("changeOwnerSlotValue(bool)", false); - account.delegateExecute(delegate, data); - } - - function testDepositFunctions() public { - vm.deal(address(account), 1 ether); - account.initialize(address(this)); - - vm.etch(account.entryPoint(), address(new MockEntryPoint()).code); - assertEq(account.getDeposit(), 0); - account.addDeposit{value: 123}(); - assertEq(account.getDeposit(), 123); - address to = _randomNonZeroAddress(); - assertEq(to.balance, 0); - account.withdrawDepositTo(to, 12); - assertEq(to.balance, 12); - assertEq(account.getDeposit(), 123 - 12); - } - - function testCdFallback() public { - vm.deal(address(account), 1 ether); - account.initialize(address(this)); - - vm.etch(account.entryPoint(), address(new MockEntryPoint()).code); - assertEq(account.getDeposit(), 0); - - bytes memory data = LibZip.cdCompress(abi.encodeWithSignature("addDeposit()")); - (bool success,) = address(account).call{value: 123}(data); - assertTrue(success); - assertEq(account.getDeposit(), 123); - } - - function testCdFallback2() public { - vm.deal(address(account), 1 ether); - account.initialize(address(this)); - - vm.etch(account.entryPoint(), address(new MockEntryPoint()).code); - assertEq(account.getDeposit(), 0); - - ERC4337.Call[] memory calls = new ERC4337.Call[](2); - calls[0].target = address(new Target()); - calls[1].target = address(new Target()); - calls[0].value = 123; - calls[1].value = 456; - calls[0].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(111)); - calls[1].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(222)); - - bytes memory data = LibZip.cdCompress( - abi.encodeWithSignature("executeBatch((address,uint256,bytes)[])", calls) - ); - (bool success,) = address(account).call(data); - assertTrue(success); - assertEq(Target(calls[0].target).datahash(), keccak256(_randomBytes(111))); - assertEq(Target(calls[1].target).datahash(), keccak256(_randomBytes(222))); - assertEq(calls[0].target.balance, 123); - assertEq(calls[1].target.balance, 456); - } - - struct _TestTemps { - bytes32 userOpHash; - bytes32 contents; - address signer; - uint256 privateKey; - uint8 v; - bytes32 r; - bytes32 s; - uint256 missingAccountFunds; - } - - function testValidateUserOp() public { - _TestTemps memory t; - t.userOpHash = keccak256("123"); - (t.signer, t.privateKey) = _randomSigner(); - (t.v, t.r, t.s) = - vm.sign(t.privateKey, SignatureCheckerLib.toEthSignedMessageHash(t.userOpHash)); - t.missingAccountFunds = 456; - vm.deal(address(account), 1 ether); - assertEq(address(account).balance, 1 ether); - - account.initialize(t.signer); - - vm.etch(account.entryPoint(), address(new MockEntryPoint()).code); - MockEntryPoint ep = MockEntryPoint(payable(account.entryPoint())); - - ERC4337.PackedUserOperation memory userOp; - // Success returns 0. - userOp.signature = abi.encodePacked(t.r, t.s, t.v); - assertEq( - ep.validateUserOp(address(account), userOp, t.userOpHash, t.missingAccountFunds), 0 - ); - assertEq(address(ep).balance, t.missingAccountFunds); - // Failure returns 1. - userOp.signature = abi.encodePacked(t.r, bytes32(uint256(t.s) ^ 1), t.v); - assertEq( - ep.validateUserOp(address(account), userOp, t.userOpHash, t.missingAccountFunds), 1 - ); - assertEq(address(ep).balance, t.missingAccountFunds * 2); - // Not entry point reverts. - vm.expectRevert(Ownable.Unauthorized.selector); - account.validateUserOp(userOp, t.userOpHash, t.missingAccountFunds); - } - - function testIsValidSignature() public { - vm.txGasPrice(10); - _TestTemps memory t; - t.contents = keccak256("123"); - (t.signer, t.privateKey) = _randomSigner(); - (t.v, t.r, t.s) = vm.sign(t.privateKey, _toERC1271Hash(t.contents)); - - account.initialize(t.signer); - - bytes memory contentsType = "Contents(bytes32 stuff)"; - bytes memory signature = abi.encodePacked( - t.r, t.s, t.v, _DOMAIN_SEP_B, t.contents, contentsType, uint16(contentsType.length) - ); - assertEq( - account.isValidSignature(_toContentsHash(t.contents), signature), bytes4(0x1626ba7e) - ); - - unchecked { - signature = abi.encodePacked( - t.r, _vs(t), _DOMAIN_SEP_B, t.contents, contentsType, uint16(contentsType.length) - ); - assertEq( - account.isValidSignature(_toContentsHash(t.contents), signature), bytes4(0x1626ba7e) - ); - } - - signature = abi.encodePacked(t.r, t.s, t.v, uint256(_DOMAIN_SEP_B) ^ 1, t.contents); - assertEq( - account.isValidSignature(_toContentsHash(t.contents), signature), bytes4(0xffffffff) - ); - - signature = abi.encodePacked(t.r, t.s, t.v, _DOMAIN_SEP_B, uint256(t.contents) ^ 1); - assertEq( - account.isValidSignature(_toContentsHash(t.contents), signature), bytes4(0xffffffff) - ); - - signature = abi.encodePacked(t.r, t.s, t.v); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - signature = abi.encodePacked(t.r, t.s); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - signature = abi.encodePacked(t.r); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - signature = ""; - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - } - - function testIsValidSignaturePersonalSign(bytes32 seed) public { - vm.txGasPrice(10); - _TestTemps memory t; - t.contents = keccak256(abi.encode("123", seed)); - (t.signer, t.privateKey) = _randomSigner(); - (t.v, t.r, t.s) = vm.sign(t.privateKey, _toERC1271HashPersonalSign(t.contents)); - - account.initialize(t.signer); - - bytes memory signature = abi.encodePacked(t.r, t.s, t.v); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0x1626ba7e)); - - unchecked { - signature = abi.encodePacked(t.r, _vs(t)); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0x1626ba7e)); - } - - signature = abi.encodePacked(t.r, t.s, _DOMAIN_SEP_B, t.contents); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - signature = abi.encodePacked(t.r, t.s, _DOMAIN_SEP_B); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - signature = abi.encodePacked(t.r, t.s); - if (keccak256(signature) == keccak256(abi.encodePacked(t.r, _vs(t)))) { - assertEq(account.isValidSignature(t.contents, signature), bytes4(0x1626ba7e)); - } else { - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - } - - signature = abi.encodePacked(t.r); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - signature = ""; - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - } - - function _vs(_TestTemps memory t) internal pure returns (uint256) { - unchecked { - return uint256(t.s) | uint256(t.v - 27) << 255; - } - } - - function testIsValidSignatureViaRPC() public { - vm.txGasPrice(10); - _TestTemps memory t; - t.contents = keccak256("123"); - (t.signer, t.privateKey) = _randomSigner(); - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.contents); - - account.initialize(t.signer); - - bytes memory signature = abi.encodePacked(t.r, t.s, t.v, _PARENT_TYPEHASH); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - vm.txGasPrice(1); - assertEq(account.isValidSignature(t.contents, signature), bytes4(0xffffffff)); - - vm.txGasPrice(0); - vm.expectRevert(); - account.isValidSignature(t.contents, signature); - - // Unfortunately, I don't know of a way to make Foundry simulate a call with `gas > gaslimit`. - // But we can be sure that most RPCs will do that. - // See: https://sepolia.etherscan.io/address/0x4f55bb26d7195babf9f8144bdc4ae4dd919c746d#code - } - - function testIsValidSignatureWrapped() public { - _TestTemps memory t; - t.contents = keccak256("123"); - (t.signer, t.privateKey) = _randomSigner(); - (t.v, t.r, t.s) = vm.sign(t.privateKey, _toERC1271Hash(t.contents)); - - MockERC1271Wallet wrappedSigner = new MockERC1271Wallet(t.signer); - account.initialize(address(wrappedSigner)); - - bytes memory contentsType = "Contents(bytes32 stuff)"; - bytes memory signature = abi.encodePacked( - t.r, t.s, t.v, _DOMAIN_SEP_B, t.contents, contentsType, uint16(contentsType.length) - ); - assertEq( - account.isValidSignature(_toContentsHash(t.contents), signature), bytes4(0x1626ba7e) - ); - } - - struct _AccountDomainStruct { - string name; - string version; - uint256 chainId; - address verifyingContract; - bytes32 salt; - } - - function _accountDomainStructFields() internal view returns (bytes memory) { - _AccountDomainStruct memory t; - (, t.name, t.version, t.chainId, t.verifyingContract, t.salt,) = account.eip712Domain(); - - return abi.encode( - keccak256(bytes(t.name)), - keccak256(bytes(t.version)), - t.chainId, - t.verifyingContract, - t.salt - ); - } - - function _toERC1271Hash(bytes32 contents) internal view returns (bytes32) { - bytes32 parentStructHash = keccak256( - abi.encodePacked( - abi.encode( - keccak256( - "TypedDataSign(Contents contents,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)Contents(bytes32 stuff)" - ), - contents - ), - _accountDomainStructFields() - ) - ); - return keccak256(abi.encodePacked("\x19\x01", _DOMAIN_SEP_B, parentStructHash)); - } - - function _toContentsHash(bytes32 contents) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(hex"1901", _DOMAIN_SEP_B, contents)); - } - - function _toERC1271HashPersonalSign(bytes32 childHash) internal view returns (bytes32) { - bytes32 domainSeparator = keccak256( - abi.encode( - keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" - ), - keccak256("Milady"), - keccak256("1"), - block.chainid, - address(account) - ) - ); - bytes32 parentStructHash = - keccak256(abi.encode(keccak256("PersonalSign(bytes prefixed)"), childHash)); - return keccak256(abi.encodePacked("\x19\x01", domainSeparator, parentStructHash)); - } - - function testETHReceived() public { - (bool success,) = address(account).call{value: 1 ether}(""); - assertTrue(success); - } - - function testOnERC721Received() public { - address alice = _randomNonZeroAddress(); - MockERC721 erc721 = new MockERC721(); - erc721.mint(alice, 1); - vm.prank(alice); - erc721.safeTransferFrom(alice, address(account), 1); - } - - function testOnERC1155Received() public { - address alice = _randomNonZeroAddress(); - MockERC1155 erc1155 = new MockERC1155(); - erc1155.mint(alice, 1, 1, ""); - vm.prank(alice); - erc1155.safeTransferFrom(alice, address(account), 1, 1, ""); - } - - function testOnERC1155BatchReceived() public { - address alice = _randomNonZeroAddress(); - MockERC1155 erc1155 = new MockERC1155(); - erc1155.mint(alice, 1, 1, ""); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amts = new uint256[](1); - amts[0] = 1; - vm.prank(alice); - erc1155.safeBatchTransferFrom(alice, address(account), ids, amts, ""); - } - - function testDirectStorage() public { - bytes32 storageSlot = bytes32(uint256(123)); - bytes32 storageValue = bytes32(uint256(456)); - - vm.expectRevert(Ownable.Unauthorized.selector); - account.storageStore(storageSlot, storageValue); - - account.initialize(address(this)); - assertEq(account.storageLoad(storageSlot), bytes32(0)); - account.storageStore(storageSlot, storageValue); - assertEq(account.storageLoad(storageSlot), storageValue); - } - - function testOwnerRecovery() public { - ERC4337.PackedUserOperation memory userOp; - - userOp.sender = address(account); - userOp.nonce = 4337; - - // `bob` is set as recovery. - address bob = address(0xb); - userOp.callData = abi.encodeWithSelector( - ERC4337.execute.selector, - address(account), - 0, - abi.encodeWithSelector(Ownable.completeOwnershipHandover.selector, bob) - ); - - // `bob` must accept recovery. - // IRL this would follow need. - vm.prank(bob); - account.requestOwnershipHandover(); - - _TestTemps memory t; - t.userOpHash = keccak256(abi.encode(userOp)); - (t.signer, t.privateKey) = _randomSigner(); - (t.v, t.r, t.s) = - vm.sign(t.privateKey, SignatureCheckerLib.toEthSignedMessageHash(t.userOpHash)); - - t.missingAccountFunds = 456; - vm.deal(address(account), 1 ether); - - account.initialize(t.signer); - assertEq(account.owner(), t.signer); - - vm.etch(account.entryPoint(), address(new MockEntryPoint()).code); - MockEntryPoint ep = MockEntryPoint(payable(account.entryPoint())); - - // Success returns 0. - userOp.signature = abi.encodePacked(t.r, t.s, t.v); - assertEq( - ep.validateUserOp(address(account), userOp, t.userOpHash, t.missingAccountFunds), 0 - ); - // Check recovery to `bob`. - vm.prank(address(ep)); - (bool success,) = address(account).call(userOp.callData); - assertTrue(success); - assertEq(account.owner(), bob); - } - - function _randomBytes(uint256 seed) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, seed) - let r := keccak256(0x00, 0x20) - if lt(byte(2, r), 0x20) { - result := mload(0x40) - let n := and(r, 0x7f) - mstore(result, n) - codecopy(add(result, 0x20), byte(1, r), add(n, 0x40)) - mstore(0x40, add(add(result, 0x40), n)) - } - } - } -} diff --git a/grouperBot/lib/solady/test/ERC4337Factory.t.sol b/grouperBot/lib/solady/test/ERC4337Factory.t.sol deleted file mode 100644 index 932c4d4..0000000 --- a/grouperBot/lib/solady/test/ERC4337Factory.t.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MockERC4337} from "./utils/mocks/MockERC4337.sol"; -import {ERC4337Factory} from "../src/accounts/ERC4337Factory.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; - -contract ERC4337FactoryTest is SoladyTest { - address internal constant _ENTRY_POINT = 0x0000000071727De22E5E9d8BAf0edAc6f37da032; - - ERC4337Factory factory; - - MockERC4337 erc4337; - - function setUp() public { - // Etch something onto `_ENTRY_POINT` such that we can deploy the account implementation. - vm.etch(_ENTRY_POINT, hex"00"); - erc4337 = new MockERC4337(); - factory = new ERC4337Factory(address(erc4337)); - } - - function testDeployDeterministic(uint256) public { - vm.deal(address(this), 100 ether); - address owner = _randomNonZeroAddress(); - uint256 initialValue = _random() % 100 ether; - bytes32 ownSalt = bytes32(bytes20(owner)) | bytes32(uint256(uint96(_random()))); - address account = factory.createAccount{value: initialValue}(ownSalt); - assertEq(address(account).balance, initialValue); - assertEq(MockERC4337(payable(account)).owner(), owner); - _checkImplementationSlot(account, address(erc4337)); - } - - function testCreateAccountRepeatedDeployment() public { - address owner = address(0xABCD); - bytes32 ownSalt = bytes32(bytes20(owner)) | bytes32(uint256(uint96(_random()))); - address expectedInstance = factory.getAddress(ownSalt); - address instance = factory.createAccount{value: 123}(ownSalt); - assertEq(instance.balance, 123); - assertEq(factory.createAccount{value: 456}(ownSalt), instance); - assertEq(factory.createAccount(ownSalt), instance); - assertEq(instance.balance, 123 + 456); - assertEq(expectedInstance, instance); - } - - function testCreateAccountRepeatedDeployment(uint256) public { - address owner = _randomNonZeroAddress(); - bytes32 ownSalt = bytes32(bytes20(owner)) | bytes32(uint256(uint96(_random()))); - address expectedInstance = factory.getAddress(ownSalt); - address notOwner = _randomNonZeroAddress(); - while (owner == notOwner) notOwner = _randomNonZeroAddress(); - - address instance = factory.createAccount{value: 123}(ownSalt); - assertEq(instance.balance, 123); - assertEq(factory.createAccount{value: 456}(ownSalt), instance); - assertEq(factory.createAccount(ownSalt), instance); - assertEq(instance.balance, 123 + 456); - assertEq(expectedInstance, instance); - } - - function _checkImplementationSlot(address proxy, address implementation_) internal { - bytes32 slot = bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1); - assertEq(vm.load(proxy, slot), bytes32(uint256(uint160(implementation_)))); - } -} diff --git a/grouperBot/lib/solady/test/ERC4626.t.sol b/grouperBot/lib/solady/test/ERC4626.t.sol deleted file mode 100644 index e6d9b0b..0000000 --- a/grouperBot/lib/solady/test/ERC4626.t.sol +++ /dev/null @@ -1,609 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; - -import {ERC20, MockERC20} from "./utils/mocks/MockERC20.sol"; -import {ERC4626, MockERC4626} from "./utils/mocks/MockERC4626.sol"; -import {SafeTransferLib} from "../src/utils/SafeTransferLib.sol"; -import {FixedPointMathLib} from "../src/utils/FixedPointMathLib.sol"; - -contract ERC4626Test is SoladyTest { - MockERC20 underlying; - MockERC4626 vault; - - event Deposit(address indexed by, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed by, - address indexed to, - address indexed owner, - uint256 assets, - uint256 shares - ); - - function setUp() public { - underlying = new MockERC20("Mock Token", "TKN", 18); - vault = new MockERC4626(address(underlying), "Mock Token Vault", "vwTKN", false, 0); - } - - function _replaceWithVirtualSharesVault(uint8 decimalsOffset) internal { - vault = new MockERC4626(address(underlying), "VSV", "VSVTKN", true, decimalsOffset); - } - - function _replaceWithVirtualSharesVault() internal { - _replaceWithVirtualSharesVault(0); - } - - function testDifferentialFullMulDiv(uint256 x, uint256 y, uint256 d) public { - d = type(uint256).max - d % 4; - (bool success0,) = address(this).call( - abi.encodeWithSignature("fullMulDivChecked(uint256,uint256,uint256)", x, y, d) - ); - (bool success1,) = address(this).call( - abi.encodeWithSignature("fullMulDivUnchecked(uint256,uint256,uint256)", x, y, d) - ); - if (d == type(uint256).max) { - assertFalse(success0); - assertFalse(success1); - } - assertEq(success0, success1); - } - - function fullMulDivChecked(uint256 x, uint256 y, uint256 d) public pure { - FixedPointMathLib.fullMulDiv(x, y, d + 1); - } - - function fullMulDivUnchecked(uint256 x, uint256 y, uint256 d) public pure { - unchecked { - FixedPointMathLib.fullMulDiv(x, y, d + 1); - } - } - - function testMetadata() public { - assertEq(vault.name(), "Mock Token Vault"); - assertEq(vault.symbol(), "vwTKN"); - assertEq(vault.decimals(), 18); - } - - function testUseVirtualShares() public { - assertEq(vault.useVirtualShares(), false); - _replaceWithVirtualSharesVault(); - assertEq(vault.useVirtualShares(), true); - assertEq(vault.decimals(), 18); - _replaceWithVirtualSharesVault(1); - assertEq(vault.decimals(), 19); - } - - function testTryGetAssetDecimals() public { - unchecked { - for (uint256 i = 0; i < 5; ++i) { - _testTryGetAssetDecimals(uint8(i)); - } - for (uint256 i = 125; i < 130; ++i) { - _testTryGetAssetDecimals(uint8(i)); - } - for (uint256 i = 250; i < 256; ++i) { - _testTryGetAssetDecimals(uint8(i)); - } - } - vault = new MockERC4626(address(this), "", "", false, 0); - assertEq(vault.decimals(), 18); - } - - function _testTryGetAssetDecimals(uint8 i) internal { - underlying = new MockERC20("", "", i); - assertEq(underlying.decimals(), i); - vault = new MockERC4626(address(underlying), "", "", false, 0); - assertEq(vault.decimals(), i); - } - - function testSingleDepositWithdraw(uint128 amount) public { - if (amount == 0) amount = 1; - - uint256 aliceUnderlyingAmount = amount; - - address alice = address(0xABCD); - - underlying.mint(alice, aliceUnderlyingAmount); - - vm.prank(alice); - underlying.approve(address(vault), aliceUnderlyingAmount); - assertEq(underlying.allowance(alice, address(vault)), aliceUnderlyingAmount); - - uint256 alicePreDepositBal = underlying.balanceOf(alice); - - vm.prank(alice); - uint256 aliceShareAmount = vault.deposit(aliceUnderlyingAmount, alice); - - assertEq(vault.afterDepositHookCalledCounter(), 1); - - // Expect exchange rate to be 1:1 on initial deposit. - unchecked { - assertEq(aliceUnderlyingAmount, aliceShareAmount); - assertEq(vault.previewWithdraw(aliceShareAmount), aliceUnderlyingAmount); - assertEq(vault.previewDeposit(aliceUnderlyingAmount), aliceShareAmount); - assertEq(vault.totalSupply(), aliceShareAmount); - assertEq(vault.totalAssets(), aliceUnderlyingAmount); - assertEq(vault.balanceOf(alice), aliceShareAmount); - assertEq(vault.convertToAssets(aliceShareAmount), aliceUnderlyingAmount); - assertEq(underlying.balanceOf(alice), alicePreDepositBal - aliceUnderlyingAmount); - } - - vm.prank(alice); - vault.withdraw(aliceUnderlyingAmount, alice, alice); - - assertEq(vault.beforeWithdrawHookCalledCounter(), 1); - - assertEq(vault.totalAssets(), 0); - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 0); - assertEq(underlying.balanceOf(alice), alicePreDepositBal); - } - - function testSingleMintRedeem(uint128 amount) public { - if (amount == 0) amount = 1; - - uint256 aliceShareAmount = amount; - - address alice = address(0xABCD); - - underlying.mint(alice, aliceShareAmount); - - vm.prank(alice); - underlying.approve(address(vault), aliceShareAmount); - assertEq(underlying.allowance(alice, address(vault)), aliceShareAmount); - - uint256 alicePreDepositBal = underlying.balanceOf(alice); - - vm.prank(alice); - uint256 aliceUnderlyingAmount = vault.mint(aliceShareAmount, alice); - - assertEq(vault.afterDepositHookCalledCounter(), 1); - - // Expect exchange rate to be 1:1 on initial mint. - unchecked { - assertEq(aliceShareAmount, aliceUnderlyingAmount); - assertEq(vault.previewWithdraw(aliceShareAmount), aliceUnderlyingAmount); - assertEq(vault.previewDeposit(aliceUnderlyingAmount), aliceShareAmount); - assertEq(vault.totalSupply(), aliceShareAmount); - assertEq(vault.totalAssets(), aliceUnderlyingAmount); - assertEq(vault.balanceOf(alice), aliceUnderlyingAmount); - assertEq(vault.convertToAssets(aliceUnderlyingAmount), aliceUnderlyingAmount); - assertEq(underlying.balanceOf(alice), alicePreDepositBal - aliceUnderlyingAmount); - } - - vm.prank(alice); - vault.redeem(aliceShareAmount, alice, alice); - - assertEq(vault.beforeWithdrawHookCalledCounter(), 1); - - assertEq(vault.totalAssets(), 0); - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 0); - assertEq(underlying.balanceOf(alice), alicePreDepositBal); - } - - function testMultipleMintDepositRedeemWithdraw() public { - _testMultipleMintDepositRedeemWithdraw(0); - } - - function testVirtualSharesMultipleMintDepositRedeemWithdraw() public { - _replaceWithVirtualSharesVault(); - _testMultipleMintDepositRedeemWithdraw(1); - } - - struct _TestTemps { - uint256 slippage; - address alice; - address bob; - uint256 mutationUnderlyingAmount; - uint256 aliceUnderlyingAmount; - uint256 aliceShareAmount; - uint256 bobShareAmount; - uint256 bobUnderlyingAmount; - uint256 preMutationShareBal; - uint256 preMutationBal; - } - - function _testMultipleMintDepositRedeemWithdraw(uint256 slippage) public { - // Scenario: - // A = Alice, B = Bob - // ________________________________________________________ - // | Vault shares | A share | A assets | B share | B assets | - // |::::::::::::::::::::::::::::::::::::::::::::::::::::::::| - // | 1. Alice mints 2000 shares (costs 2000 tokens) | - // |--------------|---------|----------|---------|----------| - // | 2000 | 2000 | 2000 | 0 | 0 | - // |--------------|---------|----------|---------|----------| - // | 2. Bob deposits 4000 tokens (mints 4000 shares) | - // |--------------|---------|----------|---------|----------| - // | 6000 | 2000 | 2000 | 4000 | 4000 | - // |--------------|---------|----------|---------|----------| - // | 3. Vault mutates by +3000 tokens... | - // | (simulated yield returned from strategy)... | - // |--------------|---------|----------|---------|----------| - // | 6000 | 2000 | 3000 | 4000 | 6000 | - // |--------------|---------|----------|---------|----------| - // | 4. Alice deposits 2000 tokens (mints 1333 shares) | - // |--------------|---------|----------|---------|----------| - // | 7333 | 3333 | 4999 | 4000 | 6000 | - // |--------------|---------|----------|---------|----------| - // | 5. Bob mints 2000 shares (costs 3001 assets) | - // | NOTE: Bob's assets spent got rounded up | - // | NOTE: Alice's vault assets got rounded up | - // |--------------|---------|----------|---------|----------| - // | 9333 | 3333 | 5000 | 6000 | 9000 | - // |--------------|---------|----------|---------|----------| - // | 6. Vault mutates by +3000 tokens... | - // | (simulated yield returned from strategy) | - // | NOTE: Vault holds 17001 tokens, but sum of | - // | assetsOf() is 17000. | - // |--------------|---------|----------|---------|----------| - // | 9333 | 3333 | 6071 | 6000 | 10929 | - // |--------------|---------|----------|---------|----------| - // | 7. Alice redeem 1333 shares (2428 assets) | - // |--------------|---------|----------|---------|----------| - // | 8000 | 2000 | 3643 | 6000 | 10929 | - // |--------------|---------|----------|---------|----------| - // | 8. Bob withdraws 2928 assets (1608 shares) | - // |--------------|---------|----------|---------|----------| - // | 6392 | 2000 | 3643 | 4392 | 8000 | - // |--------------|---------|----------|---------|----------| - // | 9. Alice withdraws 3643 assets (2000 shares) | - // | NOTE: Bob's assets have been rounded back up | - // |--------------|---------|----------|---------|----------| - // | 4392 | 0 | 0 | 4392 | 8001 | - // |--------------|---------|----------|---------|----------| - // | 10. Bob redeem 4392 shares (8001 tokens) | - // |--------------|---------|----------|---------|----------| - // | 0 | 0 | 0 | 0 | 0 | - // |______________|_________|__________|_________|__________| - - _TestTemps memory t; - t.slippage = slippage; - t.alice = address(0x9988776655443322110000112233445566778899); - t.bob = address(0x1122334455667788990000998877665544332211); - - t.mutationUnderlyingAmount = 3000; - - underlying.mint(t.alice, 4000); - - vm.prank(t.alice); - underlying.approve(address(vault), 4000); - - assertEq(underlying.allowance(t.alice, address(vault)), 4000); - - underlying.mint(t.bob, 7001); - - vm.prank(t.bob); - underlying.approve(address(vault), 7001); - - assertEq(underlying.allowance(t.bob, address(vault)), 7001); - - _testMultipleMintDepositRedeemWithdraw1(t); - _testMultipleMintDepositRedeemWithdraw2(t); - _testMultipleMintDepositRedeemWithdraw3(t); - _testMultipleMintDepositRedeemWithdraw4(t); - _testMultipleMintDepositRedeemWithdraw5(t); - _testMultipleMintDepositRedeemWithdraw6(t); - _testMultipleMintDepositRedeemWithdraw7(t); - _testMultipleMintDepositRedeemWithdraw8(t); - _testMultipleMintDepositRedeemWithdraw9(t); - _testMultipleMintDepositRedeemWithdraw10(t); - } - - function _testMultipleMintDepositRedeemWithdraw1(_TestTemps memory t) internal { - // 1. Alice mints 2000 shares (costs 2000 tokens) - vm.prank(t.alice); - vm.expectEmit(true, true, true, true); - emit Deposit(t.alice, t.alice, 2000, 2000); - t.aliceUnderlyingAmount = vault.mint(2000, t.alice); - - t.aliceShareAmount = vault.previewDeposit(t.aliceUnderlyingAmount); - assertEq(vault.afterDepositHookCalledCounter(), 1); - - // Expect to have received the requested mint amount. - assertEq(t.aliceShareAmount, 2000); - assertEq(vault.balanceOf(t.alice), t.aliceShareAmount); - assertEq(vault.convertToAssets(t.aliceShareAmount), t.aliceUnderlyingAmount); - assertEq(vault.convertToShares(t.aliceUnderlyingAmount), t.aliceShareAmount); - - // Expect a 1:1 ratio before mutation. - assertEq(t.aliceUnderlyingAmount, 2000); - - // Sanity check. - assertEq(vault.totalSupply(), t.aliceShareAmount); - assertEq(vault.totalAssets(), t.aliceUnderlyingAmount); - } - - function _testMultipleMintDepositRedeemWithdraw2(_TestTemps memory t) internal { - // 2. Bob deposits 4000 tokens (mints 4000 shares) - unchecked { - vm.prank(t.bob); - vm.expectEmit(true, true, true, true); - emit Deposit(t.bob, t.bob, 4000, 4000); - t.bobShareAmount = vault.deposit(4000, t.bob); - t.bobUnderlyingAmount = vault.previewWithdraw(t.bobShareAmount); - assertEq(vault.afterDepositHookCalledCounter(), 2); - - // Expect to have received the requested underlying amount. - assertEq(t.bobUnderlyingAmount, 4000); - assertEq(vault.balanceOf(t.bob), t.bobShareAmount); - assertEq(vault.convertToAssets(t.bobShareAmount), t.bobUnderlyingAmount); - assertEq(vault.convertToShares(t.bobUnderlyingAmount), t.bobShareAmount); - - // Expect a 1:1 ratio before mutation. - assertEq(t.bobShareAmount, t.bobUnderlyingAmount); - - // Sanity check. - t.preMutationShareBal = t.aliceShareAmount + t.bobShareAmount; - t.preMutationBal = t.aliceUnderlyingAmount + t.bobUnderlyingAmount; - assertEq(vault.totalSupply(), t.preMutationShareBal); - assertEq(vault.totalAssets(), t.preMutationBal); - assertEq(vault.totalSupply(), 6000); - assertEq(vault.totalAssets(), 6000); - } - } - - function _testMultipleMintDepositRedeemWithdraw3(_TestTemps memory t) internal { - // 3. Vault mutates by +3000 tokens... | - // (simulated yield returned from strategy)... - // The Vault now contains more tokens than deposited which causes the exchange rate to change. - // Alice share is 33.33% of the Vault, Bob 66.66% of the Vault. - // Alice's share count stays the same but the underlying amount changes from 2000 to 3000. - // Bob's share count stays the same but the underlying amount changes from 4000 to 6000. - unchecked { - underlying.mint(address(vault), t.mutationUnderlyingAmount); - assertEq(vault.totalSupply(), t.preMutationShareBal); - assertEq(vault.totalAssets(), t.preMutationBal + t.mutationUnderlyingAmount); - assertEq(vault.balanceOf(t.alice), t.aliceShareAmount); - assertEq( - vault.convertToAssets(t.aliceShareAmount), - t.aliceUnderlyingAmount + (t.mutationUnderlyingAmount / 3) * 1 - t.slippage - ); - assertEq(vault.balanceOf(t.bob), t.bobShareAmount); - assertEq( - vault.convertToAssets(t.bobShareAmount), - t.bobUnderlyingAmount + (t.mutationUnderlyingAmount / 3) * 2 - t.slippage - ); - } - } - - function _testMultipleMintDepositRedeemWithdraw4(_TestTemps memory t) internal { - // 4. Alice deposits 2000 tokens (mints 1333 shares) - vm.prank(t.alice); - vault.deposit(2000, t.alice); - - assertEq(vault.totalSupply(), 7333); - assertEq(vault.balanceOf(t.alice), 3333); - assertEq(vault.convertToAssets(3333), 4999); - assertEq(vault.balanceOf(t.bob), 4000); - assertEq(vault.convertToAssets(4000), 6000); - } - - function _testMultipleMintDepositRedeemWithdraw5(_TestTemps memory t) internal { - // 5. Bob mints 2000 shares (costs 3001 assets) - // NOTE: Bob's assets spent got rounded up - // NOTE: Alices's vault assets got rounded up - unchecked { - vm.prank(t.bob); - vault.mint(2000, t.bob); - - assertEq(vault.totalSupply(), 9333); - assertEq(vault.balanceOf(t.alice), 3333); - assertEq(vault.convertToAssets(3333), 5000 - t.slippage); - assertEq(vault.balanceOf(t.bob), 6000); - assertEq(vault.convertToAssets(6000), 9000); - - // Sanity checks: - // Alice and t.bob should have spent all their tokens now - assertEq(underlying.balanceOf(t.alice), 0); - assertEq(underlying.balanceOf(t.bob) - t.slippage, 0); - // Assets in vault: 4k (t.alice) + 7k (t.bob) + 3k (yield) + 1 (round up) - assertEq(vault.totalAssets(), 14001 - t.slippage); - } - } - - function _testMultipleMintDepositRedeemWithdraw6(_TestTemps memory t) internal { - // 6. Vault mutates by +3000 tokens - // NOTE: Vault holds 17001 tokens, but sum of assetsOf() is 17000. - unchecked { - underlying.mint(address(vault), t.mutationUnderlyingAmount); - assertEq(vault.convertToAssets(vault.balanceOf(t.alice)), 6071 - t.slippage); - assertEq(vault.convertToAssets(vault.balanceOf(t.bob)), 10929 - t.slippage); - assertEq(vault.totalSupply(), 9333); - assertEq(vault.totalAssets(), 17001 - t.slippage); - } - } - - function _testMultipleMintDepositRedeemWithdraw7(_TestTemps memory t) internal { - // 7. Alice redeem 1333 shares (2428 assets) - unchecked { - vm.prank(t.alice); - vault.redeem(1333, t.alice, t.alice); - - assertEq(underlying.balanceOf(t.alice), 2428 - t.slippage); - assertEq(vault.totalSupply(), 8000); - assertEq(vault.totalAssets(), 14573); - assertEq(vault.balanceOf(t.alice), 2000); - assertEq(vault.convertToAssets(2000), 3643); - assertEq(vault.balanceOf(t.bob), 6000); - assertEq(vault.convertToAssets(6000), 10929); - } - } - - function _testMultipleMintDepositRedeemWithdraw8(_TestTemps memory t) internal { - // 8. Bob withdraws 2929 assets (1608 shares) - unchecked { - vm.prank(t.bob); - vault.withdraw(2929, t.bob, t.bob); - - assertEq(underlying.balanceOf(t.bob) - t.slippage, 2929); - assertEq(vault.totalSupply(), 6392); - assertEq(vault.totalAssets(), 11644); - assertEq(vault.balanceOf(t.alice), 2000); - assertEq(vault.convertToAssets(2000), 3643); - assertEq(vault.balanceOf(t.bob), 4392); - assertEq(vault.convertToAssets(4392), 8000); - } - } - - function _testMultipleMintDepositRedeemWithdraw9(_TestTemps memory t) internal { - // 9. Alice withdraws 3643 assets (2000 shares) - // NOTE: Bob's assets have been rounded back up - unchecked { - vm.prank(t.alice); - vm.expectEmit(true, true, true, true); - emit Withdraw(t.alice, t.alice, t.alice, 3643, 2000); - vault.withdraw(3643, t.alice, t.alice); - assertEq(underlying.balanceOf(t.alice), 6071 - t.slippage); - assertEq(vault.totalSupply(), 4392); - assertEq(vault.totalAssets(), 8001); - assertEq(vault.balanceOf(t.alice), 0); - assertEq(vault.convertToAssets(0), 0); - assertEq(vault.balanceOf(t.bob), 4392); - assertEq(vault.convertToAssets(4392), 8001 - t.slippage); - } - } - - function _testMultipleMintDepositRedeemWithdraw10(_TestTemps memory t) internal { - // 10. Bob redeem 4392 shares (8001 tokens) - unchecked { - vm.prank(t.bob); - vm.expectEmit(true, true, true, true); - emit Withdraw(t.bob, t.bob, t.bob, 8001 - t.slippage, 4392); - vault.redeem(4392, t.bob, t.bob); - assertEq(underlying.balanceOf(t.bob), 10930); - assertEq(vault.totalSupply(), 0); - assertEq(vault.totalAssets() - t.slippage, 0); - assertEq(vault.balanceOf(t.alice), 0); - assertEq(vault.convertToAssets(0), 0); - assertEq(vault.balanceOf(t.bob), 0); - assertEq(vault.convertToAssets(0), 0); - - // Sanity check - assertEq(underlying.balanceOf(address(vault)) - t.slippage, 0); - } - } - - function testDepositWithNotEnoughApprovalReverts() public { - underlying.mint(address(this), 0.5e18); - underlying.approve(address(vault), 0.5e18); - assertEq(underlying.allowance(address(this), address(vault)), 0.5e18); - - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - vault.deposit(1e18, address(this)); - } - - function testWithdrawWithNotEnoughUnderlyingAmountReverts() public { - underlying.mint(address(this), 0.5e18); - underlying.approve(address(vault), 0.5e18); - - vault.deposit(0.5e18, address(this)); - - vm.expectRevert(ERC4626.WithdrawMoreThanMax.selector); - vault.withdraw(1e18, address(this), address(this)); - } - - function testRedeemWithNotEnoughShareAmountReverts() public { - underlying.mint(address(this), 0.5e18); - underlying.approve(address(vault), 0.5e18); - - vault.deposit(0.5e18, address(this)); - - vm.expectRevert(ERC4626.RedeemMoreThanMax.selector); - vault.redeem(1e18, address(this), address(this)); - } - - function testWithdrawWithNoUnderlyingAmountReverts() public { - vm.expectRevert(ERC4626.WithdrawMoreThanMax.selector); - vault.withdraw(1e18, address(this), address(this)); - } - - function testRedeemWithNoShareAmountReverts() public { - vm.expectRevert(ERC4626.RedeemMoreThanMax.selector); - vault.redeem(1e18, address(this), address(this)); - } - - function testDepositWithNoApprovalReverts() public { - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - vault.deposit(1e18, address(this)); - } - - function testMintWithNoApprovalReverts() public { - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - vault.mint(1e18, address(this)); - } - - function testMintZero() public { - vault.mint(0, address(this)); - - assertEq(vault.balanceOf(address(this)), 0); - assertEq(vault.convertToAssets(0), 0); - assertEq(vault.totalSupply(), 0); - assertEq(vault.totalAssets(), 0); - } - - function testWithdrawZero() public { - vault.withdraw(0, address(this), address(this)); - - assertEq(vault.balanceOf(address(this)), 0); - assertEq(vault.convertToAssets(0), 0); - assertEq(vault.totalSupply(), 0); - assertEq(vault.totalAssets(), 0); - } - - function testVaultInteractionsForSomeoneElse() public { - // init 2 users with a 1e18 balance - address alice = address(0xABCD); - address bob = address(0xDCBA); - underlying.mint(alice, 1e18); - underlying.mint(bob, 1e18); - - vm.prank(alice); - underlying.approve(address(vault), 1e18); - - vm.prank(bob); - underlying.approve(address(vault), 1e18); - - // alice deposits 1e18 for bob - vm.prank(alice); - vm.expectEmit(true, true, true, true); - emit Deposit(alice, bob, 1e18, 1e18); - vault.deposit(1e18, bob); - - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.balanceOf(bob), 1e18); - assertEq(underlying.balanceOf(alice), 0); - - // bob mint 1e18 for alice - vm.prank(bob); - vm.expectEmit(true, true, true, true); - emit Deposit(bob, alice, 1e18, 1e18); - vault.mint(1e18, alice); - assertEq(vault.balanceOf(alice), 1e18); - assertEq(vault.balanceOf(bob), 1e18); - assertEq(underlying.balanceOf(bob), 0); - - // alice redeem 1e18 for bob - vm.prank(alice); - vm.expectEmit(true, true, true, true); - emit Withdraw(alice, bob, alice, 1e18, 1e18); - vault.redeem(1e18, bob, alice); - - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.balanceOf(bob), 1e18); - assertEq(underlying.balanceOf(bob), 1e18); - - // bob withdraw 1e18 for alice - vm.prank(bob); - vm.expectEmit(true, true, true, true); - emit Withdraw(bob, alice, bob, 1e18, 1e18); - vault.withdraw(1e18, alice, bob); - - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.balanceOf(bob), 0); - assertEq(underlying.balanceOf(alice), 1e18); - } -} diff --git a/grouperBot/lib/solady/test/ERC6551.t.sol b/grouperBot/lib/solady/test/ERC6551.t.sol deleted file mode 100644 index 5160567..0000000 --- a/grouperBot/lib/solady/test/ERC6551.t.sol +++ /dev/null @@ -1,470 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {SignatureCheckerLib} from "../src/utils/SignatureCheckerLib.sol"; -import {ERC6551Proxy} from "../src/accounts/ERC6551Proxy.sol"; -import {EIP712} from "../src/utils/EIP712.sol"; -import {CallContextChecker} from "../src/utils/CallContextChecker.sol"; -import {ERC6551, MockERC6551, MockERC6551V2} from "./utils/mocks/MockERC6551.sol"; -import {MockERC6551Registry} from "./utils/mocks/MockERC6551Registry.sol"; -import {MockERC721} from "./utils/mocks/MockERC721.sol"; -import {MockERC1155} from "./utils/mocks/MockERC1155.sol"; -import {LibZip} from "../src/utils/LibZip.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract Target { - error TargetError(bytes data); - - bytes32 public datahash; - - bytes public data; - - function setData(bytes memory data_) public payable returns (bytes memory) { - data = data_; - datahash = keccak256(data_); - return data_; - } - - function revertWithTargetError(bytes memory data_) public payable { - revert TargetError(data_); - } -} - -contract ERC6551Test is SoladyTest { - MockERC6551Registry internal _registry; - - address internal _erc6551; - - address internal _erc6551V2; - - address internal _erc721; - - address internal _proxy; - - // By right, this should be the keccak256 of some long-ass string: - // (e.g. `keccak256("Parent(bytes32 childHash,Mail child)Mail(Person from,Person to,string contents)Person(string name,address wallet)")`). - // But I'm lazy and will use something randomish here. - bytes32 internal constant _PARENT_TYPEHASH = - 0xd61db970ec8a2edc5f9fd31d876abe01b785909acb16dcd4baaf3b434b4c439b; - - // By right, this should be a proper domain separator, but I'm lazy. - bytes32 internal constant _DOMAIN_SEP_B = - 0xa1a044077d7677adbbfa892ded5390979b33993e0e2a457e3f974bbcda53821b; - - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - struct _TestTemps { - address owner; - uint256 chainId; - uint256 tokenId; - bytes32 salt; - MockERC6551 account; - address signer; - uint256 privateKey; - uint8 v; - bytes32 r; - bytes32 s; - } - - function setUp() public { - _registry = new MockERC6551Registry(); - _erc6551 = address(new MockERC6551()); - _erc721 = address(new MockERC721()); - _proxy = address(new ERC6551Proxy(_erc6551)); - _erc6551V2 = address(new MockERC6551V2()); - } - - function testBaseFeeMini() public { - vm.fee(11); - - bytes memory initcode = hex"65483d52593df33d526006601af3"; - emit LogBytes32(keccak256(initcode)); - uint256 result; - /// @solidity memory-safe-assembly - assembly { - let deployed := create(0, add(initcode, 0x20), mload(initcode)) - if iszero(staticcall(gas(), deployed, 0x00, 0x00, 0x00, 0x20)) { invalid() } - if iszero(eq(returndatasize(), 0x20)) { invalid() } - result := mload(0x00) - } - emit LogUint("basefee", result); - } - - function _testTempsMint(address owner) internal returns (uint256 tokenId) { - while (true) { - tokenId = _randomChance(8) ? _random() % 32 : _random(); - (bool success,) = - _erc721.call(abi.encodeWithSignature("mint(address,uint256)", owner, tokenId)); - if (success) return tokenId; - } - } - - function _testTemps() internal returns (_TestTemps memory t) { - t.owner = _randomNonZeroAddress(); - t.tokenId = _testTempsMint(t.owner); - t.chainId = block.chainid; - t.salt = bytes32(_random()); - address account = _registry.createAccount(_proxy, t.salt, t.chainId, _erc721, t.tokenId); - t.account = MockERC6551(payable(account)); - } - - function testDeployERC6551Proxy() public { - emit LogBytes("ERC6551Proxy code", address(new ERC6551Proxy(_erc6551)).code); - } - - function testInitializeERC6551ProxyImplementation() public { - address account = address(_testTemps().account); - (bool success,) = account.call(""); - assertTrue(success); - bytes32 implementationSlotValue = bytes32(uint256(uint160(_erc6551))); - assertEq(vm.load(account, _ERC1967_IMPLEMENTATION_SLOT), implementationSlotValue); - } - - function testDeployERC6551(uint256) public { - _TestTemps memory t = _testTemps(); - (uint256 chainId, address tokenContract, uint256 tokenId) = t.account.token(); - assertEq(chainId, t.chainId); - assertEq(tokenContract, _erc721); - assertEq(tokenId, t.tokenId); - address owner = t.account.owner(); - assertEq(owner, t.owner); - if (_randomChance(8)) { - vm.prank(owner); - address newOwner = _randomNonZeroAddress(); - MockERC721(_erc721).transferFrom(owner, newOwner, t.tokenId); - assertEq(t.account.owner(), newOwner); - } - } - - function testOwnerWorksWithChainIdChange(uint256 oldChainId, uint256 newChainId) public { - oldChainId = _bound(oldChainId, 0, 2 ** 64 - 1); - newChainId = _bound(newChainId, 0, 2 ** 64 - 1); - vm.chainId(oldChainId); - _erc6551 = address(new MockERC6551()); - _proxy = address(new ERC6551Proxy(_erc6551)); - _TestTemps memory t = _testTemps(); - assertEq(t.account.owner(), t.owner); - vm.chainId(newChainId); - assertEq(t.account.owner(), t.owner); - } - - function testOnERC721ReceivedCycles() public { - unchecked { - uint256 n = 8; - _TestTemps[] memory t = new _TestTemps[](n); - for (uint256 i; i != n; ++i) { - t[i] = _testTemps(); - if (i != 0) { - vm.prank(t[i].owner); - MockERC721(_erc721).safeTransferFrom( - t[i].owner, address(t[i - 1].account), t[i].tokenId - ); - t[i].owner = address(t[i - 1].account); - } - } - for (uint256 i; i != n; ++i) { - for (uint256 j = i; j != n; ++j) { - vm.prank(t[i].owner); - vm.expectRevert(ERC6551.SelfOwnDetected.selector); - MockERC721(_erc721).safeTransferFrom( - t[i].owner, address(t[j].account), t[i].tokenId - ); - } - for (uint256 j; j != i; ++j) { - vm.prank(t[i].owner); - MockERC721(_erc721).safeTransferFrom( - t[i].owner, address(t[j].account), t[i].tokenId - ); - vm.prank(address(t[j].account)); - MockERC721(_erc721).safeTransferFrom( - address(t[j].account), t[i].owner, t[i].tokenId - ); - } - } - - _TestTemps memory u = _testTemps(); - vm.prank(u.owner); - MockERC721(_erc721).safeTransferFrom(u.owner, address(t[n - 1].account), u.tokenId); - } - } - - function testOnERC721ReceivedCyclesWithDifferentChainIds(uint256) public { - _TestTemps[] memory t = new _TestTemps[](3); - unchecked { - for (uint256 i; i != 3; ++i) { - vm.chainId(i); - t[i] = _testTemps(); - if (i != 0) { - vm.prank(t[i].owner); - MockERC721(_erc721).safeTransferFrom( - t[i].owner, address(t[i - 1].account), t[i].tokenId - ); - t[i].owner = address(t[i - 1].account); - } - } - } - unchecked { - vm.chainId(_random() % 3); - uint256 i = _random() % 3; - uint256 j = _random() % 3; - while (j == i) j = _random() % 3; - vm.prank(t[i].owner); - MockERC721(_erc721).safeTransferFrom(t[i].owner, address(t[j].account), t[i].tokenId); - } - } - - function testOnERC721Received() public { - _TestTemps memory t = _testTemps(); - address alice = _randomNonZeroAddress(); - MockERC721 erc721 = new MockERC721(); - erc721.mint(alice, 1); - vm.prank(alice); - if (alice != address(t.account)) { - erc721.safeTransferFrom(alice, address(t.account), 1); - } - } - - function testOnERC1155Received() public { - _TestTemps memory t = _testTemps(); - address alice = _randomNonZeroAddress(); - MockERC1155 erc1155 = new MockERC1155(); - erc1155.mint(alice, 1, 1, ""); - vm.prank(alice); - erc1155.safeTransferFrom(alice, address(t.account), 1, 1, ""); - } - - function testOnERC1155BatchReceived() public { - _TestTemps memory t = _testTemps(); - address alice = _randomNonZeroAddress(); - MockERC1155 erc1155 = new MockERC1155(); - erc1155.mint(alice, 1, 1, ""); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amts = new uint256[](1); - amts[0] = 1; - vm.prank(alice); - erc1155.safeBatchTransferFrom(alice, address(t.account), ids, amts, ""); - } - - function testExecute() public { - _TestTemps memory t = _testTemps(); - vm.deal(address(t.account), 1 ether); - - address target = address(new Target()); - bytes memory data = _randomBytes(111); - - assertEq(t.account.state(), bytes32(0)); - - vm.prank(t.owner); - t.account.execute(target, 123, abi.encodeWithSignature("setData(bytes)", data), 0); - assertEq(Target(target).datahash(), keccak256(data)); - assertEq(target.balance, 123); - - vm.prank(_randomNonZeroAddress()); - vm.expectRevert(ERC6551.Unauthorized.selector); - t.account.execute(target, 123, abi.encodeWithSignature("setData(bytes)", data), 0); - - vm.prank(t.owner); - vm.expectRevert(abi.encodeWithSignature("TargetError(bytes)", data)); - t.account.execute( - target, 123, abi.encodeWithSignature("revertWithTargetError(bytes)", data), 0 - ); - - vm.prank(t.owner); - vm.expectRevert(ERC6551.OperationNotSupported.selector); - t.account.execute( - target, 123, abi.encodeWithSignature("revertWithTargetError(bytes)", data), 1 - ); - } - - function testExecuteBatch() public { - _TestTemps memory t = _testTemps(); - vm.deal(address(t.account), 1 ether); - - ERC6551.Call[] memory calls = new ERC6551.Call[](2); - calls[0].target = address(new Target()); - calls[1].target = address(new Target()); - calls[0].value = 123; - calls[1].value = 456; - calls[0].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(111)); - calls[1].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(222)); - - assertEq(t.account.state(), bytes32(0)); - - vm.prank(t.owner); - t.account.executeBatch(calls, 0); - assertEq(Target(calls[0].target).datahash(), keccak256(_randomBytes(111))); - assertEq(Target(calls[1].target).datahash(), keccak256(_randomBytes(222))); - assertEq(calls[0].target.balance, 123); - assertEq(calls[1].target.balance, 456); - - calls[1].data = abi.encodeWithSignature("revertWithTargetError(bytes)", _randomBytes(111)); - vm.expectRevert(abi.encodeWithSignature("TargetError(bytes)", _randomBytes(111))); - vm.prank(t.owner); - t.account.executeBatch(calls, 0); - - vm.prank(t.owner); - vm.expectRevert(ERC6551.OperationNotSupported.selector); - t.account.executeBatch(calls, 1); - } - - function testExecuteBatch(uint256 r) public { - _TestTemps memory t = _testTemps(); - vm.deal(address(t.account), 1 ether); - - assertEq(t.account.state(), bytes32(0)); - - unchecked { - uint256 n = r & 3; - ERC6551.Call[] memory calls = new ERC6551.Call[](n); - - for (uint256 i; i != n; ++i) { - uint256 v = _random() & 0xff; - calls[i].target = address(new Target()); - calls[i].value = v; - calls[i].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(v)); - } - - bytes[] memory results; - if (_random() & 1 == 0) { - vm.prank(t.owner); - results = t.account.executeBatch(_random(), calls, 0); - } else { - vm.prank(t.owner); - results = t.account.executeBatch(calls, 0); - } - - assertEq(results.length, n); - for (uint256 i; i != n; ++i) { - uint256 v = calls[i].value; - assertEq(Target(calls[i].target).datahash(), keccak256(_randomBytes(v))); - assertEq(calls[i].target.balance, v); - assertEq(abi.decode(results[i], (bytes)), _randomBytes(v)); - } - } - } - - function testUpgrade() public { - _TestTemps memory t = _testTemps(); - vm.expectRevert(ERC6551.Unauthorized.selector); - t.account.upgradeToAndCall(_erc6551V2, bytes("")); - bytes32 state; - assertEq(t.account.state(), state); - assertEq(t.account.mockId(), "1"); - - vm.prank(t.owner); - bytes memory data = - abi.encodeWithSignature("upgradeToAndCall(address,bytes)", _erc6551V2, ""); - (bool success,) = address(t.account).call(data); - assertTrue(success); - assertEq(t.account.mockId(), "2"); - state = keccak256(abi.encode(state, data)); - assertEq(t.account.state(), state); - - vm.prank(t.owner); - data = abi.encodeWithSignature("upgradeToAndCall(address,bytes)", _erc6551, ""); - (success,) = address(t.account).call(data); - assertTrue(success); - assertEq(t.account.mockId(), "1"); - state = keccak256(abi.encode(state, data)); - assertEq(t.account.state(), state); - } - - function testUpgradeRevertsIfNotViaERC6551Proxy() public { - _TestTemps memory t = _testTemps(); - address account = _registry.createAccount(_erc6551, t.salt, t.chainId, _erc721, t.tokenId); - t.account = MockERC6551(payable(account)); - - vm.prank(t.owner); - vm.expectRevert(CallContextChecker.UnauthorizedCallContext.selector); - t.account.upgradeToAndCall(_erc6551V2, bytes("")); - } - - function testSupportsInterface() public { - _TestTemps memory t = _testTemps(); - assertTrue(t.account.supportsInterface(0x01ffc9a7)); - assertTrue(t.account.supportsInterface(0x6faff5f1)); - assertTrue(t.account.supportsInterface(0x51945447)); - assertFalse(t.account.supportsInterface(0x00000001)); - } - - function testCdFallback() public { - _TestTemps memory t = _testTemps(); - vm.deal(t.owner, 1 ether); - - ERC6551.Call[] memory calls = new ERC6551.Call[](2); - calls[0].target = address(new Target()); - calls[1].target = address(new Target()); - calls[0].value = 123; - calls[1].value = 456; - calls[0].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(111)); - calls[1].data = abi.encodeWithSignature("setData(bytes)", _randomBytes(222)); - - bytes memory data = LibZip.cdCompress( - abi.encodeWithSignature("executeBatch((address,uint256,bytes)[],uint8)", calls, 0) - ); - vm.prank(t.owner); - (bool success,) = address(t.account).call{value: 1 ether}(data); - assertTrue(success); - assertEq(Target(calls[0].target).datahash(), keccak256(_randomBytes(111))); - assertEq(Target(calls[1].target).datahash(), keccak256(_randomBytes(222))); - assertEq(calls[0].target.balance, 123); - assertEq(calls[1].target.balance, 456); - } - - function testIsValidSigner(address signer) public { - _TestTemps memory t = _testTemps(); - if (signer == t.owner) { - assertEq(t.account.isValidSigner(signer, _randomBytes(111)), bytes4(0x523e3260)); - } else { - assertEq(t.account.isValidSigner(signer, _randomBytes(111)), bytes4(0x00000000)); - } - } - - function _randomBytes(uint256 seed) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, seed) - let r := keccak256(0x00, 0x20) - if lt(byte(2, r), 0x20) { - result := mload(0x40) - let n := and(r, 0x7f) - mstore(result, n) - codecopy(add(result, 0x20), byte(1, r), add(n, 0x40)) - mstore(0x40, add(add(result, 0x40), n)) - } - } - } - - function testUpdateState(uint256 seed) public { - bytes[] memory data = new bytes[](2); - if (!_randomChance(8)) data[0] = _randomBytes(seed); - if (!_randomChance(8)) data[1] = _randomBytes(~seed); - - bytes32[] memory statesA = new bytes32[](2); - bytes32[] memory statesB = new bytes32[](2); - - _TestTemps memory t = _testTemps(); - - t.account.somethingThatUpdatesState(data[0]); - statesA[0] = t.account.state(); - t.account.somethingThatUpdatesState(data[1]); - statesA[1] = t.account.state(); - - vm.prank(t.owner); - t.account.upgradeToAndCall(_erc6551V2, ""); - - t.account.clearState(); - - t.account.somethingThatUpdatesState(data[0]); - statesB[0] = t.account.state(); - t.account.somethingThatUpdatesState(data[1]); - statesB[1] = t.account.state(); - - assertEq(statesA, statesB); - assertTrue(statesA[0] != statesA[1]); - } -} diff --git a/grouperBot/lib/solady/test/ERC6909.t.sol b/grouperBot/lib/solady/test/ERC6909.t.sol deleted file mode 100644 index 36d695a..0000000 --- a/grouperBot/lib/solady/test/ERC6909.t.sol +++ /dev/null @@ -1,544 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; - -import {ERC6909, MockERC6909} from "./utils/mocks/MockERC6909.sol"; - -contract ERC6909Test is SoladyTest { - MockERC6909 token; - - event Transfer( - address by, address indexed from, address indexed to, uint256 indexed id, uint256 amount - ); - - event OperatorSet(address indexed owner, address indexed spender, bool approved); - - event Approval( - address indexed owner, address indexed spender, uint256 indexed id, uint256 amount - ); - - function setUp() public { - token = new MockERC6909(); - } - - function testMetadata(uint256 id) public { - assertEq(token.name(id), "Solady Token"); - assertEq(token.symbol(id), "ST"); - } - - function testMint() public { - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), address(0), address(0xBEEF), 1, 1e18); - - token.mint(address(0xBEEF), 1, 1e18); - assertEq(token.balanceOf(address(0xBEEF), 1), 1e18); - } - - function testDecimals() public { - assertEq(token.decimals(1), 18); - } - - function testBurn() public { - token.mint(address(0xBEEF), 1, 1e18); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), address(0xBEEF), address(0), 1, 0.9e18); - token.burn(address(0xBEEF), 1, 0.9e18); - - assertEq(token.balanceOf(address(0xBEEF), 1), 0.1e18); - } - - function testApprove() public { - vm.expectEmit(true, true, true, true); - emit Approval(address(this), address(0xBEEF), 1, 1e18); - assertTrue(token.approve(address(0xBEEF), 1, 1e18)); - - assertEq(token.allowance(address(this), address(0xBEEF), 1), 1e18); - } - - function testTransfer() public { - token.mint(address(this), 1, 1e18); - - assertEq(token.balanceOf(address(this), 1), 1e18); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), address(this), address(0xBEEF), 1, 1e18); - assertTrue(token.transfer(address(0xBEEF), 1, 1e18)); - assertEq(token.balanceOf(address(this), 1), 0); - assertEq(token.balanceOf(address(0xBEEF), 1), 1e18); - } - - function testTransferFrom() public { - address from = address(0xABCD); - - token.mint(from, 1, 1e18); - - _approve(from, address(this), 1, 1e18); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), from, address(0xBEEF), 1, 1e18); - assertTrue(token.transferFrom(from, address(0xBEEF), 1, 1e18)); - - assertEq(token.allowance(from, address(this), 1), 0); - - assertEq(token.balanceOf(from, 1), 0); - assertEq(token.balanceOf(address(0xBEEF), 1), 1e18); - } - - function testInfiniteApproveTransferFrom() public { - address from = address(0xABCD); - - token.mint(from, 1, 1e18); - - _approve(from, address(this), 1, type(uint256).max); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), from, address(0xBEEF), 1, 1e18); - assertTrue(token.transferFrom(from, address(0xBEEF), 1, 1e18)); - - assertEq(token.allowance(from, address(this), 1), type(uint256).max); - - assertEq(token.balanceOf(from, 1), 0); - assertEq(token.balanceOf(address(0xBEEF), 1), 1e18); - } - - function testOperatorTransferFrom() public { - address from = address(0xABcD); - - token.mint(from, 1, 1e18); - - _setOperator(from, address(this), true); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), from, address(0xBEEF), 1, 1e18); - assertTrue(token.transferFrom(from, address(0xBEEF), 1, 1e18)); - - assertEq(token.balanceOf(from, 1), 0); - assertEq(token.balanceOf(address(0xBEEF), 1), 1e18); - } - - function testSetOperator() public { - assertEq(token.isOperator(address(this), address(0xBEEF)), false); - - vm.expectEmit(true, true, true, true); - emit OperatorSet(address(this), address(0xBEEF), true); - token.setOperator(address(0xBEEF), true); - assertEq(token.isOperator(address(this), address(0xBEEF)), true); - } - - function testTokenURI() public { - token.mint(address(0xBEEF), 1, 1e18); - assertEq(token.tokenURI(1), "http://solady.org/1"); - } - - function testMintOverMaxUintReverts() public { - token.mint(address(this), 1, type(uint256).max); - vm.expectRevert(ERC6909.BalanceOverflow.selector); - token.mint(address(this), 1, 1); - } - - function testTransferOverMaxUintReverts() public { - token.mint(address(this), 1, type(uint256).max); - token.transfer(address(0xBEEF), 1, type(uint256).max); - token.mint(address(this), 1, 1); - vm.expectRevert(ERC6909.BalanceOverflow.selector); - token.transfer(address(0xBEEF), 1, 1); - } - - function testTransferFromOverMaxUintReverts() public { - address from = address(0xABCD); - - _approve(from, address(this), 1, type(uint256).max); - - token.mint(from, 1, type(uint256).max); - token.transferFrom(from, address(0xBEEF), 1, type(uint256).max); - - token.mint(from, 1, 1); - vm.expectRevert(ERC6909.BalanceOverflow.selector); - token.transferFrom(from, address(0xBEEF), 1, 1); - } - - function testTransferInsufficientBalanceReverts() public { - token.mint(address(this), 1, 0.9e18); - _expectInsufficientBalanceRevert(); - token.transfer(address(0xBEEF), 1, 1e18); - } - - function testTransferFromInsufficientPermission() public { - address from = address(0xABCD); - - token.mint(from, 1, 1e18); - - _approve(from, address(this), 1, 0.9e18); - - _expectInsufficientPermissionRevert(); - token.transferFrom(from, address(0xBEEF), 1, 1e18); - } - - function testTransferFromInsufficientBalanceReverts() public { - address from = address(0xABCD); - - token.mint(from, 1, 0.9e18); - - _approve(from, address(this), 1, 1e18); - - _expectInsufficientBalanceRevert(); - token.transferFrom(from, address(0xBEEF), 1, 1e18); - } - - function testMint(address to, uint256 id, uint256 amount) public { - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), address(0), to, id, amount); - token.mint(to, id, amount); - - assertEq(token.balanceOf(to, id), amount); - } - - function testBurn(address from, uint256 id, uint256 mintAmount, uint256 burnAmount) public { - burnAmount = _bound(burnAmount, 0, mintAmount); - - token.mint(from, id, mintAmount); - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), from, address(0), id, burnAmount); - token.burn(from, id, burnAmount); - - assertEq(token.balanceOf(from, id), mintAmount - burnAmount); - } - - function testApprove(address to, uint256 id, uint256 amount) public { - _approve(address(this), to, id, amount); - } - - function testTransfer(address to, uint256 id, uint256 amount) public { - token.mint(address(this), id, amount); - - vm.expectEmit(true, true, true, true); - emit Transfer(address(this), address(this), to, id, amount); - assertTrue(token.transfer(to, id, amount)); - - if (address(this) == to) { - assertEq(token.balanceOf(address(this), id), amount); - } else { - assertEq(token.balanceOf(address(this), id), 0); - assertEq(token.balanceOf(to, id), amount); - } - } - - function testTransferFrom( - address spender, - address from, - address to, - uint256 id, - uint256 approval, - uint256 amount - ) public { - amount = _bound(amount, 0, approval); - - token.mint(from, id, amount); - assertEq(token.balanceOf(from, id), amount); - - _approve(from, spender, id, approval); - - vm.expectEmit(true, true, true, true); - emit Transfer(spender, from, to, id, amount); - vm.prank(spender); - assertTrue(token.transferFrom(from, to, id, amount)); - - if (approval == type(uint256).max) { - assertEq(token.allowance(from, spender, id), approval); - } else { - assertEq(token.allowance(from, spender, id), approval - amount); - } - - if (from == to) { - assertEq(token.balanceOf(from, id), amount); - } else { - assertEq(token.balanceOf(from, id), 0); - assertEq(token.balanceOf(to, id), amount); - } - } - - function testSetOperator(address owner, address spender, bool approved) public { - _setOperator(owner, spender, approved); - } - - function testMintOverMaxUintReverts(address to, uint256 id, uint256 amount0, uint256 amount1) - public - { - amount0 = _bound(amount0, 1, type(uint256).max); - amount1 = _bound(amount1, type(uint256).max - amount0 + 1, type(uint256).max); - token.mint(to, id, amount0); - - vm.expectRevert(ERC6909.BalanceOverflow.selector); - token.mint(to, id, amount1); - } - - function testBurnInsufficientBalanceReverts( - address to, - uint256 mintAmount, - uint256 id, - uint256 burnAmount - ) public { - if (mintAmount == type(uint256).max) mintAmount--; - burnAmount = _bound(burnAmount, mintAmount + 1, type(uint256).max); - - token.mint(to, id, mintAmount); - - _expectInsufficientBalanceRevert(); - token.burn(to, id, burnAmount); - } - - function testTransferOverMaxUintReverts( - address to, - uint256 id, - uint256 amount0, - uint256 amount1 - ) public { - amount0 = _bound(amount0, 1, type(uint256).max); - amount1 = _bound(amount1, type(uint256).max - amount0 + 1, type(uint256).max); - - token.mint(address(this), id, amount0); - if (to == address(this) && amount1 > type(uint256).max - amount0) { - to = address(uint160(to) ^ 1); - } - token.transfer(to, id, amount0); - token.mint(address(this), id, amount1); - - vm.expectRevert(ERC6909.BalanceOverflow.selector); - token.transfer(to, id, amount1); - } - - function testTransferInsufficientBalanceReverts( - address to, - uint256 id, - uint256 mintAmount, - uint256 sendAmount - ) public { - if (mintAmount == type(uint256).max) mintAmount--; - sendAmount = _bound(sendAmount, mintAmount + 1, type(uint256).max); - - token.mint(address(this), id, mintAmount); - - _expectInsufficientBalanceRevert(); - token.transfer(to, id, sendAmount); - } - - function testTransferFromOverMaxUintReverts( - address to, - uint256 id, - uint256 amount0, - uint256 amount1 - ) public { - amount0 = _bound(amount0, 1, type(uint256).max); - amount1 = _bound(amount1, type(uint256).max - amount0 + 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, id, amount0); - _approve(from, address(this), id, amount0); - - token.transferFrom(from, to, id, amount0); - - if (to == from) { - vm.expectRevert(ERC6909.BalanceOverflow.selector); - token.mint(from, id, amount1); - return; - } - - token.mint(from, id, amount1); - _approve(from, address(this), id, amount1); - - vm.expectRevert(ERC6909.BalanceOverflow.selector); - token.transferFrom(from, to, id, amount1); - } - - function testTransferFromInsufficientAllowanceReverts( - address to, - uint256 id, - uint256 approval, - uint256 amount - ) public { - if (approval == type(uint256).max) approval--; - amount = _bound(amount, approval + 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, amount, id); - - _approve(from, address(this), id, approval); - - _expectInsufficientPermissionRevert(); - token.transferFrom(from, to, id, amount); - } - - function testTransferFromInsufficientBalanceReverts( - address to, - uint256 id, - uint256 mintAmount, - uint256 sendAmount - ) public { - if (mintAmount == type(uint256).max) mintAmount--; - sendAmount = _bound(sendAmount, mintAmount + 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, id, mintAmount); - - _approve(from, address(this), id, sendAmount); - - _expectInsufficientBalanceRevert(); - token.transferFrom(from, to, id, sendAmount); - } - - function testTransferFromCallerIsNotOperator(address to, uint256 id, uint256 amount) public { - amount = _bound(amount, 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, id, amount); - - _expectInsufficientPermissionRevert(); - token.transferFrom(from, to, id, amount); - } - - struct _TestTemps { - uint256 id; - uint256 allowance; - bool isOperator; - uint256 balance; - uint256 amount; - address by; - address from; - address to; - bool success; - } - - function testDirectSetOperator() public { - _directSetOperator(address(1), address(2), true); - } - - function testDirectApprove() public { - _directApprove(address(1), address(2), 1, 123); - } - - function testDirectTransfer() public { - token.mint(address(2), 1, 1); - vm.prank(address(2)); - token.approve(address(1), 1, 1); - token.directTransferFrom(address(1), address(2), address(3), 1, 1); - } - - function testDirectFunctions(uint256) public { - _TestTemps memory t; - t.id = _random(); - t.by = _randomChance(16) ? address(0) : _randomAddress(); - t.from = _randomAddress(); - t.to = _randomAddress(); - - for (uint256 q; q != 2; ++q) { - t.success = false; - t.allowance = _random(); - t.balance = _random(); - t.amount = _random(); - t.isOperator = _randomChance(4); - t.id ^= 1; - - token.mint(t.from, t.id, t.balance); - if (_randomChance(2)) { - _directSetOperator(t.from, t.by, t.isOperator); - _directApprove(t.from, t.by, t.id, t.allowance); - } else { - _setOperator(t.from, t.by, t.isOperator); - _directApprove(t.from, t.by, t.id, t.allowance); - } - - if (t.balance >= t.amount) { - if (t.by == address(0) || t.isOperator || t.allowance >= t.amount) { - t.success = true; - } else { - _expectInsufficientPermissionRevert(); - } - } else { - if (t.by == address(0) || t.isOperator || t.allowance >= t.amount) { - _expectInsufficientBalanceRevert(); - } else { - _expectInsufficientPermissionRevert(); - } - } - - if (t.by == address(0) && _randomChance(4)) { - if (t.success) { - vm.expectEmit(true, true, true, true); - emit Transfer(t.from, t.from, t.to, t.id, t.amount); - } - vm.prank(t.from); - token.transfer(t.to, t.id, t.amount); - } else if (t.by != address(0) && _randomChance(4)) { - if (t.success) { - vm.expectEmit(true, true, true, true); - emit Transfer(t.by, t.from, t.to, t.id, t.amount); - } - vm.prank(t.by); - token.transferFrom(t.from, t.to, t.id, t.amount); - } else { - if (t.success) { - vm.expectEmit(true, true, true, true); - emit Transfer(t.by, t.from, t.to, t.id, t.amount); - } - token.directTransferFrom(t.by, t.from, t.to, t.id, t.amount); - } - - if (t.by == address(0) || t.isOperator || t.allowance == type(uint256).max) { - assertEq(token.allowance(t.from, t.by, t.id), t.allowance); - } - - if (t.success) { - if (t.to == t.from) { - assertEq(token.balanceOf(t.to, t.id), t.balance); - } else { - assertEq(token.balanceOf(t.from, t.id), t.balance - t.amount); - assertEq(token.balanceOf(t.to, t.id), t.amount); - } - } - } - } - - function _expectInsufficientBalanceRevert() internal { - vm.expectRevert(ERC6909.InsufficientBalance.selector); - } - - function _expectInsufficientPermissionRevert() internal { - vm.expectRevert(ERC6909.InsufficientPermission.selector); - } - - function _approve(address owner, address spender, uint256 id, uint256 amount) internal { - vm.prank(owner); - vm.expectEmit(true, true, true, true); - emit Approval(owner, spender, id, amount); - token.approve(spender, id, amount); - assertEq(token.allowance(owner, spender, id), amount); - } - - function _setOperator(address owner, address operator, bool approved) internal { - vm.prank(owner); - vm.expectEmit(true, true, true, true); - emit OperatorSet(owner, operator, approved); - token.directSetOperator(owner, operator, approved); - assertEq(token.isOperator(owner, operator), approved); - } - - function _directApprove(address owner, address spender, uint256 id, uint256 amount) internal { - vm.expectEmit(true, true, true, true); - emit Approval(owner, spender, id, amount); - token.directApprove(owner, spender, id, amount); - assertEq(token.allowance(owner, spender, id), amount); - } - - function _directSetOperator(address owner, address operator, bool approved) internal { - vm.expectEmit(true, true, true, true); - emit OperatorSet(owner, operator, approved); - token.directSetOperator(owner, operator, approved); - assertEq(token.isOperator(owner, operator), approved); - } -} diff --git a/grouperBot/lib/solady/test/ERC721.t.sol b/grouperBot/lib/solady/test/ERC721.t.sol deleted file mode 100644 index bc47818..0000000 --- a/grouperBot/lib/solady/test/ERC721.t.sol +++ /dev/null @@ -1,1018 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; - -import {ERC721, MockERC721} from "./utils/mocks/MockERC721.sol"; - -abstract contract ERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) - external - virtual - returns (bytes4) - { - return ERC721TokenReceiver.onERC721Received.selector; - } -} - -contract ERC721Recipient is ERC721TokenReceiver { - address public operator; - address public from; - uint256 public id; - bytes public data; - - function onERC721Received(address _operator, address _from, uint256 _id, bytes calldata _data) - public - virtual - override - returns (bytes4) - { - operator = _operator; - from = _from; - id = _id; - data = _data; - - return ERC721TokenReceiver.onERC721Received.selector; - } -} - -contract RevertingERC721Recipient is ERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) - public - virtual - override - returns (bytes4) - { - revert(string(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector))); - } -} - -contract WrongReturnDataERC721Recipient is ERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) - public - virtual - override - returns (bytes4) - { - return 0xCAFEBEEF; - } -} - -contract NonERC721Recipient {} - -contract MockERC721WithHooks is MockERC721 { - uint256 public beforeCounter; - uint256 public afterCounter; - - function _beforeTokenTransfer(address, address, uint256) internal virtual override { - beforeCounter++; - } - - function _afterTokenTransfer(address, address, uint256) internal virtual override { - afterCounter++; - } -} - -contract ERC721HooksTest is SoladyTest, ERC721TokenReceiver { - uint256 public expectedBeforeCounter; - uint256 public expectedAfterCounter; - uint256 public ticker; - - function _checkCounters() internal view { - require( - expectedBeforeCounter == MockERC721WithHooks(msg.sender).beforeCounter(), - "Before counter mismatch." - ); - require( - expectedAfterCounter == MockERC721WithHooks(msg.sender).afterCounter(), - "After counter mismatch." - ); - } - - function onERC721Received(address, address, uint256, bytes calldata) - external - virtual - override - returns (bytes4) - { - _checkCounters(); - return ERC721TokenReceiver.onERC721Received.selector; - } - - function _testHooks(MockERC721WithHooks token) internal { - address from = _randomNonZeroAddress(); - uint256 tokenId = - uint256(keccak256(abi.encode(expectedBeforeCounter, expectedAfterCounter))); - expectedBeforeCounter++; - expectedAfterCounter++; - token.mint(address(this), tokenId); - - expectedBeforeCounter++; - expectedAfterCounter++; - token.transferFrom(address(this), from, tokenId); - - expectedBeforeCounter++; - expectedAfterCounter++; - uint256 r = ticker < 4 ? ticker : _random() % 4; - vm.prank(from); - if (r == 0) { - token.safeTransferFrom(from, address(this), tokenId); - } else if (r == 1) { - token.safeTransferFrom(from, address(this), tokenId, ""); - } else if (r == 2) { - token.directSafeTransferFrom(from, address(this), tokenId); - } else if (r == 3) { - token.directSafeTransferFrom(from, address(this), tokenId, ""); - } else { - revert(); - } - } - - function testERC721Hooks() public { - MockERC721WithHooks token = new MockERC721WithHooks(); - - for (uint256 i; i < 32; ++i) { - _testHooks(token); - } - } -} - -contract ERC721Test is SoladyTest { - MockERC721 token; - - uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; - - event Transfer(address indexed from, address indexed to, uint256 indexed id); - - event Approval(address indexed owner, address indexed approved, uint256 indexed id); - - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - function setUp() public { - token = new MockERC721(); - } - - function _expectMintEvent(address to, uint256 id) internal { - _expectTransferEvent(address(0), to, id); - } - - function _expectBurnEvent(address from, uint256 id) internal { - _expectTransferEvent(from, address(0), id); - } - - function _expectTransferEvent(address from, address to, uint256 id) internal { - vm.expectEmit(true, true, true, true); - emit Transfer(_cleaned(from), _cleaned(to), id); - } - - function _expectApprovalEvent(address owner, address approved, uint256 id) internal { - vm.expectEmit(true, true, true, true); - emit Approval(_cleaned(owner), _cleaned(approved), id); - } - - function _expectApprovalForAllEvent(address owner, address operator, bool approved) internal { - vm.expectEmit(true, true, true, true); - emit ApprovalForAll(_cleaned(owner), _cleaned(operator), approved); - } - - function _aux(address owner) internal pure returns (uint224 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, owner) - result := shr(32, shl(32, keccak256(0x0c, 0x14))) - } - } - - function _extraData(uint256 id) internal pure returns (uint96 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - result := shr(160, shl(160, keccak256(0x00, 0x20))) - } - } - - function _transferFrom(address from, address to, uint256 id) internal { - if (_randomChance(2)) { - token.transferFrom(from, to, id); - } else { - token.directTransferFrom(from, to, id); - } - } - - function _safeTransferFrom(address from, address to, uint256 id) internal { - if (_randomChance(2)) { - token.safeTransferFrom(from, to, id); - } else { - token.directSafeTransferFrom(from, to, id); - } - } - - function _safeTransferFrom(address from, address to, uint256 id, bytes memory data) internal { - if (_randomChance(2)) { - token.safeTransferFrom(from, to, id, data); - } else { - token.directSafeTransferFrom(from, to, id, data); - } - } - - function _approve(address spender, uint256 id) internal { - if (_randomChance(2)) { - token.approve(spender, id); - } else { - token.directApprove(spender, id); - } - } - - function _setApprovalForAll(address operator, bool approved) internal { - if (_randomChance(2)) { - token.setApprovalForAll(operator, approved); - } else { - token.directSetApprovalForAll(operator, approved); - } - } - - function _ownerOf(uint256 id) internal returns (address) { - if (_randomChance(2)) { - return token.ownerOf(id); - } else { - return token.directOwnerOf(id); - } - } - - function _getApproved(uint256 id) internal returns (address) { - if (_randomChance(2)) { - return token.getApproved(id); - } else { - return token.directGetApproved(id); - } - } - - function _owners() internal returns (address a, address b) { - a = _randomNonZeroAddress(); - b = _randomNonZeroAddress(); - while (a == b) b = _randomNonZeroAddress(); - } - - function testSafetyOfCustomStorage(uint256 id0, uint256 id1) public { - bool safe; - while (id0 == id1) id1 = _random(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id0) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let slot0 := add(id0, add(id0, keccak256(0x00, 0x20))) - let slot2 := add(1, slot0) - mstore(0x00, id1) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let slot1 := add(id1, add(id1, keccak256(0x00, 0x20))) - let slot3 := add(1, slot1) - safe := 1 - if eq(slot0, slot1) { safe := 0 } - if eq(slot0, slot2) { safe := 0 } - if eq(slot0, slot3) { safe := 0 } - if eq(slot1, slot2) { safe := 0 } - if eq(slot1, slot3) { safe := 0 } - if eq(slot2, slot3) { safe := 0 } - } - require(safe, "Custom storage not safe"); - } - - function testAuthorizedEquivalence(address by, bool isOwnerOrOperator, bool isApprovedAccount) - public - { - bool a = true; - bool b = true; - /// @solidity memory-safe-assembly - assembly { - if by { if iszero(isOwnerOrOperator) { a := isApprovedAccount } } - if iszero(or(iszero(by), isOwnerOrOperator)) { b := isApprovedAccount } - } - assertEq(a, b); - } - - function testCannotExceedMaxBalance() public { - bytes32 balanceSlot; - (address owner0, address owner1) = _owners(); - - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner0) - balanceSlot := keccak256(0x0c, 0x1c) - } - - vm.store(address(token), balanceSlot, bytes32(uint256(0xfffffffe))); - token.setAux(owner0, type(uint224).max); - assertEq(token.balanceOf(owner0), 0xfffffffe); - assertEq(token.getAux(owner0), type(uint224).max); - token.mint(owner0, 0); - assertEq(token.balanceOf(owner0), 0xffffffff); - - vm.expectRevert(ERC721.AccountBalanceOverflow.selector); - token.mint(owner0, 1); - - vm.expectRevert(ERC721.AccountBalanceOverflow.selector); - token.mintWithExtraDataUnchecked(owner0, 1, _extraData(1)); - - token.uncheckedBurn(0); - assertEq(token.balanceOf(owner0), 0xfffffffe); - - token.mint(owner1, 0); - vm.prank(owner1); - _transferFrom(owner1, owner0, 0); - - token.mint(owner1, 1); - vm.expectRevert(ERC721.AccountBalanceOverflow.selector); - vm.prank(owner1); - _transferFrom(owner1, owner0, 1); - assertEq(token.getAux(owner0), type(uint224).max); - } - - function testMint(uint256 id) public { - address owner = _randomNonZeroAddress(); - - _expectMintEvent(owner, id); - token.mint(owner, id); - - assertEq(token.balanceOf(owner), 1); - assertEq(_ownerOf(id), owner); - } - - function testMintAndSetExtraDataUnchecked(uint256 id) public { - address owner = _randomNonZeroAddress(); - - _expectMintEvent(owner, id); - token.mintWithExtraDataUnchecked(owner, id, _extraData(id)); - - assertEq(token.balanceOf(owner), 1); - assertEq(_ownerOf(id), owner); - assertEq(token.getExtraData(id), _extraData(id)); - } - - function testMintAndSetExtraDataUncheckedWithOverwrite(uint256 id, uint96 random) public { - address owner = _randomNonZeroAddress(); - - token.setExtraData(id, random); - assertEq(token.getExtraData(id), random); - - _expectMintEvent(owner, id); - token.mintWithExtraDataUnchecked(owner, id, _extraData(id)); - - assertEq(token.getExtraData(id), _extraData(id)); - } - - function testBurn(uint256 id) public { - address owner = _randomNonZeroAddress(); - - _expectMintEvent(owner, id); - token.mint(owner, id); - - if (_randomChance(2)) { - _expectBurnEvent(owner, id); - token.uncheckedBurn(id); - } else { - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - token.burn(id); - uint256 r = _random() % 3; - if (r == 0) { - vm.prank(owner); - _transferFrom(owner, address(this), id); - _expectBurnEvent(address(this), id); - token.burn(id); - } - if (r == 1) { - vm.prank(owner); - _setApprovalForAll(address(this), true); - _expectBurnEvent(owner, id); - token.burn(id); - } - if (r == 2) { - vm.prank(owner); - _approve(address(this), id); - _expectBurnEvent(owner, id); - token.burn(id); - } - } - - assertEq(token.balanceOf(owner), 0); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } - - function testTransferFrom() public { - address owner = _randomNonZeroAddress(); - token.mint(owner, 0); - vm.prank(owner); - token.transferFrom(owner, address(this), 0); - } - - function testEverything(uint256) public { - address[2] memory owners; - uint256[][2] memory tokens; - - unchecked { - (owners[0], owners[1]) = _owners(); - for (uint256 j; j != 2; ++j) { - tokens[j] = new uint256[](_random() % 3); - } - - for (uint256 j; j != 2; ++j) { - token.setAux(owners[j], _aux(owners[j])); - for (uint256 i; i != tokens[j].length;) { - uint256 id = _random(); - if (!token.exists(id)) { - tokens[j][i++] = id; - _expectMintEvent(owners[j], id); - token.mint(owners[j], id); - token.setExtraData(id, _extraData(id)); - } - } - } - for (uint256 j; j != 2; ++j) { - assertEq(token.balanceOf(owners[j]), tokens[j].length); - for (uint256 i; i != tokens[j].length; ++i) { - vm.prank(owners[j]); - _expectApprovalEvent(owners[j], address(this), tokens[j][i]); - _approve(address(this), tokens[j][i]); - } - } - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(_getApproved(tokens[j][i]), address(this)); - uint256 fromBalanceBefore = token.balanceOf(owners[j]); - uint256 toBalanceBefore = token.balanceOf(owners[j ^ 1]); - _expectTransferEvent(owners[j], owners[j ^ 1], tokens[j][i]); - _transferFrom(owners[j], owners[j ^ 1], tokens[j][i]); - assertEq(token.balanceOf(owners[j]), fromBalanceBefore - 1); - assertEq(token.balanceOf(owners[j ^ 1]), toBalanceBefore + 1); - assertEq(_getApproved(tokens[j][i]), address(0)); - } - } - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(_ownerOf(tokens[j][i]), owners[j ^ 1]); - assertEq(token.getExtraData(tokens[j][i]), _extraData(tokens[j][i])); - } - } - if (_randomChance(2)) { - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - _transferFrom(owners[j ^ 1], owners[j], tokens[j][i]); - vm.prank(owners[j ^ 1]); - _expectApprovalEvent(owners[j ^ 1], address(this), tokens[j][i]); - _approve(address(this), tokens[j][i]); - _expectTransferEvent(owners[j ^ 1], owners[j], tokens[j][i]); - _transferFrom(owners[j ^ 1], owners[j], tokens[j][i]); - } - } - } else { - for (uint256 j; j != 2; ++j) { - vm.prank(owners[j ^ 1]); - _expectApprovalForAllEvent(owners[j ^ 1], address(this), true); - token.setApprovalForAll(address(this), true); - for (uint256 i; i != tokens[j].length; ++i) { - _expectTransferEvent(owners[j ^ 1], owners[j], tokens[j][i]); - _transferFrom(owners[j ^ 1], owners[j], tokens[j][i]); - } - } - } - for (uint256 j; j != 2; ++j) { - assertEq(token.getAux(owners[j]), _aux(owners[j])); - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(_ownerOf(tokens[j][i]), owners[j]); - assertEq(token.getExtraData(tokens[j][i]), _extraData(tokens[j][i])); - } - } - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - token.uncheckedBurn(tokens[j][i]); - } - } - for (uint256 j; j != 2; ++j) { - assertEq(token.balanceOf(owners[j]), 0); - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(token.getExtraData(tokens[j][i]), _extraData(tokens[j][i])); - } - } - } - } - - function testIsApprovedOrOwner(uint256 id) public { - (address owner0, address owner1) = _owners(); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - token.isApprovedOrOwner(owner0, id); - - token.mint(owner0, id); - assertEq(token.isApprovedOrOwner(owner0, id), true); - - vm.prank(owner0); - _transferFrom(owner0, owner1, id); - assertEq(token.isApprovedOrOwner(owner0, id), false); - - vm.prank(owner1); - _setApprovalForAll(owner0, true); - assertEq(token.isApprovedOrOwner(owner0, id), true); - - vm.prank(owner1); - _setApprovalForAll(owner0, false); - assertEq(token.isApprovedOrOwner(owner0, id), false); - - vm.prank(owner1); - _approve(owner0, id); - assertEq(token.isApprovedOrOwner(owner0, id), true); - } - - function testExtraData(uint256 id) public { - (address owner0, address owner1) = _owners(); - - bool setExtraData = _randomChance(2); - uint96 extraData = uint96(_bound(_random(), 0, type(uint96).max)); - if (setExtraData) { - token.setExtraData(id, extraData); - } - _expectMintEvent(owner0, id); - token.mint(owner0, id); - if (setExtraData) { - assertEq(token.getExtraData(id), extraData); - } else { - assertEq(token.getExtraData(id), 0); - } - - vm.prank(owner0); - _expectTransferEvent(owner0, owner1, id); - _transferFrom(owner0, owner1, id); - if (setExtraData) { - assertEq(token.getExtraData(id), extraData); - } else { - assertEq(token.getExtraData(id), 0); - } - assertEq(_ownerOf(id), owner1); - - if (_randomChance(2)) { - extraData = uint96(_bound(_random(), 0, type(uint96).max)); - token.setExtraData(id, extraData); - setExtraData = true; - } - - _expectBurnEvent(owner1, id); - token.uncheckedBurn(id); - if (setExtraData) { - assertEq(token.getExtraData(id), extraData); - } else { - assertEq(token.getExtraData(id), 0); - } - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } - - function testExtraData2(uint256 id0, uint256 id1) public { - while (id0 == id1) id1 = _random(); - token.setExtraData(id0, _extraData(id0)); - token.setExtraData(id1, _extraData(id1)); - assertEq(token.getExtraData(id0), _extraData(id0)); - assertEq(token.getExtraData(id1), _extraData(id1)); - } - - function testAux(uint256) public { - (address owner0, address owner1) = _owners(); - - bool setAux = _randomChance(2); - if (setAux) { - token.setAux(owner0, _aux(owner0)); - token.setAux(owner1, _aux(owner1)); - } - - for (uint256 i; i < 2; ++i) { - _expectMintEvent(owner0, i * 2 + 0); - token.mint(owner0, i * 2 + 0); - assertEq(token.balanceOf(owner0), i + 1); - - _expectMintEvent(owner1, i * 2 + 1); - token.mint(owner1, i * 2 + 1); - assertEq(token.balanceOf(owner1), i + 1); - - if (setAux) { - assertEq(token.getAux(owner0), _aux(owner0)); - assertEq(token.getAux(owner1), _aux(owner1)); - } else { - assertEq(token.getAux(owner0), 0); - assertEq(token.getAux(owner1), 0); - } - } - - for (uint256 i; i < 2; ++i) { - _expectBurnEvent(owner0, i * 2 + 0); - token.uncheckedBurn(i * 2 + 0); - assertEq(token.balanceOf(owner0), 1 - i); - - _expectBurnEvent(owner1, i * 2 + 1); - token.uncheckedBurn(i * 2 + 1); - assertEq(token.balanceOf(owner1), 1 - i); - - if (setAux) { - assertEq(token.getAux(owner0), _aux(owner0)); - assertEq(token.getAux(owner1), _aux(owner1)); - } else { - assertEq(token.getAux(owner0), 0); - assertEq(token.getAux(owner1), 0); - } - } - } - - function testApprove(uint256 id) public { - (address spender,) = _randomSigner(); - - token.mint(address(this), id); - - _expectApprovalEvent(address(this), spender, id); - _approve(spender, id); - assertEq(_getApproved(id), spender); - } - - function testApproveBurn(uint256 id) public { - (address spender,) = _randomSigner(); - - token.mint(address(this), id); - - _approve(spender, id); - - token.uncheckedBurn(id); - - assertEq(token.balanceOf(address(this)), 0); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _getApproved(id); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } - - function testApproveAll(uint256) public { - (address operator,) = _randomSigner(); - bool approved = _randomChance(2); - _expectApprovalForAllEvent(address(this), operator, approved); - _setApprovalForAll(operator, approved); - assertEq(token.isApprovedForAll(address(this), operator), approved); - } - - function testTransferFrom(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - if (_randomChance(2)) { - uint256 r = _random() % 3; - if (r == 0) { - vm.prank(from); - _approve(address(this), id); - _expectTransferEvent(from, to, id); - _transferFrom(from, to, id); - } - if (r == 1) { - vm.prank(from); - _setApprovalForAll(address(this), true); - _expectTransferEvent(from, to, id); - _transferFrom(from, to, id); - } - if (r == 2) { - vm.prank(from); - _expectTransferEvent(from, address(this), id); - _transferFrom(from, address(this), id); - _expectTransferEvent(address(this), to, id); - _transferFrom(address(this), to, id); - } - } else { - (address temp,) = _randomSigner(); - while (temp == from || temp == to) (temp,) = _randomSigner(); - if (_randomChance(2)) { - _expectTransferEvent(from, temp, id); - token.uncheckedTransferFrom(from, temp, id); - } else { - vm.prank(from); - _expectTransferEvent(from, temp, id); - _transferFrom(from, temp, id); - } - _expectTransferEvent(temp, to, id); - token.uncheckedTransferFrom(temp, to, id); - } - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testTransferFromSelf(uint256 id) public { - (address to,) = _randomSigner(); - - token.mint(address(this), id); - - _transferFrom(address(this), to, id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(address(this)), 0); - } - - function testTransferFromApproveAll(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _transferFrom(from, to, id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToEOA(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _safeTransferFrom(from, to, id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToERC721Recipient(uint256 id) public { - (address from,) = _randomSigner(); - - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _safeTransferFrom(from, address(recipient), id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - assertEq(recipient.id(), id); - assertEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes memory data) public { - (address from,) = _randomSigner(); - - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _safeTransferFrom(from, address(recipient), id, data); - - assertEq(recipient.data(), data); - assertEq(recipient.id(), id); - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeMintToEOA(uint256 id) public { - (address to,) = _randomSigner(); - - token.safeMint(to, id); - - assertEq(_ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - } - - function testSafeMintToERC721Recipient(uint256 id) public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), id); - - assertEq(_ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), id); - assertEq(to.data(), ""); - } - - function testSafeMintToERC721RecipientWithData(uint256 id, bytes memory data) public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), id, data); - - assertEq(_ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), id); - assertEq(to.data(), data); - } - - function testMintToZeroReverts(uint256 id) public { - vm.expectRevert(ERC721.TransferToZeroAddress.selector); - token.mint(address(0), id); - - vm.expectRevert(ERC721.TransferToZeroAddress.selector); - token.mintWithExtraDataUnchecked(address(0), id, _extraData(id)); - } - - function testDoubleMintReverts(uint256 id) public { - (address to,) = _randomSigner(); - - token.mint(to, id); - vm.expectRevert(ERC721.TokenAlreadyExists.selector); - token.mint(to, id); - } - - function testBurnNonExistentReverts(uint256 id) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - token.uncheckedBurn(id); - } - - function testDoubleBurnReverts(uint256 id) public { - (address to,) = _randomSigner(); - - token.mint(to, id); - - token.uncheckedBurn(id); - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - token.uncheckedBurn(id); - } - - function testApproveNonExistentReverts(uint256 id, address to) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _approve(to, id); - } - - function testApproveUnauthorizedReverts(uint256 id) public { - (address owner, address to) = _owners(); - - token.mint(owner, id); - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - _approve(to, id); - } - - function testTransferFromNotExistentReverts(address from, address to, uint256 id) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _transferFrom(from, to, id); - } - - function testTransferFromWrongFromReverts(address to, uint256 id) public { - (address owner, address from) = _owners(); - - token.mint(owner, id); - vm.expectRevert(ERC721.TransferFromIncorrectOwner.selector); - _transferFrom(from, to, id); - } - - function testTransferFromToZeroReverts(uint256 id) public { - token.mint(address(this), id); - - vm.expectRevert(ERC721.TransferToZeroAddress.selector); - _transferFrom(address(this), address(0), id); - } - - function testTransferFromNotOwner(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - _transferFrom(from, to, id); - } - - function testSafeTransferFromToNonERC721RecipientReverts(uint256 id) public { - token.mint(address(this), id); - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), address(to), id); - } - - function testSafeTransferFromToNonERC721RecipientWithDataReverts(uint256 id, bytes memory data) - public - { - token.mint(address(this), id); - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), to, id, data); - } - - function testSafeTransferFromToRevertingERC721RecipientReverts(uint256 id) public { - token.mint(address(this), id); - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - _safeTransferFrom(address(this), to, id); - } - - function testSafeTransferFromToRevertingERC721RecipientWithDataReverts( - uint256 id, - bytes memory data - ) public { - token.mint(address(this), id); - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - _safeTransferFrom(address(this), to, id, data); - } - - function testSafeTransferFromToERC721RecipientWithWrongReturnDataReverts(uint256 id) public { - token.mint(address(this), id); - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), to, id); - } - - function testSafeTransferFromToERC721RecipientWithWrongReturnDataWithDataReverts( - uint256 id, - bytes memory data - ) public { - token.mint(address(this), id); - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), to, id, data); - } - - function testSafeMintToNonERC721RecipientReverts(uint256 id) public { - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id); - } - - function testSafeMintToNonERC721RecipientWithDataReverts(uint256 id, bytes memory data) - public - { - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id, data); - } - - function testSafeMintToRevertingERC721RecipientReverts(uint256 id) public { - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - token.safeMint(to, id); - } - - function testSafeMintToRevertingERC721RecipientWithDataReverts(uint256 id, bytes memory data) - public - { - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - token.safeMint(to, id, data); - } - - function testSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public { - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id); - } - - function testSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes memory data) - public - { - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id, data); - } - - function testOwnerOfNonExistent(uint256 id) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } - - function check_AuxPackEquivalence(uint224 a, uint32 b) public pure { - uint256 packed = (uint256(a) << 32) | uint256(b); - unchecked { - bool hasOverflow = ((packed + 1) & 0xffffffff) == 0; - bool groundTruth = b == 0xffffffff; - assert(hasOverflow == groundTruth); - } - } - - function testAuxPackEquivalence(uint224 a, uint32 b) public pure { - check_AuxPackEquivalence(a, b); - } -} diff --git a/grouperBot/lib/solady/test/ERC7821.t.sol b/grouperBot/lib/solady/test/ERC7821.t.sol deleted file mode 100644 index c91de9b..0000000 --- a/grouperBot/lib/solady/test/ERC7821.t.sol +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {ERC7821, MockERC7821} from "./utils/mocks/MockERC7821.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; - -contract ERC7821Test is SoladyTest { - error CustomError(); - - MockERC7821 mbe; - - address target; - - bytes32 internal constant _SUPPORTED_MODE = bytes10(0x01000000000078210001); - - bytes[] internal _bytes; - - function setUp() public { - mbe = new MockERC7821(); - mbe.setAuthorizedCaller(address(this), true); - target = LibClone.clone(address(this)); - } - - function revertsWithCustomError() external payable { - revert CustomError(); - } - - function returnsBytes(bytes memory b) external payable returns (bytes memory) { - return b; - } - - function returnsHash(bytes memory b) external payable returns (bytes32) { - return keccak256(b); - } - - function testERC7821Gas() public { - vm.pauseGasMetering(); - vm.deal(address(this), 1 ether); - - ERC7821.Call[] memory calls = new ERC7821.Call[](2); - - calls[0].to = target; - calls[0].value = 123; - calls[0].data = abi.encodeWithSignature("returnsBytes(bytes)", "hehe"); - - calls[1].to = target; - calls[1].value = 789; - calls[1].data = abi.encodeWithSignature("returnsHash(bytes)", "lol"); - - bytes memory data = abi.encode(calls); - vm.resumeGasMetering(); - - mbe.execute{value: _totalValue(calls)}(_SUPPORTED_MODE, data); - } - - function testERC7821(bytes memory opData) public { - vm.deal(address(this), 1 ether); - - ERC7821.Call[] memory calls = new ERC7821.Call[](2); - - calls[0].to = target; - calls[0].value = 123; - calls[0].data = abi.encodeWithSignature("returnsBytes(bytes)", "hehe"); - - calls[1].to = target; - calls[1].value = 789; - calls[1].data = abi.encodeWithSignature("returnsHash(bytes)", "lol"); - - mbe.execute{value: _totalValue(calls)}(_SUPPORTED_MODE, _encode(calls, opData)); - - assertEq(mbe.lastOpData(), opData); - } - - function testERC7821ForRevert() public { - ERC7821.Call[] memory calls = new ERC7821.Call[](1); - calls[0].to = target; - calls[0].value = 0; - calls[0].data = abi.encodeWithSignature("revertsWithCustomError()"); - - vm.expectRevert(CustomError.selector); - mbe.execute{value: _totalValue(calls)}(_SUPPORTED_MODE, _encode(calls, "")); - } - - function _encode(ERC7821.Call[] memory calls, bytes memory opData) - internal - returns (bytes memory) - { - if (_randomChance(2) && opData.length == 0) return abi.encode(calls); - return abi.encode(calls, opData); - } - - struct Payload { - bytes data; - uint256 mode; - } - - function testERC7821(bytes32) public { - vm.deal(address(this), 1 ether); - - ERC7821.Call[] memory calls = new ERC7821.Call[](_randomUniform() & 3); - Payload[] memory payloads = new Payload[](calls.length); - - for (uint256 i; i < calls.length; ++i) { - calls[i].to = target; - calls[i].value = _randomUniform() & 0xff; - bytes memory data = _truncateBytes(_randomBytes(), 0x1ff); - payloads[i].data = data; - if (_randomChance(2)) { - payloads[i].mode = 0; - calls[i].data = abi.encodeWithSignature("returnsBytes(bytes)", data); - } else { - payloads[i].mode = 1; - calls[i].data = abi.encodeWithSignature("returnsHash(bytes)", data); - } - } - - mbe.executeDirect{value: _totalValue(calls)}(calls); - - if (calls.length != 0 && _randomChance(32)) { - calls[_randomUniform() % calls.length].data = - abi.encodeWithSignature("revertsWithCustomError()"); - vm.expectRevert(CustomError.selector); - mbe.executeDirect{value: _totalValue(calls)}(calls); - } - } - - function _totalValue(ERC7821.Call[] memory calls) internal pure returns (uint256 result) { - unchecked { - for (uint256 i; i < calls.length; ++i) { - result += calls[i].value; - } - } - } - - function testERC7821ExecuteBatchOfBatches() public { - bytes32 mode = bytes32(0x0100000000007821000200000000000000000000000000000000000000000000); - bytes[] memory batchBytes = new bytes[](3); - batchBytes[0] = hex"112233"; - batchBytes[1] = hex""; - batchBytes[2] = - hex"112233445566778899112233445566778899112233445566778899112233445566778899112233445566778899"; - bytes[] memory batches = new bytes[](batchBytes.length); - for (uint256 i; i < batches.length; ++i) { - batches[i] = _encodePushBytesBatch(batchBytes[i]); - } - mbe.execute(mode, abi.encode(batches)); - for (uint256 i; i < batches.length; ++i) { - assertEq(_bytes[i], batchBytes[i]); - } - assertEq(_bytes.length, batchBytes.length); - - // Test that batch of batches is executed with the correct `msg.sender`. - - address pranker = _randomUniqueHashedAddress(); - vm.startPrank(pranker); - - vm.expectRevert(MockERC7821.Unauthorized.selector); - mbe.execute(mode, abi.encode(batches)); - - mbe.setAuthorizedCaller(pranker, true); - mbe.execute(mode, abi.encode(batches)); - - assertEq(_bytes.length, batchBytes.length * 2); - - mbe.setAuthorizedCaller(pranker, false); - vm.expectRevert(MockERC7821.Unauthorized.selector); - mbe.execute(mode, abi.encode(batches)); - - assertEq(_bytes.length, batchBytes.length * 2); - - vm.stopPrank(); - } - - function _encodePushBytesBatch(bytes memory x) internal view returns (bytes memory) { - ERC7821.Call[] memory calls = new ERC7821.Call[](1); - calls[0].data = abi.encodeWithSignature("pushBytes(bytes)", x); - calls[0].to = address(this); - return abi.encode(calls); - } - - function pushBytes(bytes memory x) public { - _bytes.push(x); - } -} diff --git a/grouperBot/lib/solady/test/EfficientHashLib.t.sol b/grouperBot/lib/solady/test/EfficientHashLib.t.sol deleted file mode 100644 index 56356f6..0000000 --- a/grouperBot/lib/solady/test/EfficientHashLib.t.sol +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {EfficientHashLib} from "../src/utils/EfficientHashLib.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract EfficientHashLibTest is SoladyTest { - using EfficientHashLib for bytes32[]; - - function testEfficientHash() public { - testEfficientHash(0); - } - - function testEfficientHash(uint256 x) public { - string memory t = "01234567890123456789012345678901"; - _checkMemory(); - bytes32[] memory a = EfficientHashLib.malloc(10); - _checkMemory(); - unchecked { - for (uint256 i; i < 10; ++i) { - EfficientHashLib.set(a, i, bytes32(x ^ (i << 128))); - } - } - bytes memory encoded = abi.encodePacked(a); - assertEq(EfficientHashLib.hash(a[0]), _hash(encoded, 1)); - assertEq(EfficientHashLib.hash(a[0], a[1]), _hash(encoded, 2)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2]), _hash(encoded, 3)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3]), _hash(encoded, 4)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4]), _hash(encoded, 5)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4], a[5]), _hash(encoded, 6)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4], a[5], a[6]), _hash(encoded, 7)); - assertEq( - EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]), _hash(encoded, 8) - ); - _checkMemory(); - EfficientHashLib.free(a); - _checkMemory(); - a = EfficientHashLib.malloc(1); - assertEq(t, "01234567890123456789012345678901"); - EfficientHashLib.free(a); - _checkMemory(); - assertEq(t, "01234567890123456789012345678901"); - } - - function testEfficientHashUints() public { - uint256[] memory a = new uint256[](10); - for (uint256 i; i < 10; ++i) { - a[i] = i << 128; - } - bytes memory encoded = abi.encodePacked(a); - assertEq(EfficientHashLib.hash(a[0]), _hash(encoded, 1)); - assertEq(EfficientHashLib.hash(a[0], a[1]), _hash(encoded, 2)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2]), _hash(encoded, 3)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3]), _hash(encoded, 4)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4]), _hash(encoded, 5)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4], a[5]), _hash(encoded, 6)); - assertEq(EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4], a[5], a[6]), _hash(encoded, 7)); - assertEq( - EfficientHashLib.hash(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]), _hash(encoded, 8) - ); - } - - function testEfficientHashSet() public { - assertEq( - EfficientHashLib.malloc(3).set(0, 1).set(1, 2).set(2, 3).hash(), - keccak256(abi.encode(uint256(1), uint256(2), uint256(3))) - ); - assertEq( - EfficientHashLib.malloc(2).set(0, 1).set(1, 2).hash(), - keccak256(abi.encode(uint256(1), uint256(2))) - ); - assertEq(EfficientHashLib.malloc(1).set(0, 1).hash(), keccak256(abi.encode(uint256(1)))); - assertEq(EfficientHashLib.malloc(0).hash(), keccak256("")); - assertEq(EfficientHashLib.malloc(0).hash(), keccak256("")); - bytes32[] memory empty; - assertEq(EfficientHashLib.hash(empty), keccak256("")); - } - - function _hash(bytes memory encoded, uint256 n) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(add(encoded, 0x20), shl(5, n)) - } - } - - function testEfficientHashFree() public { - uint256 mBefore = _fmp(); - bytes32[] memory buffer; - EfficientHashLib.free(buffer); - assertEq(mBefore, _fmp()); - } - - function testEfficientHashFree(uint8 n, bool b, uint8 t) public { - if (b) EfficientHashLib.malloc(t | 1); - uint256 mBefore = _fmp(); - bytes32[] memory buffer = EfficientHashLib.malloc(n | 1); - assertGt(_fmp(), mBefore); - EfficientHashLib.free(buffer); - assertEq(mBefore, _fmp()); - } - - function _fmp() internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - } - } - - function testEfficientHashBytesSlice(bytes32, bytes calldata b) public { - unchecked { - uint256 n = b.length + 100; - uint256 start = _bound(_random(), 0, n); - uint256 end = _bound(_random(), 0, n); - bytes memory bMem = b; - if (b.length == 0 && _randomChance(2)) { - /// @solidity memory-safe-assembly - assembly { - bMem := 0x60 - } - } - bytes32 h; - - h = EfficientHashLib.hashCalldata(b); - assertEq(h, keccak256(bMem)); - assertEq(EfficientHashLib.hash(bMem), h); - - h = EfficientHashLib.hashCalldata(b, start); - assertEq(h, keccak256(bytes(LibString.slice(string(bMem), start)))); - assertEq(EfficientHashLib.hash(bMem, start), h); - - h = EfficientHashLib.hashCalldata(b, start, end); - assertEq(h, keccak256(bytes(LibString.slice(string(bMem), start, end)))); - assertEq(EfficientHashLib.hash(bMem, start, end), h); - - _checkMemory(); - } - } - - function testEfficientHashBytesSlice() public { - this.testEfficientHashBytesSlice(bytes32(0), "0123456789"); - } - - function testEfficientHashEq(bytes32 a, uint256 n) public { - bytes memory b = abi.encode(a); - bytes memory s = abi.encode(a); - /// @solidity memory-safe-assembly - assembly { - mstore(s, mod(n, 0x20)) - } - assertTrue(EfficientHashLib.eq(a, b)); - assertTrue(EfficientHashLib.eq(b, a)); - assertFalse(EfficientHashLib.eq(a, s)); - assertFalse(EfficientHashLib.eq(s, a)); - } - - function testEfficientHashEq() public { - bytes32 a = 0x123456789a123456789a123456789a123456789a123456789a123456789a1234; - bytes memory b = hex"123456789a123456789a123456789a123456789a123456789a123456789a1234"; - assertTrue(EfficientHashLib.eq(a, b)); - // The following costs approximately 90 more gas: - // `assertTrue(a == abi.decode(b, (bytes32)))`; - } - - function testSha2(bytes32 b) public { - assertEq(sha256(abi.encode(b)), EfficientHashLib.sha2(b)); - } - - function testSha2(bytes calldata b) public { - assertEq(sha256(b), EfficientHashLib.sha2(b)); - assertEq(sha256(b), EfficientHashLib.sha2Calldata(b)); - } - - function testSha2BytesSlice(bytes32, bytes calldata b) public { - unchecked { - uint256 n = b.length + 100; - uint256 start = _bound(_random(), 0, n); - uint256 end = _bound(_random(), 0, n); - bytes memory bMem = b; - if (b.length == 0 && _randomChance(2)) { - /// @solidity memory-safe-assembly - assembly { - bMem := 0x60 - } - } - bytes32 h; - - h = EfficientHashLib.sha2Calldata(b); - assertEq(h, sha256(bMem)); - assertEq(EfficientHashLib.sha2(bMem), h); - - h = EfficientHashLib.sha2Calldata(b, start); - assertEq(h, sha256(bytes(LibString.slice(string(bMem), start)))); - assertEq(EfficientHashLib.sha2(bMem, start), h); - - h = EfficientHashLib.sha2Calldata(b, start, end); - assertEq(h, sha256(bytes(LibString.slice(string(bMem), start, end)))); - assertEq(EfficientHashLib.sha2(bMem, start, end), h); - - _checkMemory(); - } - } - - function testEfficientHashMaxStack(uint256 x) public { - unchecked { - bytes32 computed = EfficientHashLib.hash(x, x, x, x, x, x, x, x, x, x, x, x, x, x); - bytes32[] memory a = EfficientHashLib.malloc(14); - for (uint256 i; i != 14; ++i) { - EfficientHashLib.set(a, i, x); - } - assertEq(computed, EfficientHashLib.hash(a)); - } - } - - function testEfficientHashMaxStack() public { - bytes32 computed = EfficientHashLib.hash(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); - bytes32[] memory a = EfficientHashLib.malloc(14); - for (uint256 i; i != 14; ++i) { - EfficientHashLib.set(a, i, i + 1); - } - assertEq(computed, EfficientHashLib.hash(a)); - } -} diff --git a/grouperBot/lib/solady/test/EnumerableMapLib.t.sol b/grouperBot/lib/solady/test/EnumerableMapLib.t.sol deleted file mode 100644 index bb018b2..0000000 --- a/grouperBot/lib/solady/test/EnumerableMapLib.t.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {EnumerableMapLib} from "../src/utils/EnumerableMapLib.sol"; - -contract EnumerableMapLibTest is SoladyTest { - using EnumerableMapLib for *; - - EnumerableMapLib.AddressToUint256Map map; - - struct _TestTemps { - bool exists; - address key; - uint256 value; - address[] keys; - } - - function testEnumerableMap(bytes32) public { - address key0 = _randomNonZeroAddress(); - address key1 = _randomNonZeroAddress(); - uint256 value0 = _random(); - uint256 value1 = _random(); - _TestTemps memory t; - - assertFalse(map.contains(key0)); - assertTrue(map.set(key0, value0)); - assertTrue(map.contains(key0)); - - if (key0 != key1) { - (t.exists, t.value) = map.tryGet(key0); - assertTrue(t.exists); - assertEq(t.value, value0); - (t.exists, t.value) = map.tryGet(key1); - assertFalse(t.exists); - assertEq(t.value, 0); - vm.expectRevert(EnumerableMapLib.EnumerableMapKeyNotFound.selector); - this.get(key1); - assertEq(this.get(key0), value0); - } - - assertEq(map.length(), 1); - assertFalse(map.set(key0, value0)); - assertEq(map.length(), 1); - - if (key0 != key1) { - assertTrue(map.set(key1, value1)); - assertEq(map.length(), 2); - - (t.key, t.value) = map.at(0); - assertEq(t.key, key0); - assertEq(t.value, value0); - (t.key, t.value) = map.at(1); - assertEq(t.key, key1); - assertEq(t.value, value1); - - t.keys = map.keys(); - assertEq(t.keys.length, 2); - assertEq(t.keys[0], key0); - assertEq(t.keys[1], key1); - - assertTrue(map.remove(key0)); - assertEq(map.length(), 1); - assertFalse(map.remove(key0)); - assertEq(map.length(), 1); - } else { - t.keys = map.keys(); - assertEq(t.keys.length, 1); - assertEq(t.keys[0], key0); - - assertTrue(map.remove(key0)); - assertEq(map.length(), 0); - assertFalse(map.remove(key0)); - assertEq(map.length(), 0); - } - } - - function get(address key) public view returns (uint256) { - return map.get(key); - } - - function testMapUpdate() public { - for (uint256 i; i < 10; ++i) { - _testMapUpdate(i); - } - } - - function _testMapUpdate(uint256 cap) internal { - for (uint256 i; i < cap; ++i) { - this.update(address(uint160(i)), i, true, cap); - } - vm.expectRevert(bytes4(keccak256("ExceedsCapacity()"))); - this.update(address(uint160(cap)), _random(), true, cap); - - for (uint256 i; i < cap; ++i) { - this.update(address(uint160(i)), i, true, cap); - } - - for (uint256 i; i < cap; ++i) { - assertEq(map.get(address(uint160(i))), i); - } - for (uint256 i; i < cap; ++i) { - this.update(address(uint160(i)), i, false, cap); - address[] memory keys = map.keys(); - assertEq(keys.length, cap - 1 - i); - for (uint256 j; j < keys.length; ++j) { - assertEq(map.get(keys[j]), uint160(keys[j])); - } - } - } - - function update(address key, uint256 value, bool isAdd, uint256 cap) public { - map.update(key, value, isAdd, cap); - } -} diff --git a/grouperBot/lib/solady/test/EnumerableRoles.t.sol b/grouperBot/lib/solady/test/EnumerableRoles.t.sol deleted file mode 100644 index ebc0c4e..0000000 --- a/grouperBot/lib/solady/test/EnumerableRoles.t.sol +++ /dev/null @@ -1,323 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {LibSort} from "../src/utils/LibSort.sol"; -import {LibPRNG} from "../src/utils/LibPRNG.sol"; -import {DynamicArrayLib} from "../src/utils/DynamicArrayLib.sol"; -import {EnumerableSetLib} from "../src/utils/EnumerableSetLib.sol"; -import "./utils/SoladyTest.sol"; -import "./utils/mocks/MockEnumerableRoles.sol"; - -contract EnumerableRolesTest is SoladyTest { - using DynamicArrayLib for *; - using EnumerableSetLib for EnumerableSetLib.AddressSet; - using EnumerableSetLib for EnumerableSetLib.Uint256Set; - - event RoleSet(address indexed holder, uint256 indexed role, bool indexed active); - - MockEnumerableRoles mockEnumerableRoles; - - function setUp() public { - mockEnumerableRoles = new MockEnumerableRoles(); - mockEnumerableRoles.setMaxRole(type(uint256).max); - mockEnumerableRoles.setOwner(address(this)); - } - - function testStorageLayoutTrick(uint256 role, uint32 slotSeed, address holder) public { - bytes32 rootSlot; - bytes32 positionSlot; - holder = _brutalized(holder); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(0x18, holder) - mstore(0x04, slotSeed) - mstore(0x00, role) - rootSlot := keccak256(0x00, 0x24) - positionSlot := keccak256(0x00, 0x38) - mstore(0x24, shl(96, holder)) - if iszero(eq(keccak256(0x00, 0x24), rootSlot)) { invalid() } - if iszero(eq(keccak256(0x00, 0x38), positionSlot)) { invalid() } - if iszero(eq(mload(0x40), m)) { invalid() } - } - assertEq(positionSlot, keccak256(abi.encodePacked(role, slotSeed, holder))); - assertEq(rootSlot, keccak256(abi.encodePacked(role, slotSeed))); - } - - function testIsContractOwner(address owner, address pranker, bool ownerReverts) public { - mockEnumerableRoles.setOwner(owner); - mockEnumerableRoles.setOwnerReverts(ownerReverts); - while (pranker == address(0)) pranker = _randomNonZeroAddress(); - if (pranker != owner || ownerReverts) { - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - } - vm.prank(pranker); - mockEnumerableRoles.setRole(address(1), 0, true); - } - - function _roleHolders(uint256 role) - internal - pure - returns (EnumerableSetLib.AddressSet storage holders) - { - /// @solidity memory-safe-assembly - assembly { - holders.slot := add(role, 0x97) - } - } - - function testSetRoleReverts(address holder, uint256 role, uint256 maxRole, bool maxRoleReverts) - public - { - mockEnumerableRoles.setMaxRole(maxRole); - mockEnumerableRoles.setMaxRoleReverts(maxRoleReverts); - bool active = _randomChance(2); - if (_randomChance(64)) { - mockEnumerableRoles.setOwner(address(1)); - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - mockEnumerableRoles.setRole(holder, role, active); - return; - } - if (role > maxRole && !maxRoleReverts) { - vm.expectRevert(EnumerableRoles.InvalidRole.selector); - mockEnumerableRoles.setRole(holder, role, active); - } else if (holder == address(0)) { - vm.expectRevert(EnumerableRoles.RoleHolderIsZeroAddress.selector); - mockEnumerableRoles.setRole(holder, role, active); - } else { - vm.expectEmit(true, true, true, true); - emit RoleSet(_cleaned(holder), role, active); - mockEnumerableRoles.setRole(holder, role, active); - } - } - - struct _TestTemps { - address[] holders; - uint256[][] roles; - uint256[][] rolesLookup; - uint256[] combinedRoles; - } - - function testHasAnyRoles(bytes32) public { - uint256[] memory rolesToSet = _sampleRoles(_randomUniform() & 7); - uint256[] memory rolesToCheck = _sampleRoles(_randomUniform() & 7); - address holder = _randomNonZeroAddress(); - unchecked { - for (uint256 i; i != rolesToSet.length; ++i) { - mockEnumerableRoles.setRole(holder, rolesToSet.get(i), true); - } - } - LibSort.insertionSort(rolesToSet); - LibSort.uniquifySorted(rolesToSet); - LibSort.insertionSort(rolesToCheck); - LibSort.uniquifySorted(rolesToCheck); - uint256 intersectionLength = LibSort.intersection(rolesToSet, rolesToCheck).length; - if (_randomChance(32)) { - uint256 numFound; - for (uint256 i; i != rolesToCheck.length; ++i) { - if (mockEnumerableRoles.hasRole(holder, rolesToCheck.get(i))) ++numFound; - } - assertEq(intersectionLength, numFound); - } - assertEq( - mockEnumerableRoles.hasAnyRoles(holder, _encodeRolesToCheck(rolesToCheck)), - intersectionLength != 0 - ); - - if (_randomChance(8)) { - mockEnumerableRoles.setAllowedRolesEncoded(_encodeRolesToCheck(rolesToCheck)); - address pranker = address(this); - if (_randomChance(2)) pranker = holder; - if (_randomChance(2)) pranker = _randomNonZeroAddress(); - vm.startPrank(pranker); - if (pranker == address(this)) { - mockEnumerableRoles.guardedByOnlyOwnerOrRoles(); - if (pranker != holder) { - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - } - mockEnumerableRoles.guardedByOnlyRoles(); - } else if (pranker == holder && pranker != address(this)) { - if (intersectionLength == 0) { - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - } - mockEnumerableRoles.guardedByOnlyOwnerOrRoles(); - if (intersectionLength == 0) { - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - } - mockEnumerableRoles.guardedByOnlyRoles(); - } else { - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - mockEnumerableRoles.guardedByOnlyOwnerOrRoles(); - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - mockEnumerableRoles.guardedByOnlyRoles(); - } - vm.stopPrank(); - } - } - - function _encodeRolesToCheck(uint256[] memory roles) internal returns (bytes memory) { - if (_randomChance(2)) { - bytes memory dirt; - uint256 dirtLength = _randomUniform() & 31; - uint256 dirtBits = _random(); - /// @solidity memory-safe-assembly - assembly { - dirt := mload(0x40) - mstore(dirt, dirtLength) - mstore(add(dirt, 0x20), dirtBits) - mstore(0x40, add(dirt, 0x40)) - } - return abi.encodePacked(roles, dirt); - } else { - return abi.encodePacked(roles); - } - } - - function testSetAndGetRolesDifferential(bytes32) public { - uint256[] memory roles; - address[] memory holders; - while (roles.length == 0 || holders.length == 0) { - roles = _sampleRoles(1 + (_randomUniform() & 7)); - holders = _sampleUniqueAddresses(16 + (_randomUniform() & 15)); - } - do { - for (uint256 q = _randomUniform() & 7; q != 0; --q) { - uint256 role = roles[_randomUniform() % roles.length]; - address holder = holders[_randomUniform() % holders.length]; - bool active = _randomChance(2); - mockEnumerableRoles.setRoleDirect(holder, role, active); - if (active) { - _roleHolders(role).add(holder); - } else { - _roleHolders(role).remove(holder); - } - assertEq(mockEnumerableRoles.hasRole(holder, role), active); - if (_randomChance(8)) _checkRoleHolders(roles); - } - } while (_randomChance(2)); - _checkRoleHolders(roles); - } - - function _checkRoleHolders(uint256[] memory roles) internal tempMemory { - for (uint256 i; i != roles.length; ++i) { - uint256 role = roles[i]; - address[] memory expected = _roleHolders(role).values(); - LibSort.insertionSort(expected); - assertEq(_sortedRoleHolders(role), expected); - uint256 n = _roleHolders(role).length(); - assertEq(mockEnumerableRoles.roleHolderCount(role), n); - assertEq(expected.length, n); - } - } - - function testOnlyOwnerOrRole(uint256 allowedRole, uint256 holderRole) public { - address holder = _randomUniqueHashedAddress(); - assertEq(mockEnumerableRoles.owner(), address(this)); - if (holder == address(this)) return; - mockEnumerableRoles.setAllowedRole(allowedRole); - mockEnumerableRoles.setRoleDirect(holder, holderRole, true); - if (_randomChance(32)) { - mockEnumerableRoles.guardedByOnlyOwnerOrRole(); - } - if (holderRole != allowedRole) { - vm.prank(holder); - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - mockEnumerableRoles.guardedByOnlyOwnerOrRole(); - } else { - vm.prank(holder); - mockEnumerableRoles.guardedByOnlyOwnerOrRole(); - } - } - - function testSetAndGetRoles(bytes32) public { - _TestTemps memory t; - t.holders = _sampleUniqueAddresses(_randomUniform() & 7); - t.roles = new uint256[][](t.holders.length); - t.rolesLookup = new uint256[][](t.holders.length); - unchecked { - for (uint256 i; i != t.holders.length; ++i) { - uint256[] memory roles = _sampleRoles(_randomUniform() & 7); - t.roles[i] = roles; - roles = LibSort.copy(roles); - LibSort.insertionSort(roles); - LibSort.uniquifySorted(roles); - t.rolesLookup[i] = roles; - t.combinedRoles = LibSort.union(roles, t.combinedRoles); - } - - for (uint256 i; i != t.holders.length; ++i) { - uint256[] memory roles = t.roles[i]; - for (uint256 j; j != roles.length; ++j) { - mockEnumerableRoles.setRoleDirect(t.holders[i], roles[j], true); - } - } - - if (_randomChance(2)) { - for (uint256 i; i < t.combinedRoles.length; ++i) { - if (!_randomChance(8)) continue; - uint256 role = t.combinedRoles.get(i); - DynamicArrayLib.DynamicArray memory expected; - for (uint256 j; j != t.holders.length; ++j) { - if (LibSort.inSorted(t.rolesLookup[j], role)) { - expected.p(t.holders[j]); - } - } - LibSort.insertionSort(expected.data); - assertEq(abi.encode(expected.data), abi.encode(_sortedRoleHolders(role))); - } - } - - if (_randomChance(2)) { - for (uint256 i; i != t.holders.length; ++i) { - uint256[] memory roles = t.roles[i]; - for (uint256 j; j != roles.length; ++j) { - mockEnumerableRoles.setRoleDirect(t.holders[i], roles[j], false); - } - } - - for (uint256 i; i < t.combinedRoles.length; ++i) { - uint256 role = t.combinedRoles.get(i); - assertEq(mockEnumerableRoles.roleHolders(role).length, 0); - assertEq(mockEnumerableRoles.roleHolderCount(role), 0); - } - } - } - } - - function _sortedRoleHolders(uint256 role) internal returns (address[] memory result) { - result = mockEnumerableRoles.roleHolders(role); - if (result.length != 0) { - if (_randomChance(8)) { - uint256 j = _randomUniform() % result.length; - assertEq(mockEnumerableRoles.roleHolderAt(role, j), result[j]); - assertEq(mockEnumerableRoles.roleHolderCount(role), result.length); - j = _bound(_randomUniform(), 0, result.length + 10); - if (j >= result.length) { - vm.expectRevert(EnumerableRoles.RoleHoldersIndexOutOfBounds.selector); - mockEnumerableRoles.roleHolderAt(role, j); - } - } - LibSort.insertionSort(result); - } - } - - function _sampleUniqueAddresses(uint256 n) internal returns (address[] memory) { - unchecked { - uint256[] memory a = DynamicArrayLib.malloc(n); - for (uint256 i; i != n; ++i) { - a.set(i, _randomUniqueHashedAddress()); - } - return a.asAddressArray(); - } - } - - function _sampleRoles(uint256 n) internal returns (uint256[] memory roles) { - unchecked { - uint256 m = 0xf00000000000000000000000000000000000000000000000000000000000000f; - roles = DynamicArrayLib.malloc(n); - for (uint256 i; i != n; ++i) { - roles.set(i, _randomUniform() & m); - } - } - } -} diff --git a/grouperBot/lib/solady/test/EnumerableSetLib.t.sol b/grouperBot/lib/solady/test/EnumerableSetLib.t.sol deleted file mode 100644 index a8964ba..0000000 --- a/grouperBot/lib/solady/test/EnumerableSetLib.t.sol +++ /dev/null @@ -1,907 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {EnumerableSetLib} from "../src/utils/EnumerableSetLib.sol"; -import {LibSort} from "../src/utils/LibSort.sol"; -import {LibPRNG} from "../src/utils/LibPRNG.sol"; - -contract EnumerableSetLibTest is SoladyTest { - using EnumerableSetLib for *; - using LibPRNG for *; - - uint256 private constant _ZERO_SENTINEL = 0xfbb67fda52d4bfb8bf; - - EnumerableSetLib.AddressSet addressSet; - EnumerableSetLib.AddressSet addressSet2; - - EnumerableSetLib.Bytes32Set bytes32Set; - EnumerableSetLib.Bytes32Set bytes32Set2; - - EnumerableSetLib.Uint256Set uint256Set; - EnumerableSetLib.Int256Set int256Set; - - EnumerableSetLib.Uint8Set uint8Set; - - function testEnumerableAddressSetNoStorageCollision() public { - addressSet.add(address(1)); - assertEq(addressSet2.contains(address(1)), false); - addressSet2.add(address(2)); - assertEq(addressSet.contains(address(1)), true); - assertEq(addressSet2.contains(address(1)), false); - assertEq(addressSet.contains(address(2)), false); - addressSet.add(address(2)); - assertEq(addressSet.contains(address(2)), true); - assertEq(addressSet2.contains(address(1)), false); - addressSet2.add(address(1)); - assertEq(addressSet.contains(address(2)), true); - assertEq(addressSet2.contains(address(1)), true); - } - - function testEnumerableBytes32SetNoStorageCollision() public { - bytes32Set.add(bytes32(uint256(1))); - assertEq(bytes32Set2.contains(bytes32(uint256(1))), false); - bytes32Set2.add(bytes32(uint256(2))); - assertEq(bytes32Set.contains(bytes32(uint256(1))), true); - assertEq(bytes32Set2.contains(bytes32(uint256(1))), false); - assertEq(bytes32Set.contains(bytes32(uint256(2))), false); - bytes32Set.add(bytes32(uint256(2))); - assertEq(bytes32Set.contains(bytes32(uint256(2))), true); - assertEq(bytes32Set2.contains(bytes32(uint256(1))), false); - bytes32Set2.add(bytes32(uint256(1))); - assertEq(bytes32Set.contains(bytes32(uint256(2))), true); - assertEq(bytes32Set2.contains(bytes32(uint256(1))), true); - } - - function testEnumerableAddressSetBasic() public { - assertEq(addressSet.length(), 0); - assertEq(addressSet.contains(address(1)), false); - assertEq(addressSet.contains(address(2)), false); - assertEq(addressSet.contains(address(3)), false); - assertEq(addressSet.contains(address(4)), false); - assertEq(addressSet.contains(address(5)), false); - - assertTrue(addressSet.add(address(1))); - assertFalse(addressSet.add(address(1))); - - assertEq(addressSet.length(), 1); - assertEq(addressSet.contains(address(1)), true); - assertEq(addressSet.contains(address(2)), false); - assertEq(addressSet.contains(address(3)), false); - assertEq(addressSet.contains(address(4)), false); - assertEq(addressSet.contains(address(5)), false); - - assertTrue(addressSet.add(address(2))); - assertFalse(addressSet.add(address(2))); - - assertEq(addressSet.length(), 2); - assertEq(addressSet.contains(address(1)), true); - assertEq(addressSet.contains(address(2)), true); - assertEq(addressSet.contains(address(3)), false); - assertEq(addressSet.contains(address(4)), false); - assertEq(addressSet.contains(address(5)), false); - - assertTrue(addressSet.add(address(3))); - assertFalse(addressSet.add(address(3))); - - assertEq(addressSet.length(), 3); - assertEq(addressSet.contains(address(1)), true); - assertEq(addressSet.contains(address(2)), true); - assertEq(addressSet.contains(address(3)), true); - assertEq(addressSet.contains(address(4)), false); - assertEq(addressSet.contains(address(5)), false); - - assertTrue(addressSet.add(address(4))); - assertFalse(addressSet.add(address(4))); - - assertEq(addressSet.length(), 4); - assertEq(addressSet.contains(address(1)), true); - assertEq(addressSet.contains(address(2)), true); - assertEq(addressSet.contains(address(3)), true); - assertEq(addressSet.contains(address(4)), true); - assertEq(addressSet.contains(address(5)), false); - - assertTrue(addressSet.add(address(5))); - assertFalse(addressSet.add(address(5))); - - assertEq(addressSet.length(), 5); - assertEq(addressSet.contains(address(1)), true); - assertEq(addressSet.contains(address(2)), true); - assertEq(addressSet.contains(address(3)), true); - assertEq(addressSet.contains(address(4)), true); - assertEq(addressSet.contains(address(5)), true); - } - - function testEnumerableBytes32SetBasic() public { - assertEq(bytes32Set.length(), 0); - assertEq(bytes32Set.contains(bytes32(uint256(1))), false); - assertEq(bytes32Set.contains(bytes32(uint256(2))), false); - assertEq(bytes32Set.contains(bytes32(uint256(3))), false); - assertEq(bytes32Set.contains(bytes32(uint256(4))), false); - assertEq(bytes32Set.contains(bytes32(uint256(5))), false); - - assertTrue(bytes32Set.add(bytes32(uint256(1)))); - assertFalse(bytes32Set.add(bytes32(uint256(1)))); - - assertEq(bytes32Set.length(), 1); - assertEq(bytes32Set.contains(bytes32(uint256(1))), true); - assertEq(bytes32Set.contains(bytes32(uint256(2))), false); - assertEq(bytes32Set.contains(bytes32(uint256(3))), false); - assertEq(bytes32Set.contains(bytes32(uint256(4))), false); - assertEq(bytes32Set.contains(bytes32(uint256(5))), false); - - assertTrue(bytes32Set.add(bytes32(uint256(2)))); - assertFalse(bytes32Set.add(bytes32(uint256(2)))); - - assertEq(bytes32Set.length(), 2); - assertEq(bytes32Set.contains(bytes32(uint256(1))), true); - assertEq(bytes32Set.contains(bytes32(uint256(2))), true); - assertEq(bytes32Set.contains(bytes32(uint256(3))), false); - assertEq(bytes32Set.contains(bytes32(uint256(4))), false); - assertEq(bytes32Set.contains(bytes32(uint256(5))), false); - - assertTrue(bytes32Set.add(bytes32(uint256(3)))); - assertFalse(bytes32Set.add(bytes32(uint256(3)))); - - assertEq(bytes32Set.length(), 3); - assertEq(bytes32Set.contains(bytes32(uint256(1))), true); - assertEq(bytes32Set.contains(bytes32(uint256(2))), true); - assertEq(bytes32Set.contains(bytes32(uint256(3))), true); - assertEq(bytes32Set.contains(bytes32(uint256(4))), false); - assertEq(bytes32Set.contains(bytes32(uint256(5))), false); - - assertTrue(bytes32Set.add(bytes32(uint256(4)))); - assertFalse(bytes32Set.add(bytes32(uint256(4)))); - - assertEq(bytes32Set.length(), 4); - assertEq(bytes32Set.contains(bytes32(uint256(1))), true); - assertEq(bytes32Set.contains(bytes32(uint256(2))), true); - assertEq(bytes32Set.contains(bytes32(uint256(3))), true); - assertEq(bytes32Set.contains(bytes32(uint256(4))), true); - assertEq(bytes32Set.contains(bytes32(uint256(5))), false); - - assertTrue(bytes32Set.add(bytes32(uint256(5)))); - assertFalse(bytes32Set.add(bytes32(uint256(5)))); - - assertEq(bytes32Set.length(), 5); - assertEq(bytes32Set.contains(bytes32(uint256(1))), true); - assertEq(bytes32Set.contains(bytes32(uint256(2))), true); - assertEq(bytes32Set.contains(bytes32(uint256(3))), true); - assertEq(bytes32Set.contains(bytes32(uint256(4))), true); - assertEq(bytes32Set.contains(bytes32(uint256(5))), true); - } - - function testEnumerableAddressSetBasic2() public { - addressSet.add(address(1)); - addressSet.add(address(2)); - - addressSet.remove(address(1)); - assertEq(addressSet.length(), 1); - addressSet.remove(address(2)); - assertEq(addressSet.length(), 0); - - addressSet.add(address(1)); - addressSet.add(address(2)); - - addressSet.remove(address(2)); - assertEq(addressSet.length(), 1); - addressSet.remove(address(1)); - assertEq(addressSet.length(), 0); - - addressSet.add(address(1)); - addressSet.add(address(2)); - addressSet.add(address(3)); - - addressSet.remove(address(3)); - assertEq(addressSet.length(), 2); - addressSet.remove(address(2)); - assertEq(addressSet.length(), 1); - addressSet.remove(address(1)); - assertEq(addressSet.length(), 0); - - addressSet.add(address(1)); - addressSet.add(address(2)); - addressSet.add(address(3)); - - addressSet.remove(address(1)); - assertEq(addressSet.length(), 2); - addressSet.remove(address(2)); - assertEq(addressSet.length(), 1); - addressSet.remove(address(3)); - assertEq(addressSet.length(), 0); - } - - function testEnumerableBytes32SetBasic2() public { - bytes32Set.add(bytes32(uint256(1))); - bytes32Set.add(bytes32(uint256(2))); - - bytes32Set.remove(bytes32(uint256(1))); - assertEq(bytes32Set.length(), 1); - bytes32Set.remove(bytes32(uint256(2))); - assertEq(bytes32Set.length(), 0); - - bytes32Set.add(bytes32(uint256(1))); - bytes32Set.add(bytes32(uint256(2))); - - bytes32Set.remove(bytes32(uint256(2))); - assertEq(bytes32Set.length(), 1); - bytes32Set.remove(bytes32(uint256(1))); - assertEq(bytes32Set.length(), 0); - - bytes32Set.add(bytes32(uint256(1))); - bytes32Set.add(bytes32(uint256(2))); - bytes32Set.add(bytes32(uint256(3))); - - bytes32Set.remove(bytes32(uint256(3))); - assertEq(bytes32Set.length(), 2); - bytes32Set.remove(bytes32(uint256(2))); - assertEq(bytes32Set.length(), 1); - bytes32Set.remove(bytes32(uint256(1))); - assertEq(bytes32Set.length(), 0); - - bytes32Set.add(bytes32(uint256(1))); - bytes32Set.add(bytes32(uint256(2))); - bytes32Set.add(bytes32(uint256(3))); - - bytes32Set.remove(bytes32(uint256(1))); - assertEq(bytes32Set.length(), 2); - bytes32Set.remove(bytes32(uint256(2))); - assertEq(bytes32Set.length(), 1); - bytes32Set.remove(bytes32(uint256(3))); - assertEq(bytes32Set.length(), 0); - } - - function testEnumerableSetFuzz(uint256 n) public { - if (_randomChance(2)) { - _testEnumerableAddressSetFuzz(n); - _testEnumerableBytes32SetFuzz(n); - } else { - if (_randomChance(2)) _testEnumerableAddressSetFuzz(); - if (_randomChance(2)) _testEnumerableBytes32SetFuzz(); - if (_randomChance(2)) _testEnumerableUint256SetFuzz(); - if (_randomChance(2)) _testEnumerableInt256SetFuzz(); - } - } - - function _testEnumerableAddressSetFuzz(uint256 n) internal { - unchecked { - LibPRNG.PRNG memory prng; - prng.state = n; - uint256[] memory additions = new uint256[](prng.next() % 16); - uint256 mask = _randomChance(2) ? 7 : 15; - - for (uint256 i; i != additions.length; ++i) { - uint256 x = prng.next() & mask; - additions[i] = x; - addressSet.add(_brutalized(address(uint160(x)))); - assertTrue(addressSet.contains(_brutalized(address(uint160(x))))); - } - LibSort.sort(additions); - LibSort.uniquifySorted(additions); - assertEq(addressSet.length(), additions.length); - { - address[] memory values = addressSet.values(); - _checkMemory(); - uint256[] memory valuesCasted = _toUints(values); - LibSort.sort(valuesCasted); - assertEq(valuesCasted, additions); - } - - uint256[] memory removals = new uint256[](prng.next() % 16); - for (uint256 i; i != removals.length; ++i) { - uint256 x = prng.next() & mask; - removals[i] = x; - addressSet.remove(_brutalized(address(uint160(x)))); - assertFalse(addressSet.contains(_brutalized(address(uint160(x))))); - } - LibSort.sort(removals); - LibSort.uniquifySorted(removals); - - { - uint256[] memory difference = LibSort.difference(additions, removals); - address[] memory values = addressSet.values(); - _checkMemory(); - if (_randomChance(8)) _checkAddressSetValues(values); - uint256[] memory valuesCasted = _toUints(values); - LibSort.sort(valuesCasted); - assertEq(valuesCasted, difference); - } - } - } - - function _testEnumerableAddressSetFuzz() internal { - uint256[] memory s = _makeArray(0); - do { - address r = address(uint160(_random())); - if (_randomChance(16)) _brutalizeMemory(); - if (_randomChance(2)) { - addressSet.add(r); - _addToArray(s, uint256(uint160(r))); - assertTrue(addressSet.contains(r)); - } else { - addressSet.remove(r); - _removeFromArray(s, uint256(uint160(r))); - assertFalse(addressSet.contains(r)); - } - if (_randomChance(16)) _brutalizeMemory(); - if (_randomChance(8)) { - _checkArraysSortedEq(_toUints(addressSet.values()), s); - } - assertEq(addressSet.length(), s.length); - if (s.length == 512) break; - } while (!_randomChance(8)); - assertEq(addressSet.length(), s.length); - _checkArraysSortedEq(_toUints(addressSet.values()), s); - if (_randomChance(4)) { - unchecked { - for (uint256 i; i != s.length; ++i) { - assertTrue(addressSet.contains(address(uint160(s[i])))); - } - } - } - } - - function _testEnumerableBytes32SetFuzz(uint256 n) internal { - unchecked { - LibPRNG.PRNG memory prng; - prng.state = n; - uint256[] memory additions = new uint256[](prng.next() % 16); - uint256 mask = _randomChance(2) ? 7 : 15; - - for (uint256 i; i != additions.length; ++i) { - uint256 x = prng.next() & mask; - additions[i] = x; - bytes32Set.add(bytes32(x)); - assertTrue(bytes32Set.contains(bytes32(x))); - } - LibSort.sort(additions); - LibSort.uniquifySorted(additions); - assertEq(bytes32Set.length(), additions.length); - { - bytes32[] memory values = bytes32Set.values(); - _checkMemory(); - uint256[] memory valuesCasted = _toUints(values); - LibSort.sort(valuesCasted); - assertEq(valuesCasted, additions); - } - - uint256[] memory removals = new uint256[](prng.next() % 16); - for (uint256 i; i != removals.length; ++i) { - uint256 x = prng.next() & mask; - removals[i] = x; - bytes32Set.remove(bytes32(x)); - assertFalse(bytes32Set.contains(bytes32(x))); - } - LibSort.sort(removals); - LibSort.uniquifySorted(removals); - - { - uint256[] memory difference = LibSort.difference(additions, removals); - bytes32[] memory values = bytes32Set.values(); - _checkMemory(); - if (_randomChance(8)) _checkBytes32SetValues(values); - uint256[] memory valuesCasted = _toUints(values); - LibSort.sort(valuesCasted); - assertEq(valuesCasted, difference); - } - } - } - - function _testEnumerableBytes32SetFuzz() internal { - uint256[] memory s = _makeArray(0); - do { - bytes32 r = bytes32(_random()); - if (_randomChance(16)) _brutalizeMemory(); - if (_randomChance(2)) { - bytes32Set.add(r); - _addToArray(s, uint256(r)); - assertTrue(bytes32Set.contains(r)); - } else { - bytes32Set.remove(r); - _removeFromArray(s, uint256(r)); - assertFalse(bytes32Set.contains(r)); - } - if (_randomChance(16)) _brutalizeMemory(); - if (_randomChance(16)) { - _checkArraysSortedEq(_toUints(bytes32Set.values()), s); - assertEq(bytes32Set.length(), s.length); - } - if (s.length == 512) break; - } while (!_randomChance(8)); - _checkArraysSortedEq(_toUints(bytes32Set.values()), s); - } - - function _testEnumerableUint256SetFuzz() public { - uint256[] memory s = _makeArray(0); - uint256 mask = _randomChance(2) ? 7 : type(uint256).max; - do { - uint256 r = _random() & mask; - if (_randomChance(2)) { - uint256Set.add(r); - _addToArray(s, r); - } else { - uint256Set.remove(r); - _removeFromArray(s, r); - } - if (_randomChance(8)) { - _checkArraysSortedEq(uint256Set.values(), s); - assertEq(uint256Set.length(), s.length); - } - if (s.length == 512) break; - } while (!_randomChance(16)); - _checkArraysSortedEq(uint256Set.values(), s); - if (_randomChance(4)) { - unchecked { - for (uint256 i; i != s.length; ++i) { - assertTrue(uint256Set.contains(s[i])); - } - } - } - } - - function _testEnumerableInt256SetFuzz() public { - uint256[] memory s = _makeArray(0); - do { - uint256 r = _random(); - if (_randomChance(2)) { - int256Set.add(int256(r)); - _addToArray(s, uint256(r)); - } else { - int256Set.remove(int256(r)); - _removeFromArray(s, uint256(r)); - } - if (_randomChance(16)) { - _checkArraysSortedEq(_toUints(int256Set.values()), s); - assertEq(int256Set.length(), s.length); - } - if (s.length == 512) break; - } while (!_randomChance(8)); - _checkArraysSortedEq(_toUints(int256Set.values()), s); - } - - function _checkArraysSortedEq(uint256[] memory a, uint256[] memory b) internal { - LibSort.sort(a); - LibSort.sort(b); - assertEq(a, b); - } - - function _checkAddressSetValues(address[] memory values) internal { - unchecked { - for (uint256 i; i != values.length; ++i) { - assertEq(addressSet.at(i), values[i]); - } - vm.expectRevert(EnumerableSetLib.IndexOutOfBounds.selector); - this.addressSetAt(_bound(_random(), values.length, type(uint256).max)); - } - } - - function _checkBytes32SetValues(bytes32[] memory values) internal { - unchecked { - for (uint256 i; i != values.length; ++i) { - assertEq(bytes32Set.at(i), values[i]); - } - vm.expectRevert(EnumerableSetLib.IndexOutOfBounds.selector); - this.bytes32SetAt(_bound(_random(), values.length, type(uint256).max)); - } - } - - function testEnumerableSetDifferential(bytes32) public { - address[] memory a; - uint256[] memory s = _makeArray(0); - while (a.length == 0) { - a = _sampleUniqueAddresses(_randomUniform() & 0xf); - } - do { - for (uint256 q = _randomUniform() & 7; q != 0; --q) { - address x = a[_randomUniform() % a.length]; - if (_randomChance(2)) { - uint256Set.add(uint160(x)); - addressSet.add(x); - _addToArray(s, uint160(x)); - } else { - uint256Set.remove(uint160(x)); - addressSet.remove(x); - _removeFromArray(s, uint160(x)); - } - } - } while (_randomChance(2)); - } - - function _checkDifferential(uint256[] memory s) internal tempMemory { - uint256[] memory uint256s = uint256Set.values(); - address[] memory addresses = addressSet.values(); - unchecked { - for (uint256 i; i < uint256s.length; ++i) { - assertEq(uint256Set.at(i), uint256s[i]); - } - for (uint256 i; i < addresses.length; ++i) { - assertEq(addressSet.at(i), addresses[i]); - } - } - LibSort.insertionSort(uint256s); - LibSort.insertionSort(addresses); - bytes memory encoded = abi.encode(addresses); - assertEq(encoded, abi.encode(uint256s)); - LibSort.insertionSort(s); - assertEq(encoded, abi.encode(s)); - } - - function _sampleUniqueAddresses(uint256 n) internal returns (address[] memory result) { - unchecked { - result = new address[](n); - for (uint256 i; i != n; ++i) { - result[i] = _randomUniqueHashedAddress(); - } - } - } - - function testEnumerableAddressSetRevertsOnSentinel(uint256) public { - do { - address a = address(uint160(_random())); - if (_randomChance(32)) { - a = address(uint160(_ZERO_SENTINEL)); - } - uint256 r = _random() % 3; - if (r == 0) { - if (a == address(uint160(_ZERO_SENTINEL))) { - vm.expectRevert(EnumerableSetLib.ValueIsZeroSentinel.selector); - } - this.addToAddressSet(a); - } - if (r == 1) { - if (a == address(uint160(_ZERO_SENTINEL))) { - vm.expectRevert(EnumerableSetLib.ValueIsZeroSentinel.selector); - } - this.addressSetContains(a); - } - if (r == 2) { - if (a == address(uint160(_ZERO_SENTINEL))) { - vm.expectRevert(EnumerableSetLib.ValueIsZeroSentinel.selector); - } - this.removeFromAddressSet(a); - } - } while (!_randomChance(2)); - } - - function testEnumerableBytes32SetRevertsOnSentinel(uint256) public { - do { - bytes32 a = bytes32(_random()); - if (_randomChance(32)) { - a = bytes32(_ZERO_SENTINEL); - } - uint256 r = _random() % 3; - if (r == 0) { - if (a == bytes32(_ZERO_SENTINEL)) { - vm.expectRevert(EnumerableSetLib.ValueIsZeroSentinel.selector); - } - this.addToBytes32Set(a); - } - if (r == 1) { - if (a == bytes32(_ZERO_SENTINEL)) { - vm.expectRevert(EnumerableSetLib.ValueIsZeroSentinel.selector); - } - this.bytes32SetContains(a); - } - if (r == 2) { - if (a == bytes32(_ZERO_SENTINEL)) { - vm.expectRevert(EnumerableSetLib.ValueIsZeroSentinel.selector); - } - this.removeFromBytes32Set(a); - } - } while (!_randomChance(2)); - } - - function testEnumerableUint8Set() public { - uint8[] memory ordinals = _flagsToOrdinals(0xff00000000ff); - unchecked { - for (uint256 i; i != ordinals.length; ++i) { - uint8Set.add(ordinals[i]); - } - uint8[] memory values = uint8Set.values(); - for (uint256 i; i != ordinals.length; ++i) { - assertEq(uint8Set.at(i), values[i]); - } - assertEq(values.length, 16); - } - } - - function testEnumerableUint8Set(uint256 flags, bytes32) public { - uint8[] memory ordinals = _flagsToOrdinals(flags); - bytes32 sortedHash = keccak256(abi.encodePacked(ordinals)); - _shuffle(ordinals); - unchecked { - for (uint256 i; i != ordinals.length; ++i) { - assertTrue(uint8Set.add(ordinals[i])); - } - if (_randomChance(16)) { - _shuffle(ordinals); - for (uint256 i; i != ordinals.length; ++i) { - assertFalse(uint8Set.add(ordinals[i])); - } - } - if (_randomChance(16)) { - for (uint256 i; i != 256; ++i) { - assertEq(uint8Set.contains(uint8(i)), flags & (1 << i) != 0); - } - } - uint8[] memory values = uint8Set.values(); - assertEq(keccak256(abi.encodePacked(values)), sortedHash); - assertEq(values.length, uint8Set.length()); - if (_randomChance(16)) { - for (uint256 i; i != ordinals.length; ++i) { - assertEq(uint8Set.at(i), values[i]); - } - vm.expectRevert(EnumerableSetLib.IndexOutOfBounds.selector); - this.uint8SetAt(_bound(_random(), ordinals.length, type(uint256).max)); - } - if (_randomChance(16)) { - _shuffle(ordinals); - for (uint256 i; i != ordinals.length; ++i) { - assertTrue(uint8Set.remove(ordinals[i])); - assertFalse(uint8Set.remove(ordinals[i])); - } - if (_randomChance(32)) { - for (uint256 i; i != 256; ++i) { - assertFalse(uint8Set.contains(uint8(i))); - } - } - assertEq(uint8Set.length(), 0); - } - } - } - - function _shuffle(uint8[] memory a) internal { - LibPRNG.PRNG memory prng; - prng.state = _random(); - uint256[] memory casted; - /// @solidity memory-safe-assembly - assembly { - casted := a - } - prng.shuffle(casted); - } - - function _flagsToOrdinals(uint256 flags) internal pure returns (uint8[] memory ordinals) { - ordinals = new uint8[](256); - uint256 n; - unchecked { - for (uint256 i; i != 256; ++i) { - if (flags & (1 << i) != 0) ordinals[n++] = uint8(i); - } - } - /// @solidity memory-safe-assembly - assembly { - mstore(ordinals, n) - } - } - - function uint8SetAt(uint256 i) public view returns (uint8) { - return uint8Set.at(i); - } - - function addToAddressSet(address a) public returns (bool) { - return addressSet.add(a); - } - - function addressSetContains(address a) public view returns (bool) { - return addressSet.contains(a); - } - - function removeFromAddressSet(address a) public returns (bool) { - return addressSet.remove(a); - } - - function addressSetAt(uint256 i) public view returns (address) { - return addressSet.at(i); - } - - function addToBytes32Set(bytes32 a) public returns (bool) { - return bytes32Set.add(a); - } - - function bytes32SetContains(bytes32 a) public view returns (bool) { - return bytes32Set.contains(a); - } - - function removeFromBytes32Set(bytes32 a) public returns (bool) { - return bytes32Set.remove(a); - } - - function bytes32SetAt(uint256 i) public view returns (bytes32) { - return bytes32Set.at(i); - } - - function _toUints(address[] memory a) private pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - function _toUints(int256[] memory a) private pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - function _toUints(bytes32[] memory a) private pure returns (uint256[] memory result) { - /// @solidity memory-safe-assembly - assembly { - result := a - } - } - - function _makeArray(uint256 size, uint256 maxCap) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, size) - mstore(0x40, add(result, shl(5, add(maxCap, 1)))) - } - } - - function _makeArray(uint256 size) internal pure returns (uint256[] memory result) { - require(size <= 512, "Size too big."); - result = _makeArray(size, 512); - } - - function _addToArray(uint256[] memory a, uint256 x) internal pure { - /// @solidity memory-safe-assembly - assembly { - let exists := 0 - let n := mload(a) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - let o := add(add(a, 0x20), shl(5, i)) - if eq(mload(o), x) { - exists := 1 - break - } - } - if iszero(exists) { - n := add(n, 1) - mstore(add(a, shl(5, n)), x) - mstore(a, n) - } - } - } - - function _removeFromArray(uint256[] memory a, uint256 x) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - let o := add(add(a, 0x20), shl(5, i)) - if eq(mload(o), x) { - mstore(o, mload(add(a, shl(5, n)))) - mstore(a, sub(n, 1)) - break - } - } - } - } - - function testEnumerableAddressSetUpdate() public { - uint256 cap = 3; - assertTrue(this.updateAddressSet(address(0), true, cap)); - assertTrue(this.updateAddressSet(address(1), true, cap)); - assertTrue(this.updateAddressSet(address(2), true, cap)); - assertFalse(this.updateAddressSet(address(2), true, cap)); - - vm.expectRevert(EnumerableSetLib.ExceedsCapacity.selector); - this.updateAddressSet(address(3), true, cap); - - assertFalse(this.updateAddressSet(address(3), false, cap)); - assertTrue(this.updateAddressSet(address(2), false, cap)); - assertFalse(this.updateAddressSet(address(2), false, cap)); - assertTrue(this.updateAddressSet(address(3), true, cap)); - } - - function testEnumerableBytes32SetUpdate(bytes32) public { - uint256 cap = 3; - assertTrue(this.updateBytes32Set(bytes32("0"), true, cap)); - assertTrue(this.updateBytes32Set(bytes32("1"), true, cap)); - assertTrue(this.updateBytes32Set(bytes32("2"), true, cap)); - assertFalse(this.updateBytes32Set(bytes32("2"), true, cap)); - - vm.expectRevert(EnumerableSetLib.ExceedsCapacity.selector); - this.updateBytes32Set(bytes32("3"), true, cap); - - assertFalse(this.updateBytes32Set(bytes32("3"), false, cap)); - assertTrue(this.updateBytes32Set(bytes32("2"), false, cap)); - assertFalse(this.updateBytes32Set(bytes32("2"), false, cap)); - assertTrue(this.updateBytes32Set(bytes32("3"), true, cap)); - } - - function testEnumerableUint8SetUpdate(bytes32) public { - uint256 cap = 3; - assertTrue(this.updateUint8Set(0, true, cap)); - assertTrue(this.updateUint8Set(1, true, cap)); - assertTrue(this.updateUint8Set(2, true, cap)); - assertFalse(this.updateUint8Set(2, true, cap)); - - vm.expectRevert(EnumerableSetLib.ExceedsCapacity.selector); - this.updateUint8Set(3, true, cap); - - assertFalse(this.updateUint8Set(3, false, cap)); - assertTrue(this.updateUint8Set(2, false, cap)); - assertFalse(this.updateUint8Set(2, false, cap)); - assertTrue(this.updateUint8Set(3, true, cap)); - } - - function updateAddressSet(address value, bool isAdd, uint256 cap) public returns (bool) { - return addressSet.update(value, isAdd, cap); - } - - function updateBytes32Set(bytes32 value, bool isAdd, uint256 cap) public returns (bool) { - return bytes32Set.update(value, isAdd, cap); - } - - function updateUint8Set(uint8 value, bool isAdd, uint256 cap) public returns (bool) { - return uint8Set.update(value, isAdd, cap); - } - - function testAddressSetIndexOf(bytes32 r) public { - LibPRNG.PRNG memory prng; - prng.state = uint256(r); - address[] memory a = new address[](_bound(_random(), 0, 16)); - - for (uint256 i; i != a.length; ++i) { - address value = address(uint160(prng.next())); - addressSet.add(value); - a[i] = value; - } - - if (a.length != 0) { - uint256 i = _random() % a.length; - address value = a[i]; - assertEq(addressSet.indexOf(value), i); - assertEq(addressSet.at(addressSet.indexOf(value)), value); - if (_randomChance(2)) { - value = address(bytes20(keccak256(abi.encode(value, value, "abcdef")))); - assertEq(addressSet.indexOf(value), EnumerableSetLib.NOT_FOUND); - } - } - } - - function testBytes32SetIndexOf(bytes32 r) public { - LibPRNG.PRNG memory prng; - prng.state = uint256(r); - bytes32[] memory a = new bytes32[](_bound(_random(), 0, 16)); - - for (uint256 i; i != a.length; ++i) { - bytes32 value = bytes32(prng.next()); - bytes32Set.add(value); - a[i] = value; - } - - if (a.length != 0) { - uint256 i = _random() % a.length; - bytes32 value = a[i]; - assertEq(bytes32Set.indexOf(value), i); - assertEq(bytes32Set.at(bytes32Set.indexOf(value)), value); - if (_randomChance(2)) { - value = keccak256(abi.encode(value, value, "abcdef")); - assertEq(bytes32Set.indexOf(value), EnumerableSetLib.NOT_FOUND); - } - } - } - - function testEnumerableUint8SetIndexOf(uint256 flags, uint8 value) public { - uint8[] memory ordinals = _flagsToOrdinals(flags); - unchecked { - for (uint256 i; i != ordinals.length; ++i) { - uint8Set.add(ordinals[i]); - } - if (uint8Set.contains(value)) { - assertEq(uint8Set.at(uint8Set.indexOf(value)), value); - } else { - assertEq(uint8Set.indexOf(value), EnumerableSetLib.NOT_FOUND); - } - } - } -} diff --git a/grouperBot/lib/solady/test/FixedPointMathLib.t.sol b/grouperBot/lib/solady/test/FixedPointMathLib.t.sol deleted file mode 100644 index d9dcb2d..0000000 --- a/grouperBot/lib/solady/test/FixedPointMathLib.t.sol +++ /dev/null @@ -1,2432 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {FixedPointMathLib} from "../src/utils/FixedPointMathLib.sol"; - -contract FixedPointMathLibTest is SoladyTest { - function testExpWad() public { - assertEq(FixedPointMathLib.expWad(-41446531673892822312), 1); - assertEq(FixedPointMathLib.expWad(-41446531673892822313), 0); - - assertEq(FixedPointMathLib.expWad(-3e18), 49787068367863942); - assertEq(FixedPointMathLib.expWad(-2e18), 135335283236612691); - assertEq(FixedPointMathLib.expWad(-1e18), 367879441171442321); - - assertEq(FixedPointMathLib.expWad(-0.5e18), 606530659712633423); - assertEq(FixedPointMathLib.expWad(-0.3e18), 740818220681717866); - - assertEq(FixedPointMathLib.expWad(0), 1000000000000000000); - - assertEq(FixedPointMathLib.expWad(0.3e18), 1349858807576003103); - assertEq(FixedPointMathLib.expWad(0.5e18), 1648721270700128146); - - assertEq(FixedPointMathLib.expWad(1e18), 2718281828459045235); - assertEq(FixedPointMathLib.expWad(2e18), 7389056098930650227); - assertEq(FixedPointMathLib.expWad(3e18), 20085536923187667741); - // True value: 20085536923187667740.92 - - assertEq(FixedPointMathLib.expWad(10e18), 220264657948067165169_80); - // True value: 22026465794806716516957.90 - // Relative error 9.987984547746668e-22 - - assertEq(FixedPointMathLib.expWad(50e18), 5184705528587072464_148529318587763226117); - // True value: 5184705528587072464_087453322933485384827.47 - // Relative error: 1.1780031733243328e-20 - - assertEq( - FixedPointMathLib.expWad(100e18), - 268811714181613544841_34666106240937146178367581647816351662017 - ); - // True value: 268811714181613544841_26255515800135873611118773741922415191608 - // Relative error: 3.128803544297531e-22 - - assertEq( - FixedPointMathLib.expWad(135305999368893231588), - 578960446186580976_50144101621524338577433870140581303254786265309376407432913 - ); - // True value: 578960446186580976_49816762928942336782129491980154662247847962410455084893091 - // Relative error: 5.653904247484822e-21 - } - - // Notes on lambertW0Wad: - // - // If you want to attempt finding a better approximation, look at - // https://github.com/recmo/experiment-solexp/blob/main/approximate_mpmath.ipynb - // I somehow can't get it to reproduce the approximation constants for `lnWad`. - // Let me know if you can get the code to reproduce the approximation constants for `lnWad`. - - event TestingLambertW0WadMonotonicallyIncreasing( - int256 a, int256 b, int256 w0a, int256 w0b, bool success, uint256 gasUsed - ); - - int256 internal constant _ONE_DIV_EXP = 367879441171442321; - int256 internal constant _LAMBERT_W0_MIN = -367879441171442321; - int256 internal constant _EXP = 2718281828459045235; - int256 internal constant _WAD = 10 ** 18; - - function testLambertW0WadKnownValues() public { - _checkLambertW0Wad(0, 0); - _checkLambertW0Wad(1, 1); - _checkLambertW0Wad(2, 2); - _checkLambertW0Wad(3, 2); - _checkLambertW0Wad(131071, 131070); - _checkLambertW0Wad(17179869183, 17179868887); - _checkLambertW0Wad(1000000000000000000, 567143290409783872); - _checkLambertW0Wad(-3678794411715, -3678807945318); - _checkLambertW0Wad(_LAMBERT_W0_MIN, -999999999741585709); - // These are exact values. - _checkLambertW0Wad(2 ** 255 - 1, 130435123404408416612); - _checkLambertW0Wad(2 ** 254 - 1, 129747263755102316133); - _checkLambertW0Wad(2 ** 253 - 1, 129059431996357330139); - _checkLambertW0Wad(2 ** 252 - 1, 128371628422812486425); - _checkLambertW0Wad(2 ** 251 - 1, 127683853333788079721); - _checkLambertW0Wad(2 ** 250 - 1, 126996107033385166927); - _checkLambertW0Wad(2 ** 249 - 1, 126308389830587715420); - _checkLambertW0Wad(2 ** 248 - 1, 125620702039367489656); - _checkLambertW0Wad(2 ** 247 - 1, 124933043978791764502); - _checkLambertW0Wad(2 ** 246 - 1, 124245415973133957088); - _checkLambertW0Wad(2 ** 245 - 1, 123557818351987272451); - _checkLambertW0Wad(2 ** 244 - 1, 122870251450381461880); - _checkLambertW0Wad(2 ** 243 - 1, 122182715608902796703); - _checkLambertW0Wad(2 ** 242 - 1, 121495211173817364188); - _checkLambertW0Wad(2 ** 241 - 1, 120807738497197796422); - _checkLambertW0Wad(2 ** 240 - 1, 120120297937053547320); - _checkLambertW0Wad(2 ** 239 - 1, 119432889857464837488); - _checkLambertW0Wad(2 ** 238 - 1, 118745514628720391363); - _checkLambertW0Wad(2 ** 237 - 1, 118058172627459096009); - _checkLambertW0Wad(2 ** 236 - 1, 117370864236815716134); - _checkLambertW0Wad(2 ** 235 - 1, 116683589846570805279); - _checkLambertW0Wad(2 ** 234 - 1, 115996349853304958814); - _checkLambertW0Wad(2 ** 233 - 1, 115309144660557560280); - _checkLambertW0Wad(2 ** 232 - 1, 114621974678990178815); - _checkLambertW0Wad(2 ** 231 - 1, 113934840326554781918); - _checkLambertW0Wad(2 ** 230 - 1, 113247742028666934564); - _checkLambertW0Wad(2 ** 229 - 1, 112560680218384162820); - _checkLambertW0Wad(2 ** 228 - 1, 111873655336589667598); - _checkLambertW0Wad(2 ** 227 - 1, 111186667832181581935); - _checkLambertW0Wad(2 ** 226 - 1, 110499718162267973459); - _checkLambertW0Wad(2 ** 225 - 1, 109812806792367802251); - _checkLambertW0Wad(2 ** 224 - 1, 109125934196618053331); - _checkLambertW0Wad(2 ** 223 - 1, 108439100857987272488); - _checkLambertW0Wad(2 ** 222 - 1, 107752307268495744067); - _checkLambertW0Wad(2 ** 221 - 1, 107065553929442559763); - _checkLambertW0Wad(2 ** 220 - 1, 106378841351639838444); - _checkLambertW0Wad(2 ** 219 - 1, 105692170055654368478); - _checkLambertW0Wad(2 ** 218 - 1, 105005540572056956171); - _checkLambertW0Wad(2 ** 217 - 1, 104318953441679776592); - _checkLambertW0Wad(2 ** 216 - 1, 103632409215882036434); - _checkLambertW0Wad(2 ** 215 - 1, 102945908456824272609); - _checkLambertW0Wad(2 ** 214 - 1, 102259451737751625038); - _checkLambertW0Wad(2 ** 213 - 1, 101573039643286437675); - _checkLambertW0Wad(2 ** 212 - 1, 100886672769730558166); - _checkLambertW0Wad(2 ** 211 - 1, 100200351725377723788); - _checkLambertW0Wad(2 ** 210 - 1, 99514077130836439501); - _checkLambertW0Wad(2 ** 209 - 1, 98827849619363773067); - _checkLambertW0Wad(2 ** 208 - 1, 98141669837210512407); - _checkLambertW0Wad(2 ** 207 - 1, 97455538443978151616); - _checkLambertW0Wad(2 ** 206 - 1, 96769456112988194563); - _checkLambertW0Wad(2 ** 205 - 1, 96083423531664288650); - _checkLambertW0Wad(2 ** 204 - 1, 95397441401927726359); - _checkLambertW0Wad(2 ** 203 - 1, 94711510440606878644); - _checkLambertW0Wad(2 ** 202 - 1, 94025631379861152095); - _checkLambertW0Wad(2 ** 201 - 1, 93339804967620091367); - _checkLambertW0Wad(2 ** 200 - 1, 92654031968038279517); - _checkLambertW0Wad(2 ** 199 - 1, 91968313161966721893); - _checkLambertW0Wad(2 ** 198 - 1, 91282649347441434152); - _checkLambertW0Wad(2 ** 197 - 1, 90597041340189991908); - _checkLambertW0Wad(2 ** 196 - 1, 89911489974156838659); - _checkLambertW0Wad(2 ** 195 - 1, 89225996102048190100); - _checkLambertW0Wad(2 ** 194 - 1, 88540560595897416858); - _checkLambertW0Wad(2 ** 193 - 1, 87855184347651834275); - _checkLambertW0Wad(2 ** 192 - 1, 87169868269781877263); - _checkLambertW0Wad(2 ** 191 - 1, 86484613295913690725); - _checkLambertW0Wad(2 ** 190 - 1, 85799420381486221653); - _checkLambertW0Wad(2 ** 189 - 1, 85114290504433958190); - _checkLambertW0Wad(2 ** 188 - 1, 84429224665896523735); - _checkLambertW0Wad(2 ** 187 - 1, 83744223890956400983); - _checkLambertW0Wad(2 ** 186 - 1, 83059289229406131801); - _checkLambertW0Wad(2 ** 185 - 1, 82374421756546414467); - _checkLambertW0Wad(2 ** 184 - 1, 81689622574016600237); - _checkLambertW0Wad(2 ** 183 - 1, 81004892810659176931); - _checkLambertW0Wad(2 ** 182 - 1, 80320233623419918558); - _checkLambertW0Wad(2 ** 181 - 1, 79635646198285477393); - _checkLambertW0Wad(2 ** 180 - 1, 78951131751260298782); - _checkLambertW0Wad(2 ** 179 - 1, 78266691529384849812); - _checkLambertW0Wad(2 ** 178 - 1, 77582326811797271395); - _checkLambertW0Wad(2 ** 177 - 1, 76898038910840689756); - _checkLambertW0Wad(2 ** 176 - 1, 76213829173218558571); - _checkLambertW0Wad(2 ** 175 - 1, 75529698981200547567); - _checkLambertW0Wad(2 ** 174 - 1, 74845649753881648207); - _checkLambertW0Wad(2 ** 173 - 1, 74161682948497332759); - _checkLambertW0Wad(2 ** 172 - 1, 73477800061797780656); - _checkLambertW0Wad(2 ** 171 - 1, 72794002631484376331); - _checkLambertW0Wad(2 ** 170 - 1, 72110292237711886966); - _checkLambertW0Wad(2 ** 169 - 1, 71426670504659947705); - _checkLambertW0Wad(2 ** 168 - 1, 70743139102177717275); - _checkLambertW0Wad(2 ** 167 - 1, 70059699747505819935); - _checkLambertW0Wad(2 ** 166 - 1, 69376354207079961679); - _checkLambertW0Wad(2 ** 165 - 1, 68693104298420901379); - _checkLambertW0Wad(2 ** 164 - 1, 68009951892115772747); - _checkLambertW0Wad(2 ** 163 - 1, 67326898913896092682); - _checkLambertW0Wad(2 ** 162 - 1, 66643947346818157796); - _checkLambertW0Wad(2 ** 161 - 1, 65961099233551926143); - _checkLambertW0Wad(2 ** 160 - 1, 65278356678784907905); - _checkLambertW0Wad(2 ** 159 - 1, 64595721851748049983); - _checkLambertW0Wad(2 ** 158 - 1, 63913196988871098107); - _checkLambertW0Wad(2 ** 157 - 1, 63230784396575459844); - _checkLambertW0Wad(2 ** 156 - 1, 62548486454213176429); - _checkLambertW0Wad(2 ** 155 - 1, 61866305617161244980); - _checkLambertW0Wad(2 ** 154 - 1, 61184244420081220067); - _checkLambertW0Wad(2 ** 153 - 1, 60502305480354769865); - _checkLambertW0Wad(2 ** 152 - 1, 59820491501706673077); - _checkLambertW0Wad(2 ** 151 - 1, 59138805278027624755); - _checkLambertW0Wad(2 ** 150 - 1, 58457249697410179101); - _checkLambertW0Wad(2 ** 149 - 1, 57775827746412203235); - _checkLambertW0Wad(2 ** 148 - 1, 57094542514563356374); - _checkLambertW0Wad(2 ** 147 - 1, 56413397199131353678); - _checkLambertW0Wad(2 ** 146 - 1, 55732395110166133991); - _checkLambertW0Wad(2 ** 145 - 1, 55051539675841537897); - _checkLambertW0Wad(2 ** 144 - 1, 54370834448115730535); - _checkLambertW0Wad(2 ** 143 - 1, 53690283108733387465); - _checkLambertW0Wad(2 ** 142 - 1, 53009889475594618649); - _checkLambertW0Wad(2 ** 141 - 1, 52329657509517754228); - _checkLambertW0Wad(2 ** 140 - 1, 51649591321425477661); - _checkLambertW0Wad(2 ** 139 - 1, 50969695179986390948); - _checkLambertW0Wad(2 ** 138 - 1, 50289973519746960243); - _checkLambertW0Wad(2 ** 137 - 1, 49610430949791948630); - _checkLambertW0Wad(2 ** 136 - 1, 48931072262974930811); - _checkLambertW0Wad(2 ** 135 - 1, 48251902445764340905); - _checkLambertW0Wad(2 ** 134 - 1, 47572926688754773801); - _checkLambertW0Wad(2 ** 133 - 1, 46894150397897992742); - _checkLambertW0Wad(2 ** 132 - 1, 46215579206513348095); - _checkLambertW0Wad(2 ** 131 - 1, 45537218988143149666); - _checkLambertW0Wad(2 ** 130 - 1, 44859075870325031417); - _checkLambertW0Wad(2 ** 129 - 1, 44181156249360587882); - _checkLambertW0Wad(2 ** 128 - 1, 43503466806167642613); - _checkLambertW0Wad(2 ** 127 - 1, 42826014523312541917); - _checkLambertW0Wad(2 ** 126 - 1, 42148806703328979292); - _checkLambertW0Wad(2 ** 125 - 1, 41471850988441194251); - _checkLambertW0Wad(2 ** 124 - 1, 40795155381822122767); - _checkLambertW0Wad(2 ** 123 - 1, 40118728270531400808); - _checkLambertW0Wad(2 ** 122 - 1, 39442578450294263667); - _checkLambertW0Wad(2 ** 121 - 1, 38766715152300604375); - _checkLambertW0Wad(2 ** 120 - 1, 38091148072224059569); - _checkLambertW0Wad(2 ** 119 - 1, 37415887401684336100); - _checkLambertW0Wad(2 ** 118 - 1, 36740943862402491609); - _checkLambertW0Wad(2 ** 117 - 1, 36066328743329022902); - _checkLambertW0Wad(2 ** 116 - 1, 35392053941058967434); - _checkLambertW0Wad(2 ** 115 - 1, 34718132003887455986); - _checkLambertW0Wad(2 ** 114 - 1, 34044576179904059477); - _checkLambertW0Wad(2 ** 113 - 1, 33371400469575784902); - _checkLambertW0Wad(2 ** 112 - 1, 32698619683327803297); - _checkLambertW0Wad(2 ** 111 - 1, 32026249504699254799); - _checkLambertW0Wad(2 ** 110 - 1, 31354306559730344521); - _checkLambertW0Wad(2 ** 109 - 1, 30682808493328298780); - _checkLambertW0Wad(2 ** 108 - 1, 30011774053465850808); - _checkLambertW0Wad(2 ** 107 - 1, 29341223184189485097); - _checkLambertW0Wad(2 ** 106 - 1, 28671177128558970924); - _checkLambertW0Wad(2 ** 105 - 1, 28001658542808735364); - _checkLambertW0Wad(2 ** 104 - 1, 27332691623220201135); - _checkLambertW0Wad(2 ** 103 - 1, 26664302247428250682); - _checkLambertW0Wad(2 ** 102 - 1, 25996518132161712657); - _checkLambertW0Wad(2 ** 101 - 1, 25329369009746106264); - _checkLambertW0Wad(2 ** 100 - 1, 24662886826087826761); - _checkLambertW0Wad(2 ** 99 - 1, 23997105963326166352); - _checkLambertW0Wad(2 ** 98 - 1, 23332063490900058530); - _checkLambertW0Wad(2 ** 97 - 1, 22667799449451523321); - _checkLambertW0Wad(2 ** 96 - 1, 22004357172804292983); - _checkLambertW0Wad(2 ** 95 - 1, 21341783654247925671); - _checkLambertW0Wad(2 ** 94 - 1, 20680129964567978803); - _checkLambertW0Wad(2 ** 93 - 1, 20019451730746615034); - _checkLambertW0Wad(2 ** 92 - 1, 19359809686086176343); - _checkLambertW0Wad(2 ** 91 - 1, 18701270304772358157); - _checkLambertW0Wad(2 ** 90 - 1, 18043906536712772323); - _checkLambertW0Wad(2 ** 89 - 1, 17387798662016868795); - _checkLambertW0Wad(2 ** 88 - 1, 16733035288929945451); - _checkLambertW0Wad(2 ** 87 - 1, 16079714524670107222 + 1); - _checkLambertW0Wad(2 ** 86 - 1, 15427945355807184379); - _checkLambertW0Wad(2 ** 85 - 1, 14777849284057868231); - _checkLambertW0Wad(2 ** 84 - 1, 14129562275318189632); - _checkLambertW0Wad(2 ** 83 - 1, 13483237095324880705); - _checkLambertW0Wad(2 ** 82 - 1, 12839046125789215063); - _checkLambertW0Wad(2 ** 81 - 1, 12197184781931118579); - _checkLambertW0Wad(2 ** 80 - 1, 11557875688514566228 - 1); - _checkLambertW0Wad(2 ** 79 - 1, 10921373820226202580); - _checkLambertW0Wad(2 ** 78 - 1, 10287972878516218499); - _checkLambertW0Wad(2 ** 77 - 1, 9658013267990184319); - _checkLambertW0Wad(2 ** 76 - 1, 9031892161491509531); - _checkLambertW0Wad(2 ** 75 - 1, 8410076319328428686); - _checkLambertW0Wad(2 ** 74 - 1, 7793118576966979948); - _checkLambertW0Wad(2 ** 73 - 1, 7181679269695846234); - _checkLambertW0Wad(2 ** 72 - 1, 6576554370186862926); - _checkLambertW0Wad(2 ** 71 - 1, 5978712844468804878 - 1); - _checkLambertW0Wad(2 ** 70 - 1, 5389346779005776683); - _checkLambertW0Wad(2 ** 69 - 1, 4809939316762921936); - _checkLambertW0Wad(2 ** 68 - 1, 4242357480017482271); - _checkLambertW0Wad(2 ** 67 - 1, 3688979548845126287); - _checkLambertW0Wad(2 ** 66 - 1, 3152869312105232629); - _checkLambertW0Wad(2 ** 65 - 1, 2638010157689274059); - _checkLambertW0Wad(2 ** 64 - 1, 2149604165721149566); - _checkLambertW0Wad(2 ** 63 - 1, 1694407549795038335); - _checkLambertW0Wad(2 ** 62 - 1, 1280973323147500590); - _checkLambertW0Wad(2 ** 61 - 1, 919438481612859603); - _checkLambertW0Wad(2 ** 60 - 1, 620128202996354327); - _checkLambertW0Wad(2 ** 59 - 1, 390213425026895126); - _checkLambertW0Wad(2 ** 58 - 1, 229193491169149614); - _checkLambertW0Wad(2 ** 57 - 1, 126935310044982397); - _checkLambertW0Wad(2 ** 56 - 1, 67363429834711483); - _checkLambertW0Wad(2 ** 55 - 1, 34796675828817814); - _checkLambertW0Wad(2 ** 54 - 1, 17698377658513340); - _checkLambertW0Wad(2 ** 53 - 1, 8927148493627578); - _checkLambertW0Wad(2 ** 52 - 1, 4483453146102402); - _checkLambertW0Wad(2 ** 51 - 1, 2246746269994097); - _checkLambertW0Wad(2 ** 50 - 1, 1124634392838166); - _checkLambertW0Wad(2 ** 49 - 1, 562633308112667); - _checkLambertW0Wad(2 ** 48 - 1, 281395781982528); - _checkLambertW0Wad(2 ** 47 - 1, 140717685495042); - _checkLambertW0Wad(2 ** 46 - 1, 70363792940114); - _checkLambertW0Wad(2 ** 45 - 1, 35183134214121); - _checkLambertW0Wad(2 ** 44 - 1, 17591876567571); - _checkLambertW0Wad(2 ** 43 - 1, 8796015651975); - _checkLambertW0Wad(2 ** 42 - 1, 4398027168417); - _checkLambertW0Wad(2 ** 41 - 1, 2199018419863); - _checkLambertW0Wad(2 ** 40 - 1, 1099510418851); - _checkLambertW0Wad(2 ** 39 - 1, 549755511655); - _checkLambertW0Wad(2 ** 38 - 1, 274877831385); - _checkLambertW0Wad(2 ** 37 - 1, 137438934581); - _checkLambertW0Wad(2 ** 36 - 1, 68719472012); - _checkLambertW0Wad(2 ** 35 - 1, 34359737186); - _checkLambertW0Wad(2 ** 34 - 1, 17179868887); - _checkLambertW0Wad(2 ** 33 - 1, 8589934517); - _checkLambertW0Wad(2 ** 32 - 1, 4294967276); - _checkLambertW0Wad(2 ** 31 - 1, 2147483642); - _checkLambertW0Wad(2 ** 30 - 1, 1073741821); - _checkLambertW0Wad(2 ** 29 - 1, 536870910); - _checkLambertW0Wad(2 ** 28 - 1, 268435454); - _checkLambertW0Wad(2 ** 27 - 1, 134217726); - _checkLambertW0Wad(2 ** 26 - 1, 67108862); - _checkLambertW0Wad(2 ** 25 - 1, 33554430); - _checkLambertW0Wad(2 ** 24 - 1, 16777214); - _checkLambertW0Wad(2 ** 23 - 1, 8388606); - _checkLambertW0Wad(2 ** 22 - 1, 4194302); - _checkLambertW0Wad(2 ** 21 - 1, 2097150); - _checkLambertW0Wad(2 ** 20 - 1, 1048574); - _checkLambertW0Wad(2 ** 19 - 1, 524286); - _checkLambertW0Wad(2 ** 18 - 1, 262142); - _checkLambertW0Wad(2 ** 17 - 1, 131070); - _checkLambertW0Wad(2 ** 16 - 1, 65534); - _checkLambertW0Wad(2 ** 15 - 1, 32766); - _checkLambertW0Wad(2 ** 14 - 1, 16382); - _checkLambertW0Wad(2 ** 13 - 1, 8190); - _checkLambertW0Wad(2 ** 12 - 1, 4094); - _checkLambertW0Wad(2 ** 11 - 1, 2046); - _checkLambertW0Wad(2 ** 10 - 1, 1022); - _checkLambertW0Wad(2 ** 9 - 1, 510); - _checkLambertW0Wad(2 ** 8 - 1, 254); - } - - function testLambertW0WadRevertsForOutOfDomain() public { - FixedPointMathLib.lambertW0Wad(_LAMBERT_W0_MIN); - for (int256 i = 0; i <= 10; ++i) { - vm.expectRevert(FixedPointMathLib.OutOfDomain.selector); - this.lambertW0Wad(_LAMBERT_W0_MIN - 1 - i); - } - vm.expectRevert(FixedPointMathLib.OutOfDomain.selector); - this.lambertW0Wad(-type(int256).max); - } - - function lambertW0Wad(int256 x) public pure returns (int256) { - return FixedPointMathLib.lambertW0Wad(x); - } - - function _checkLambertW0Wad(int256 x, int256 expected) internal { - unchecked { - uint256 gasBefore = gasleft(); - int256 w = FixedPointMathLib.lambertW0Wad(x); - uint256 gasUsed = gasBefore - gasleft(); - emit LogInt("x", x); - emit LogUint("gasUsed", gasUsed); - assertEq(w, expected); - } - } - - function testLambertW0WadAccuracy() public { - testLambertW0WadAccuracy(uint184(int184(_testLamberW0WadAccuracyThres()))); - testLambertW0WadAccuracy(2 ** 184 - 1); - } - - function testLambertW0WadAccuracy(uint184 a) public { - int256 x = int256(int184(a)); - if (x >= _testLamberW0WadAccuracyThres()) { - int256 l = FixedPointMathLib.lnWad(x); - int256 r = x * l / _WAD; - int256 w = FixedPointMathLib.lambertW0Wad(r); - assertLt(FixedPointMathLib.abs(l - w), 0xff); - } - } - - function _testLamberW0WadAccuracyThres() internal pure returns (int256) { - unchecked { - return _ONE_DIV_EXP + _ONE_DIV_EXP * 0.01 ether / 1 ether; - } - } - - function testLambertW0WadWithinBounds(int256 x) public { - if (x <= 0) x = _boundLambertW0WadInput(x); - int256 w = FixedPointMathLib.lambertW0Wad(x); - assertTrue(w <= x); - unchecked { - if (x > _EXP) { - int256 l = FixedPointMathLib.lnWad(x); - assertGt(l, 0); - int256 ll = FixedPointMathLib.lnWad(l); - int256 q = ll * _WAD; - int256 lower = l - ll + q / (2 * l); - if (x > _EXP + 4) { - assertLt(lower, w + 1); - } else { - assertLt(lower, w + 2); - } - int256 upper = l - ll + (q * _EXP) / (l * (_EXP - _WAD)) + 1; - assertLt(w, upper); - } - } - } - - function testLambertW0WadWithinBounds() public { - unchecked { - for (int256 i = -10; i != 20; ++i) { - testLambertW0WadWithinBounds(_EXP + i); - } - testLambertW0WadWithinBounds(type(int256).max); - } - } - - function testLambertW0WadMonotonicallyIncreasing() public { - unchecked { - for (uint256 i; i <= 256; ++i) { - uint256 x = 1 << i; - testLambertW0WadMonotonicallyIncreasingAround(int256(x)); - testLambertW0WadMonotonicallyIncreasingAround(int256(x - 1)); - } - for (uint256 i; i <= 57; ++i) { - uint256 x = 1 << i; - testLambertW0WadMonotonicallyIncreasingAround(-int256(x)); - testLambertW0WadMonotonicallyIncreasingAround(-int256(x - 1)); - } - } - } - - function testLambertW0WadMonotonicallyIncreasing2() public { - // These are some problematic values gathered over the attempts. - // Some might not be problematic now. - _testLambertW0WadMonoAround(0x598cdf77327d789dc); - _testLambertW0WadMonoAround(0x3c8d97dfe4afb1b05); - _testLambertW0WadMonoAround(0x56a147b480c03cc22); - _testLambertW0WadMonoAround(0x3136f439c231d0bb9); - _testLambertW0WadMonoAround(0x2ae7cff17ef2469a1); - _testLambertW0WadMonoAround(0x1de668fd7afcf61cc); - _testLambertW0WadMonoAround(0x15024b2a35f2cdd95); - _testLambertW0WadMonoAround(0x11a65ae94b59590f9); - _testLambertW0WadMonoAround(0xf0c2c82174dffb7e); - _testLambertW0WadMonoAround(0xed3e56938cb11626); - _testLambertW0WadMonoAround(0xecf5c4e511142439); - _testLambertW0WadMonoAround(0xc0755fa2b4033cb0); - _testLambertW0WadMonoAround(0xa235db282ea4edc6); - _testLambertW0WadMonoAround(0x9ff2ec5c26eec112); - _testLambertW0WadMonoAround(0xa0c3c4e36f4415f1); - _testLambertW0WadMonoAround(0x9b9f0e8d61287782); - _testLambertW0WadMonoAround(0x7df719d1a4a7b8ad); - _testLambertW0WadMonoAround(0x7c881679a1464d25); - _testLambertW0WadMonoAround(0x7bec47487071495a); - _testLambertW0WadMonoAround(0x7be31c75fc717f9f); - _testLambertW0WadMonoAround(0x7bbb4e0716eeca53); - _testLambertW0WadMonoAround(0x78e59d40a92b443b); - _testLambertW0WadMonoAround(0x77658c4ad3af717d); - _testLambertW0WadMonoAround(0x75ae9afa425919fe); - _testLambertW0WadMonoAround(0x7526092d05bef41f); - _testLambertW0WadMonoAround(0x52896fe82be03dfe); - _testLambertW0WadMonoAround(0x4f05b0ddf3b71a19); - _testLambertW0WadMonoAround(0x3094b0feb93943fd); - _testLambertW0WadMonoAround(0x2ef215ae6701c40e); - _testLambertW0WadMonoAround(0x2ebd1c82095d6a92); - _testLambertW0WadMonoAround(0x2e520a4e670d52bb); - _testLambertW0WadMonoAround(0xfc2f004412e5ce69); - _testLambertW0WadMonoAround(0x158bc0b201103a7fc); - _testLambertW0WadMonoAround(0x39280df60945c436b); - _testLambertW0WadMonoAround(0x47256e5d374b35f74); - _testLambertW0WadMonoAround(0x2b9568ffb08c155a4); - _testLambertW0WadMonoAround(0x1b60b07806956f34d); - _testLambertW0WadMonoAround(0x21902755d1eee824c); - _testLambertW0WadMonoAround(0x6e15c8a6ee6e4fca4); - _testLambertW0WadMonoAround(0x5b13067d92d8e49c6); - _testLambertW0WadMonoAround(0x2826ebc1fce90cf6e); - _testLambertW0WadMonoAround(0x215eb5aa1041510a4); - _testLambertW0WadMonoAround(0x47b20347b57504c32); - _testLambertW0WadMonoAround(0x75e8fd53f8c90f95a); - _testLambertW0WadMonoAround(0x43e8d80f9af282627); - _testLambertW0WadMonoAround(0x3cf555b5fd4f20615); - _testLambertW0WadMonoAround(0xaff4b8b52f8355e6e); - _testLambertW0WadMonoAround(0x529e89e77ae046255); - _testLambertW0WadMonoAround(0x1f0289433f07cbf53b); - _testLambertW0WadMonoAround(0xc1f6e56c2001d9432); - _testLambertW0WadMonoAround(0x5e4117305c6e33ebc); - _testLambertW0WadMonoAround(0x2b416472dce2ea26d); - _testLambertW0WadMonoAround(0x71f55956ef3326067); - _testLambertW0WadMonoAround(0x35d9d57c965eb82c6); - _testLambertW0WadMonoAround(0x184f520f19335f25d); - _testLambertW0WadMonoAround(0x3c4bb8f445abe21a7); - _testLambertW0WadMonoAround(0x573e3b3e06e208201); - _testLambertW0WadMonoAround(0x184f520f19335f25d); - _testLambertW0WadMonoAround(0x573e3b3e06e208201); - _testLambertW0WadMonoAround(0x61e511ba00db632a4); - _testLambertW0WadMonoAround(0x12731b97bde57933d); - _testLambertW0WadMonoAround(0x79c29b05cf39be374); - _testLambertW0WadMonoAround(0x390fcd4186ac250b3); - _testLambertW0WadMonoAround(0x69c74b5975fd4832a); - _testLambertW0WadMonoAround(0x59db219a7048121bd); - _testLambertW0WadMonoAround(0x28f2adc4fab331d251); - _testLambertW0WadMonoAround(0x7be91527cc31769c); - _testLambertW0WadMonoAround(0x2ef215ae6701c40f); - _testLambertW0WadMonoAround(0x1240541334cfadd81); - _testLambertW0WadMonoAround(0x2a79eccb3d5f4faaed); - _testLambertW0WadMonoAround(0x7470d50c23bfd30e0); - _testLambertW0WadMonoAround(0x313386f14a7f95af9); - _testLambertW0WadMonoAround(0x2a60f3b64c57088e9); - _testLambertW0WadMonoAround(0x381298f7aa53edfe0); - _testLambertW0WadMonoAround(0x5cbfac5d7a1770806); - _testLambertW0WadMonoAround(0x19e46d1b5e6aba57e); - _testLambertW0WadMonoAround(0x19ff86906ae47c70a); - _testLambertW0WadMonoAround(0x164684654d9ca54ea1); - _testLambertW0WadMonoAround(0x99337fa75e803139); - _testLambertW0WadMonoAround(0x6fa0a50fcb8a95b97e); - _testLambertW0WadMonoAround(0xa117a195e06c3fd531); - _testLambertW0WadMonoAround(0x305da7073093bd8a07); - _testLambertW0WadMonoAround(0x98582b07fd3c6b64); - _testLambertW0WadMonoAround(0x1e824d2a367d9ce65); - _testLambertW0WadMonoAround(0x7bea796d633b386a); - _testLambertW0WadMonoAround(0x2fff5c38c6b2a2cd); - _testLambertW0WadMonoAround(0x198af4e7ffee1df7627); - _testLambertW0WadMonoAround(0x8ea8a7b6f7c7424d8d); - _testLambertW0WadMonoAround(0x11e504fa805e54e2ed8); - _testLambertW0WadMonoAround(0x3e5f2a7801badcdabd); - _testLambertW0WadMonoAround(0x1b7aaad69ac8770a3be); - _testLambertW0WadMonoAround(0x658acb00d525f3d345); - _testLambertW0WadMonoAround(0xd994d6447146880183f); - _testLambertW0WadMonoAround(0x2e07a342d7b1bc1a5ae); - } - - function testLambertW0WadMonoDebug() public { - unchecked { - for (int256 i = -9; i <= 9; ++i) { - _testLambertW0WadMonoAround(0x2e07a342d7b1bc1a5ae + i); - } - } - } - - function _testLambertW0WadMonoAround(int256 x) internal { - emit LogInt("x", x); - emit LogUint("log2(x)", FixedPointMathLib.log2(uint256(x))); - testLambertW0WadMonotonicallyIncreasingAround(x); - } - - function testLambertW0WadMonotonicallyIncreasingAround2(uint96 t) public { - int256 x = int256(uint256(t)); - testLambertW0WadMonotonicallyIncreasingAround(x); - if (t & 0xff == 0xab) { - _testLambertW0WadMonoFocus(x, 0, 0x1ffffffffffff, 0xffffffffffffffffff); - _testLambertW0WadMonoFocus(x, 1, 0x1fffffffffffff, 0xffffffffffffffffff); - _testLambertW0WadMonoFocus(x, 2, 0xfffffffffffffff, 0xffffffffffffffffff); - _testLambertW0WadMonoFocus(x, 3, 0xffffffffffffffff, 0xfffffffffffffffff); - _testLambertW0WadMonoFocus(x, 4, 0xffffffffffffffff, 0xfffffffffffffffff); - _testLambertW0WadMonoFocus(x, 5, 0xffffffffffffffff, 0xffffffffffffffffff); - _testLambertW0WadMonoFocus(x, 6, 0xffffffffffffffff, 0xffffffffffffffffff); - _testLambertW0WadMonoFocus(x, 7, 0xffffffffffffffff, 0xfffffffffffffffffff); - _testLambertW0WadMonoFocus(x, 8, 0xffffffffffffffff, 0xfffffffffffffffffff); - _testLambertW0WadMonoFocus(x, 9, 0xffffffffffffffff, 0xffffffffffffffffffff); - } - } - - function _testLambertW0WadMonoFocus(int256 t, int256 i, int256 low, int256 mask) internal { - int256 x; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, t) - mstore(0x20, i) - x := and(keccak256(0x00, 0x40), mask) - } - do { - testLambertW0WadMonotonicallyIncreasingAround(x); - x >>= 1; - } while (x >= low); - } - - function testLambertW0WadMonotonicallyIncreasingAround(int256 t) public { - if (t < _LAMBERT_W0_MIN) t = _boundLambertW0WadInput(t); - unchecked { - int256 end = t + 2; - for (int256 x = t - 2; x != end; ++x) { - testLambertW0WadMonotonicallyIncreasing(x, x + 1); - } - } - } - - function testLambertW0WadMonotonicallyIncreasing(int256 a, int256 b) public { - if (a < _LAMBERT_W0_MIN) a = _boundLambertW0WadInput(a); - if (b < _LAMBERT_W0_MIN) b = _boundLambertW0WadInput(b); - if (a > b) { - int256 t = b; - b = a; - a = t; - } - unchecked { - uint256 gasBefore = gasleft(); - int256 w0a = FixedPointMathLib.lambertW0Wad(a); - uint256 gasUsed = gasBefore - gasleft(); - int256 w0b = FixedPointMathLib.lambertW0Wad(b); - bool success = w0a <= w0b; - emit TestingLambertW0WadMonotonicallyIncreasing(a, b, w0a, w0b, success, gasUsed); - if (!success) { - emit LogUint("log2(a)", FixedPointMathLib.log2(uint256(a))); - emit LogUint("log2(b)", FixedPointMathLib.log2(uint256(b))); - emit LogUint("log2(w0a)", FixedPointMathLib.log2(uint256(w0a))); - emit LogUint("log2(w0b)", FixedPointMathLib.log2(uint256(w0b))); - assertTrue(success); - } - } - } - - function _boundLambertW0WadInput(int256 x) internal pure returns (int256 result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(1, shl(1, not(x))) - } - } - - function testMulWad() public { - assertEq(FixedPointMathLib.mulWad(2.5e18, 0.5e18), 1.25e18); - assertEq(FixedPointMathLib.mulWad(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.mulWad(369, 271), 0); - } - - function testMulWadEdgeCases() public { - assertEq(FixedPointMathLib.mulWad(0, 1e18), 0); - assertEq(FixedPointMathLib.mulWad(1e18, 0), 0); - assertEq(FixedPointMathLib.mulWad(0, 0), 0); - } - - function testSMulWad() public { - assertEq(FixedPointMathLib.sMulWad(0, -2e18), 0); - assertEq(FixedPointMathLib.sMulWad(1e18, -1), -1); - assertEq(FixedPointMathLib.sMulWad(-0.5e18, 2e18), -1e18); - assertEq(FixedPointMathLib.sMulWad(-0.5e18, -10e18), 5e18); - } - - function testSMulWadOverflowTrickDifferential(int256 x, int256 y) public { - unchecked { - bool c; - int256 z; - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - c := iszero(gt(or(iszero(x), eq(sdiv(z, x), y)), lt(not(x), eq(y, shl(255, 1))))) - } - assertEq(c, !((x == 0 || z / x == y) && (x != -1 || y != type(int256).min))); - } - } - - function testSMulWadEdgeCases() public { - assertEq(FixedPointMathLib.sMulWad(1e18, type(int256).max / 1e18), type(int256).max / 1e18); - assertEq(FixedPointMathLib.sMulWad(-1e18, type(int256).min / 2e18), type(int256).max / 2e18); - assertEq(FixedPointMathLib.sMulWad(0, 0), 0); - } - - function testMulWadUp() public { - assertEq(FixedPointMathLib.mulWadUp(2.5e18, 0.5e18), 1.25e18); - assertEq(FixedPointMathLib.mulWadUp(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.mulWadUp(369, 271), 1); - } - - function testMulWadUpEdgeCases() public { - assertEq(FixedPointMathLib.mulWadUp(0, 1e18), 0); - assertEq(FixedPointMathLib.mulWadUp(1e18, 0), 0); - assertEq(FixedPointMathLib.mulWadUp(0, 0), 0); - } - - function testDivWad() public { - assertEq(FixedPointMathLib.divWad(1.25e18, 0.5e18), 2.5e18); - assertEq(FixedPointMathLib.divWad(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.divWad(2, 100000000000000e18), 0); - } - - function testDivWadEdgeCases() public { - assertEq(FixedPointMathLib.divWad(0, 1e18), 0); - } - - function testSDivWad() public { - assertEq(FixedPointMathLib.sDivWad(1.25e18, -0.5e18), -2.5e18); - assertEq(FixedPointMathLib.sDivWad(3e18, -1e18), -3e18); - assertEq(FixedPointMathLib.sDivWad(type(int256).min / 1e18, type(int256).max), 0); - } - - function testSDivWadEdgeCases() public { - assertEq(FixedPointMathLib.sDivWad(0, 1e18), 0); - } - - function testDivWadZeroDenominatorReverts() public { - vm.expectRevert(FixedPointMathLib.DivWadFailed.selector); - this.divWad(1e18, 0); - } - - function testDivWadUp() public { - assertEq(FixedPointMathLib.divWadUp(1.25e18, 0.5e18), 2.5e18); - assertEq(FixedPointMathLib.divWadUp(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.divWadUp(2, 100000000000000e18), 1); - unchecked { - for (uint256 i; i < 10; ++i) { - assertEq(FixedPointMathLib.divWadUp(2, 100000000000000e18), 1); - } - } - } - - function testDivWadUpEdgeCases() public { - assertEq(FixedPointMathLib.divWadUp(0, 1e18), 0); - } - - function testDivWadUpZeroDenominatorReverts() public { - vm.expectRevert(FixedPointMathLib.DivWadFailed.selector); - this.divWadUp(1e18, 0); - } - - function testMulDiv() public { - assertEq(FixedPointMathLib.mulDiv(2.5e27, 0.5e27, 1e27), 1.25e27); - assertEq(FixedPointMathLib.mulDiv(2.5e18, 0.5e18, 1e18), 1.25e18); - assertEq(FixedPointMathLib.mulDiv(2.5e8, 0.5e8, 1e8), 1.25e8); - assertEq(FixedPointMathLib.mulDiv(369, 271, 1e2), 999); - - assertEq(FixedPointMathLib.mulDiv(1e27, 1e27, 2e27), 0.5e27); - assertEq(FixedPointMathLib.mulDiv(1e18, 1e18, 2e18), 0.5e18); - assertEq(FixedPointMathLib.mulDiv(1e8, 1e8, 2e8), 0.5e8); - - assertEq(FixedPointMathLib.mulDiv(2e27, 3e27, 2e27), 3e27); - assertEq(FixedPointMathLib.mulDiv(3e18, 2e18, 3e18), 2e18); - assertEq(FixedPointMathLib.mulDiv(2e8, 3e8, 2e8), 3e8); - } - - function testMulDivEdgeCases() public { - assertEq(FixedPointMathLib.mulDiv(0, 1e18, 1e18), 0); - assertEq(FixedPointMathLib.mulDiv(1e18, 0, 1e18), 0); - assertEq(FixedPointMathLib.mulDiv(0, 0, 1e18), 0); - } - - function testMulDivZeroDenominatorReverts() public { - vm.expectRevert(FixedPointMathLib.MulDivFailed.selector); - this.mulDiv(1e18, 1e18, 0); - } - - function testMulDivUp() public { - assertEq(FixedPointMathLib.mulDivUp(2.5e27, 0.5e27, 1e27), 1.25e27); - assertEq(FixedPointMathLib.mulDivUp(2.5e18, 0.5e18, 1e18), 1.25e18); - assertEq(FixedPointMathLib.mulDivUp(2.5e8, 0.5e8, 1e8), 1.25e8); - assertEq(FixedPointMathLib.mulDivUp(369, 271, 1e2), 1000); - - assertEq(FixedPointMathLib.mulDivUp(1e27, 1e27, 2e27), 0.5e27); - assertEq(FixedPointMathLib.mulDivUp(1e18, 1e18, 2e18), 0.5e18); - assertEq(FixedPointMathLib.mulDivUp(1e8, 1e8, 2e8), 0.5e8); - - assertEq(FixedPointMathLib.mulDivUp(2e27, 3e27, 2e27), 3e27); - assertEq(FixedPointMathLib.mulDivUp(3e18, 2e18, 3e18), 2e18); - assertEq(FixedPointMathLib.mulDivUp(2e8, 3e8, 2e8), 3e8); - } - - function testMulDivUpEdgeCases() public { - assertEq(FixedPointMathLib.mulDivUp(0, 1e18, 1e18), 0); - assertEq(FixedPointMathLib.mulDivUp(1e18, 0, 1e18), 0); - assertEq(FixedPointMathLib.mulDivUp(0, 0, 1e18), 0); - } - - function testMulDivUpZeroDenominator() public { - vm.expectRevert(FixedPointMathLib.MulDivFailed.selector); - this.mulDivUp(1e18, 1e18, 0); - } - - function mulDivUp(uint256 x, uint256 y, uint256 d) public pure returns (uint256) { - return FixedPointMathLib.mulDivUp(x, y, d); - } - - function testLnWad() public { - assertEq(FixedPointMathLib.lnWad(1e18), 0); - - // Actual: 999999999999999999.8674576… - assertEq(FixedPointMathLib.lnWad(2718281828459045235), 999999999999999999); - - // Actual: 2461607324344817917.963296… - assertEq(FixedPointMathLib.lnWad(11723640096265400935), 2461607324344817918); - } - - function testLnWadSmall() public { - // Actual: -41446531673892822312.3238461… - assertEq(FixedPointMathLib.lnWad(1), -41446531673892822313); - - // Actual: -37708862055609454006.40601608… - assertEq(FixedPointMathLib.lnWad(42), -37708862055609454007); - - // Actual: -32236191301916639576.251880365581… - assertEq(FixedPointMathLib.lnWad(1e4), -32236191301916639577); - - // Actual: -20723265836946411156.161923092… - assertEq(FixedPointMathLib.lnWad(1e9), -20723265836946411157); - } - - function testLnWadBig() public { - // Actual: 135305999368893231589.070344787… - assertEq(FixedPointMathLib.lnWad(2 ** 255 - 1), 135305999368893231589); - - // Actual: 76388489021297880288.605614463571… - assertEq(FixedPointMathLib.lnWad(2 ** 170), 76388489021297880288); - - // Actual: 47276307437780177293.081865… - assertEq(FixedPointMathLib.lnWad(2 ** 128), 47276307437780177293); - } - - function testLnWadNegativeReverts() public { - vm.expectRevert(FixedPointMathLib.LnWadUndefined.selector); - this.lnWad(-1); - vm.expectRevert(FixedPointMathLib.LnWadUndefined.selector); - this.lnWad(-2 ** 255); - } - - function testLnWadOverflowReverts() public { - vm.expectRevert(FixedPointMathLib.LnWadUndefined.selector); - this.lnWad(0); - } - - function lnWad(int256 x) public pure returns (int256) { - return FixedPointMathLib.lnWad(x); - } - - function testRPow() public { - assertEq(FixedPointMathLib.rpow(0, 0, 0), 0); - assertEq(FixedPointMathLib.rpow(1, 0, 0), 0); - assertEq(FixedPointMathLib.rpow(0, 1, 0), 0); - assertEq(FixedPointMathLib.rpow(0, 0, 1), 1); - assertEq(FixedPointMathLib.rpow(1, 1, 0), 1); - assertEq(FixedPointMathLib.rpow(1, 1, 1), 1); - assertEq(FixedPointMathLib.rpow(2e27, 0, 1e27), 1e27); - assertEq(FixedPointMathLib.rpow(2e27, 2, 1e27), 4e27); - assertEq(FixedPointMathLib.rpow(2e18, 2, 1e18), 4e18); - assertEq(FixedPointMathLib.rpow(2e8, 2, 1e8), 4e8); - assertEq(FixedPointMathLib.rpow(8, 3, 1), 512); - } - - function testRPowOverflowReverts() public { - vm.expectRevert(FixedPointMathLib.RPowOverflow.selector); - this.rpow(2, type(uint128).max, 1); - vm.expectRevert(FixedPointMathLib.RPowOverflow.selector); - this.rpow(type(uint128).max, 3, 1); - } - - function rpow(uint256 x, uint256 y, uint256 b) public pure returns (uint256) { - return FixedPointMathLib.rpow(x, y, b); - } - - function testSqrt() public { - assertEq(FixedPointMathLib.sqrt(0), 0); - assertEq(FixedPointMathLib.sqrt(1), 1); - assertEq(FixedPointMathLib.sqrt(2704), 52); - assertEq(FixedPointMathLib.sqrt(110889), 333); - assertEq(FixedPointMathLib.sqrt(32239684), 5678); - unchecked { - for (uint256 i = 100; i < 200; ++i) { - assertEq(FixedPointMathLib.sqrt(i * i), i); - } - } - } - - function testSqrtWad() public { - assertEq(FixedPointMathLib.sqrtWad(0), 0); - assertEq(FixedPointMathLib.sqrtWad(1), 10 ** 9); - assertEq(FixedPointMathLib.sqrtWad(2), 1414213562); - assertEq(FixedPointMathLib.sqrtWad(4), 2000000000); - assertEq(FixedPointMathLib.sqrtWad(8), 2828427124); - assertEq(FixedPointMathLib.sqrtWad(16), 4000000000); - assertEq(FixedPointMathLib.sqrtWad(32), 5656854249); - assertEq(FixedPointMathLib.sqrtWad(64), 8000000000); - assertEq(FixedPointMathLib.sqrtWad(10 ** 18), 10 ** 18); - assertEq(FixedPointMathLib.sqrtWad(4 * 10 ** 18), 2 * 10 ** 18); - assertEq(FixedPointMathLib.sqrtWad(type(uint8).max), 15968719422); - assertEq(FixedPointMathLib.sqrtWad(type(uint16).max), 255998046867); - assertEq(FixedPointMathLib.sqrtWad(type(uint32).max), 65535999992370); - assertEq(FixedPointMathLib.sqrtWad(type(uint64).max), 4294967295999999999); - assertEq(FixedPointMathLib.sqrtWad(type(uint128).max), 18446744073709551615999999999); - assertEq( - FixedPointMathLib.sqrtWad(type(uint256).max), - 340282366920938463463374607431768211455999999999 - ); - } - - function testCbrt() public { - assertEq(FixedPointMathLib.cbrt(0), 0); - assertEq(FixedPointMathLib.cbrt(1), 1); - assertEq(FixedPointMathLib.cbrt(2), 1); - assertEq(FixedPointMathLib.cbrt(3), 1); - assertEq(FixedPointMathLib.cbrt(9), 2); - assertEq(FixedPointMathLib.cbrt(27), 3); - assertEq(FixedPointMathLib.cbrt(80), 4); - assertEq(FixedPointMathLib.cbrt(81), 4); - assertEq(FixedPointMathLib.cbrt(10 ** 18), 10 ** 6); - assertEq(FixedPointMathLib.cbrt(8 * 10 ** 18), 2 * 10 ** 6); - assertEq(FixedPointMathLib.cbrt(9 * 10 ** 18), 2080083); - assertEq(FixedPointMathLib.cbrt(type(uint8).max), 6); - assertEq(FixedPointMathLib.cbrt(type(uint16).max), 40); - assertEq(FixedPointMathLib.cbrt(type(uint32).max), 1625); - assertEq(FixedPointMathLib.cbrt(type(uint64).max), 2642245); - assertEq(FixedPointMathLib.cbrt(type(uint128).max), 6981463658331); - assertEq(FixedPointMathLib.cbrt(type(uint256).max), 48740834812604276470692694); - } - - function testCbrtWad() public { - assertEq(FixedPointMathLib.cbrtWad(0), 0); - assertEq(FixedPointMathLib.cbrtWad(1), 10 ** 12); - assertEq(FixedPointMathLib.cbrtWad(2), 1259921049894); - assertEq(FixedPointMathLib.cbrtWad(3), 1442249570307); - assertEq(FixedPointMathLib.cbrtWad(9), 2080083823051); - assertEq(FixedPointMathLib.cbrtWad(27), 3000000000000); - assertEq(FixedPointMathLib.cbrtWad(80), 4308869380063); - assertEq(FixedPointMathLib.cbrtWad(81), 4326748710922); - assertEq(FixedPointMathLib.cbrtWad(10 ** 18), 10 ** 18); - assertEq(FixedPointMathLib.cbrtWad(8 * 10 ** 18), 2 * 10 ** 18); - assertEq(FixedPointMathLib.cbrtWad(9 * 10 ** 18), 2080083823051904114); - assertEq(FixedPointMathLib.cbrtWad(type(uint8).max), 6341325705384); - assertEq(FixedPointMathLib.cbrtWad(type(uint16).max), 40317268530317); - assertEq(FixedPointMathLib.cbrtWad(type(uint32).max), 1625498677089280); - assertEq(FixedPointMathLib.cbrtWad(type(uint64).max), 2642245949629133047); - assertEq(FixedPointMathLib.cbrtWad(type(uint128).max), 6981463658331559092288464); - assertEq( - FixedPointMathLib.cbrtWad(type(uint256).max), 48740834812604276470692694885616578541 - ); - } - - function testCbrtWadDebug() public { - uint256 x = 57896044618658097711785492504343953926634992332820282019727; - uint256 z = FixedPointMathLib.cbrt(x); - emit LogUint(z); - z = (z + 1) * 10 ** 12; - z = (FixedPointMathLib.fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3; - emit LogUint(z); - z = (FixedPointMathLib.fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3; - emit LogUint(z); - z = (FixedPointMathLib.fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3; - emit LogUint(z); - } - - function testLog2() public { - assertEq(FixedPointMathLib.log2(0), 0); - assertEq(FixedPointMathLib.log2(2), 1); - assertEq(FixedPointMathLib.log2(4), 2); - assertEq(FixedPointMathLib.log2(1024), 10); - assertEq(FixedPointMathLib.log2(1048576), 20); - assertEq(FixedPointMathLib.log2(1073741824), 30); - for (uint256 i = 1; i < 255; i++) { - assertEq(FixedPointMathLib.log2((1 << i) - 1), i - 1); - assertEq(FixedPointMathLib.log2((1 << i)), i); - assertEq(FixedPointMathLib.log2((1 << i) + 1), i); - } - } - - function testLog2Differential(uint256 x) public { - assertEq(FixedPointMathLib.log2(x), _log2Original(x)); - } - - function _log2Original(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - unchecked { - if (value >> 128 > 0) { - value >>= 128; - result += 128; - } - if (value >> 64 > 0) { - value >>= 64; - result += 64; - } - if (value >> 32 > 0) { - value >>= 32; - result += 32; - } - if (value >> 16 > 0) { - value >>= 16; - result += 16; - } - if (value >> 8 > 0) { - value >>= 8; - result += 8; - } - if (value >> 4 > 0) { - value >>= 4; - result += 4; - } - if (value >> 2 > 0) { - value >>= 2; - result += 2; - } - if (value >> 1 > 0) { - result += 1; - } - } - return result; - } - - function testLog2Up() public { - assertEq(FixedPointMathLib.log2Up(0), 0); - assertEq(FixedPointMathLib.log2Up(1), 0); - assertEq(FixedPointMathLib.log2Up(2), 1); - assertEq(FixedPointMathLib.log2Up(2 + 1), 2); - assertEq(FixedPointMathLib.log2Up(4), 2); - assertEq(FixedPointMathLib.log2Up(4 + 1), 3); - assertEq(FixedPointMathLib.log2Up(4 + 2), 3); - assertEq(FixedPointMathLib.log2Up(1024), 10); - assertEq(FixedPointMathLib.log2Up(1024 + 1), 11); - assertEq(FixedPointMathLib.log2Up(1048576), 20); - assertEq(FixedPointMathLib.log2Up(1048576 + 1), 21); - assertEq(FixedPointMathLib.log2Up(1073741824), 30); - assertEq(FixedPointMathLib.log2Up(1073741824 + 1), 31); - for (uint256 i = 2; i < 255; i++) { - assertEq(FixedPointMathLib.log2Up((1 << i) - 1), i); - assertEq(FixedPointMathLib.log2Up((1 << i)), i); - assertEq(FixedPointMathLib.log2Up((1 << i) + 1), i + 1); - } - } - - function testAvg() public { - assertEq(FixedPointMathLib.avg(uint256(5), uint256(6)), uint256(5)); - assertEq(FixedPointMathLib.avg(uint256(0), uint256(1)), uint256(0)); - assertEq(FixedPointMathLib.avg(uint256(45645465), uint256(4846513)), uint256(25245989)); - } - - function testAvgSigned() public { - assertEq(FixedPointMathLib.avg(int256(5), int256(6)), int256(5)); - assertEq(FixedPointMathLib.avg(int256(0), int256(1)), int256(0)); - assertEq(FixedPointMathLib.avg(int256(45645465), int256(4846513)), int256(25245989)); - - assertEq(FixedPointMathLib.avg(int256(5), int256(-6)), int256(-1)); - assertEq(FixedPointMathLib.avg(int256(0), int256(-1)), int256(-1)); - assertEq(FixedPointMathLib.avg(int256(45645465), int256(-4846513)), int256(20399476)); - assertEq(FixedPointMathLib.avg(int256(-10), int256(-19)), int256(-15)); - } - - function testAvgEdgeCase() public { - assertEq(FixedPointMathLib.avg(uint256(2 ** 256 - 1), uint256(1)), uint256(2 ** 255)); - assertEq(FixedPointMathLib.avg(uint256(2 ** 256 - 1), uint256(10)), uint256(2 ** 255 + 4)); - assertEq( - FixedPointMathLib.avg(uint256(2 ** 256 - 1), uint256(2 ** 256 - 1)), - uint256(2 ** 256 - 1) - ); - } - - function testAbs() public { - assertEq(FixedPointMathLib.abs(0), 0); - assertEq(FixedPointMathLib.abs(-5), 5); - assertEq(FixedPointMathLib.abs(5), 5); - assertEq(FixedPointMathLib.abs(-1155656654), 1155656654); - assertEq(FixedPointMathLib.abs(621356166516546561651), 621356166516546561651); - } - - function testDist() public { - assertEq(FixedPointMathLib.dist(int256(0), int256(0)), 0); - assertEq(FixedPointMathLib.dist(int256(-5), int256(-4)), 1); - assertEq(FixedPointMathLib.dist(int256(5), int256(46)), 41); - assertEq(FixedPointMathLib.dist(int256(46), int256(5)), 41); - assertEq(FixedPointMathLib.dist(int256(-1155656654), int256(6544844)), 1162201498); - assertEq(FixedPointMathLib.dist(int256(-848877), int256(-8447631456)), 8446782579); - } - - function testDistEdgeCases() public { - assertEq(FixedPointMathLib.dist(type(int256).min, type(int256).max), type(uint256).max); - assertEq( - FixedPointMathLib.dist(type(int256).min, 0), - 0x8000000000000000000000000000000000000000000000000000000000000000 - ); - assertEq( - FixedPointMathLib.dist(type(int256).max, 5), - 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa - ); - assertEq( - FixedPointMathLib.dist(type(int256).min, -5), - 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb - ); - } - - function testAbsEdgeCases() public { - assertEq(FixedPointMathLib.abs(-(2 ** 255 - 1)), (2 ** 255 - 1)); - assertEq(FixedPointMathLib.abs((2 ** 255 - 1)), (2 ** 255 - 1)); - } - - function testGcd() public { - assertEq(FixedPointMathLib.gcd(0, 0), 0); - assertEq(FixedPointMathLib.gcd(85, 0), 85); - assertEq(FixedPointMathLib.gcd(0, 2), 2); - assertEq(FixedPointMathLib.gcd(56, 45), 1); - assertEq(FixedPointMathLib.gcd(12, 28), 4); - assertEq(FixedPointMathLib.gcd(12, 1), 1); - assertEq(FixedPointMathLib.gcd(486516589451122, 48656), 2); - assertEq(FixedPointMathLib.gcd(2 ** 254 - 4, 2 ** 128 - 1), 15); - assertEq(FixedPointMathLib.gcd(3, 26017198113384995722614372765093167890), 1); - unchecked { - for (uint256 i = 2; i < 10; ++i) { - assertEq(FixedPointMathLib.gcd(31 * (1 << i), 31), 31); - } - } - } - - function fullMulDiv(uint256 x, uint256 y, uint256 d) public pure returns (uint256) { - return FixedPointMathLib.fullMulDiv(x, y, d); - } - - function fullMulDivN(uint256 x, uint256 y, uint8 n) public pure returns (uint256) { - return FixedPointMathLib.fullMulDivN(x, y, n); - } - - function testFullMulDiv() public { - assertEq(FixedPointMathLib.fullMulDiv(0, 0, 1), 0); - assertEq(FixedPointMathLib.fullMulDiv(4, 4, 2), 8); - assertEq(FixedPointMathLib.fullMulDiv(2 ** 200, 2 ** 200, 2 ** 200), 2 ** 200); - } - - function testFullMulDivN() public { - assertEq(FixedPointMathLib.fullMulDivN(0, 0, 0), 0); - assertEq(FixedPointMathLib.fullMulDivN(4, 4, 1), 8); - assertEq(FixedPointMathLib.fullMulDivN(2 ** 200, 2 ** 200, 200), 2 ** 200); - } - - function testFullMulDivUnchecked() public { - assertEq(FixedPointMathLib.fullMulDivUnchecked(0, 0, 1), 0); - assertEq(FixedPointMathLib.fullMulDivUnchecked(4, 4, 2), 8); - assertEq(FixedPointMathLib.fullMulDivUnchecked(2 ** 200, 2 ** 200, 2 ** 200), 2 ** 200); - } - - function testFullMulDivAlwaysRevertsIfDivisorIsZero(uint256 a, uint256 b) public { - vm.expectRevert(FixedPointMathLib.FullMulDivFailed.selector); - this.fullMulDivUp(a, b, 0); - } - - function fullMulDivUp(uint256 a, uint256 b, uint256 d) public pure returns (uint256) { - return FixedPointMathLib.fullMulDivUp(a, b, d); - } - - function testFullMulDivUpRevertsIfRoundedUpResultOverflowsCase1() public { - vm.expectRevert(FixedPointMathLib.FullMulDivFailed.selector); - this.fullMulDivUp( - 535006138814359, 432862656469423142931042426214547535783388063929571229938474969, 2 - ); - } - - function testFullMulDivUpRevertsIfRoundedUpResultOverflowsCase2() public { - vm.expectRevert(FixedPointMathLib.FullMulDivFailed.selector); - this.fullMulDivUp( - 115792089237316195423570985008687907853269984659341747863450311749907997002549, - 115792089237316195423570985008687907853269984659341747863450311749907997002550, - 115792089237316195423570985008687907853269984653042931687443039491902864365164 - ); - } - - function testFullMulDivUnchecked(uint256 a, uint256 b, uint256 d) public { - a = _bound(a, 0, type(uint128).max); - b = _bound(b, 0, type(uint128).max); - d = _bound(d, 1, type(uint256).max); - assertEq(a * b / d, FixedPointMathLib.fullMulDivUnchecked(a, b, d)); - } - - function testFullMulDiv(uint256 a, uint256 b, uint256 d) public returns (uint256 result) { - if (d == 0) { - vm.expectRevert(FixedPointMathLib.FullMulDivFailed.selector); - this.fullMulDiv(a, b, d); - return 0; - } - - // Compute a * b in Chinese Remainder Basis - uint256 expectedA; - uint256 expectedB; - unchecked { - expectedA = a * b; - expectedB = mulmod(a, b, 2 ** 256 - 1); - } - - // Construct a * b - uint256 prod0; // Least significant 256 bits of the product - uint256 prod1; // Most significant 256 bits of the product - /// @solidity memory-safe-assembly - assembly { - let mm := mulmod(a, b, not(0)) - prod0 := mul(a, b) - prod1 := sub(sub(mm, prod0), lt(mm, prod0)) - } - if (prod1 >= d) { - vm.expectRevert(FixedPointMathLib.FullMulDivFailed.selector); - this.fullMulDiv(a, b, d); - return 0; - } - - uint256 q = FixedPointMathLib.fullMulDiv(a, b, d); - uint256 r = mulmod(a, b, d); - - // Compute q * d + r in Chinese Remainder Basis - uint256 actualA; - uint256 actualB; - unchecked { - actualA = q * d + r; - actualB = addmod(mulmod(q, d, 2 ** 256 - 1), r, 2 ** 256 - 1); - } - - assertEq(actualA, expectedA); - assertEq(actualB, expectedB); - return q; - } - - function testFullMulDivN(uint256 a, uint256 b, uint8 n) public { - (bool success0, bytes memory result0) = address(this).staticcall( - abi.encodeWithSignature("fullMulDiv(uint256,uint256,uint256)", a, b, 1 << n) - ); - (bool success1, bytes memory result1) = address(this).staticcall( - abi.encodeWithSignature("fullMulDivN(uint256,uint256,uint8)", a, b, n) - ); - assertEq(success0, success1); - if (success0) { - assertEq(abi.decode(result0, (uint256)), abi.decode(result1, (uint256))); - } - } - - function testFullMulDivUp(uint256 a, uint256 b, uint256 d) public { - uint256 fullMulDivResult = testFullMulDiv(a, b, d); - if (fullMulDivResult != 0) { - uint256 expectedResult = fullMulDivResult; - if (mulmod(a, b, d) > 0) { - if (!(fullMulDivResult < type(uint256).max)) { - vm.expectRevert(FixedPointMathLib.FullMulDivFailed.selector); - this.fullMulDivUp(a, b, d); - return; - } - expectedResult++; - } - assertEq(FixedPointMathLib.fullMulDivUp(a, b, d), expectedResult); - } - } - - function _sampleEdgeCases(int256 x, int256 y) internal returns (int256, int256) { - uint256 r = _randomUniform(); - if (r & 0xf000000 == uint256(0)) y = -1; - if (r & 0x0f00000 == uint256(0)) y = type(int256).min; - if (r & 0x00f0000 == uint256(0)) x = -1; - if (r & 0x000f000 == uint256(0)) x = type(int256).min; - if (r & 0x0000f00 == uint256(0)) y = 0; - if (r & 0x00000f0 == uint256(0)) x = 0; - if (r & 0x000000f == uint256(0)) (x, y) = (int256(_random()), int256(_random())); - return (x, y); - } - - function _sampleEdgeCases(uint256 x, uint256 y) internal returns (uint256, uint256) { - uint256 r = _randomUniform(); - if (r & 0xf000000 == uint256(0)) y = uint256(int256(-1)); - if (r & 0x0f00000 == uint256(0)) y = uint256(type(int256).min); - if (r & 0x00f0000 == uint256(0)) x = uint256(int256(-1)); - if (r & 0x000f000 == uint256(0)) x = uint256(type(int256).min); - if (r & 0x0000f00 == uint256(0)) y = 0; - if (r & 0x00000f0 == uint256(0)) x = 0; - if (r & 0x000000f == uint256(0)) (x, y) = (uint256(_random()), uint256(_random())); - return (x, y); - } - - function mulWadOriginal(uint256 x, uint256 y) public pure returns (uint256) { - return (x * y) / 1e18; - } - - function _mulWadWillFail(uint256 x, uint256 y) internal view returns (bool) { - bytes memory data = abi.encodeWithSignature("mulWadOriginal(uint256,uint256)", x, y); - (bool success,) = address(this).staticcall(data); - return !success; - } - - function testMulWad(uint256 x, uint256 y) public { - (x, y) = _sampleEdgeCases(x, y); - if (_mulWadWillFail(x, y)) { - vm.expectRevert(FixedPointMathLib.MulWadFailed.selector); - this.mulWad(x, y); - return; - } - uint256 result = FixedPointMathLib.mulWad(x, y); - assertEq(result, (x * y) / 1e18); - assertEq(FixedPointMathLib.rawMulWad(x, y), result); - } - - function mulWad(uint256 x, uint256 y) public pure returns (uint256) { - return FixedPointMathLib.mulWad(x, y); - } - - function sMulWadOriginal(int256 x, int256 y) public pure returns (int256) { - return (x * y) / 1e18; - } - - function _sMulWadWillFail(int256 x, int256 y) internal view returns (bool) { - bytes memory data = abi.encodeWithSignature("sMulWadOriginal(int256,int256)", x, y); - (bool success,) = address(this).staticcall(data); - return !success; - } - - function testSMulWad(int256 x, int256 y) public { - (x, y) = _sampleEdgeCases(x, y); - if (_sMulWadWillFail(x, y)) { - vm.expectRevert(FixedPointMathLib.SMulWadFailed.selector); - this.sMulWad(x, y); - return; - } - int256 result = FixedPointMathLib.sMulWad(x, y); - assertEq(result, int256((x * y) / 1e18)); - assertEq(FixedPointMathLib.rawSMulWad(x, y), result); - } - - function sMulWad(int256 x, int256 y) public pure returns (int256) { - return FixedPointMathLib.sMulWad(x, y); - } - - function testMulWadUp(uint256 x, uint256 y) public { - (x, y) = _sampleEdgeCases(x, y); - if (_mulWadWillFail(x, y)) { - vm.expectRevert(FixedPointMathLib.MulWadFailed.selector); - this.mulWadUp(x, y); - return; - } - assertEq(FixedPointMathLib.mulWadUp(x, y), x * y == 0 ? 0 : (x * y - 1) / 1e18 + 1); - } - - function mulWadUp(uint256 x, uint256 y) public pure returns (uint256) { - return FixedPointMathLib.mulWadUp(x, y); - } - - function divWadOriginal(uint256 x, uint256 y) public pure returns (uint256) { - return (x * 1e18) / y; - } - - function _divWadWillFail(uint256 x, uint256 y) internal view returns (bool) { - bytes memory data = abi.encodeWithSignature("divWadOriginal(uint256,uint256)", x, y); - (bool success,) = address(this).staticcall(data); - return !success; - } - - function testDivWad(uint256 x, uint256 y) public { - (x, y) = _sampleEdgeCases(x, y); - if (_divWadWillFail(x, y)) { - vm.expectRevert(FixedPointMathLib.DivWadFailed.selector); - this.divWad(x, y); - return; - } - uint256 result = FixedPointMathLib.divWad(x, y); - assertEq(result, (x * 1e18) / y); - assertEq(FixedPointMathLib.rawDivWad(x, y), result); - } - - function divWad(uint256 x, uint256 y) public pure returns (uint256) { - return FixedPointMathLib.divWad(x, y); - } - - function sDivWadOriginal(int256 x, int256 y) public pure returns (int256) { - return (x * 1e18) / y; - } - - function _sDivWadWillFail(int256 x, int256 y) internal view returns (bool) { - bytes memory data = abi.encodeWithSignature("sDivWadOriginal(int256,int256)", x, y); - (bool success,) = address(this).staticcall(data); - return !success; - } - - function testSDivWad(int256 x, int256 y) public { - (x, y) = _sampleEdgeCases(x, y); - if (_sDivWadWillFail(x, y)) { - vm.expectRevert(FixedPointMathLib.SDivWadFailed.selector); - this.sDivWad(x, y); - return; - } - int256 result = FixedPointMathLib.sDivWad(x, y); - assertEq(result, int256((x * 1e18) / y)); - assertEq(FixedPointMathLib.rawSDivWad(x, y), result); - } - - function sDivWad(int256 x, int256 y) public pure returns (int256) { - return FixedPointMathLib.sDivWad(x, y); - } - - function testDivWadUp(uint256 x, uint256 y) public { - (x, y) = _sampleEdgeCases(x, y); - if (_divWadWillFail(x, y)) { - vm.expectRevert(FixedPointMathLib.DivWadFailed.selector); - this.divWadUp(x, y); - return; - } - assertEq(FixedPointMathLib.divWadUp(x, y), x == 0 ? 0 : (x * 1e18 - 1) / y + 1); - } - - function divWadUp(uint256 x, uint256 y) public pure returns (uint256) { - return FixedPointMathLib.divWadUp(x, y); - } - - function mulDivOriginal(uint256 x, uint256 y, uint256 denominator) - public - pure - returns (uint256) - { - return (x * y) / denominator; - } - - function _mulDivWillFail(uint256 x, uint256 y, uint256 denominator) - internal - view - returns (bool) - { - bytes memory data = - abi.encodeWithSignature("mulDivOriginal(uint256,uint256,uint256)", x, y, denominator); - (bool success,) = address(this).staticcall(data); - return !success; - } - - function testMulDiv(uint256 x, uint256 y, uint256 denominator) public { - (x, y) = _sampleEdgeCases(x, y); - if (_mulDivWillFail(x, y, denominator)) { - vm.expectRevert(FixedPointMathLib.MulDivFailed.selector); - this.mulDiv(x, y, denominator); - return; - } - assertEq(this.mulDiv(x, y, denominator), (x * y) / denominator); - } - - function mulDiv(uint256 x, uint256 y, uint256 d) public pure returns (uint256) { - return FixedPointMathLib.mulDiv(x, y, d); - } - - function testMulDivUp(uint256 x, uint256 y, uint256 denominator) public { - (x, y) = _sampleEdgeCases(x, y); - if (_mulDivWillFail(x, y, denominator)) { - vm.expectRevert(FixedPointMathLib.MulDivFailed.selector); - this.mulDivUp(x, y, denominator); - return; - } - assertEq(this.mulDivUp(x, y, denominator), x * y == 0 ? 0 : (x * y - 1) / denominator + 1); - } - - function testCbrt(uint256 x) public { - uint256 root = FixedPointMathLib.cbrt(x); - uint256 next = root + 1; - - // Ignore cases where `next * next * next` or `next * next` overflows. - unchecked { - if (next * next * next < next * next) return; - if (next * next < next) return; - } - - assertTrue(root * root * root <= x && next * next * next > x); - } - - function testCbrtWad(uint256 x) public { - uint256 result = FixedPointMathLib.cbrtWad(x); - uint256 floor = FixedPointMathLib.cbrt(x); - assertTrue(result >= floor * 10 ** 12 && result <= (floor + 1) * 10 ** 12); - assertEq(result / 10 ** 12, floor); - } - - function testCbrtWadMonotonicallyIncreasing(uint256 x, uint256 y) public { - unchecked { - while (x == type(uint256).max) x = _random(); - uint256 a = FixedPointMathLib.cbrtWad(x); - uint256 b = FixedPointMathLib.cbrtWad(x + 1); - assertLe(a, b); - if (x < y) { - assertLe(a, FixedPointMathLib.cbrtWad(y)); - } else { - assertLe(FixedPointMathLib.cbrtWad(y), a); - } - } - } - - function testCbrtWadMonotonicallyIncreasing() public { - this.testCbrtWadMonotonicallyIncreasing( - 57896044618658097711785492504343953926634992332820282019727, 939263490 - ); - } - - function testCbrtWadConverged(uint256 x) public { - unchecked { - x = _bound(x, type(uint256).max / 10 ** 36, type(uint256).max); - uint256 z = (1 + FixedPointMathLib.cbrt(x)) * 10 ** 12; - z = (FixedPointMathLib.fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3; - uint256 zBefore = z; - z = (FixedPointMathLib.fullMulDivUnchecked(x, 10 ** 36, z * z) + z + z) / 3; - assertLt(FixedPointMathLib.dist(zBefore, z), 2); - } - } - - function testCbrtWadConverged() public { - this.testCbrtWadConverged(149402619197264205146140478723340791358082632884804826834926); - } - - function testCbrtBack(uint256 x) public { - unchecked { - x = _bound(x, 0, 48740834812604276470692694); - while (x != 0) { - assertEq(FixedPointMathLib.cbrt(x * x * x), x); - x >>= 1; - } - } - } - - function testSqrt(uint256 x) public { - uint256 root = FixedPointMathLib.sqrt(x); - uint256 next = root + 1; - - // Ignore cases where `next * next` overflows. - unchecked { - if (next * next < next) return; - } - - assertTrue(root * root <= x && next * next > x); - } - - function testSqrtWad(uint256 x) public { - uint256 result = FixedPointMathLib.sqrtWad(x); - uint256 floor = FixedPointMathLib.sqrt(x); - assertTrue(result >= floor * 10 ** 9 && result <= (floor + 1) * 10 ** 9); - assertEq(result / 10 ** 9, floor); - } - - function testSqrtWadMonotonicallyIncreasing(uint256 x, uint256 y) public { - while (x == type(uint256).max) x = _random(); - uint256 a = FixedPointMathLib.sqrtWad(x); - uint256 b = FixedPointMathLib.sqrtWad(x + 1); - assertLe(a, b); - if (x < y) { - assertLe(a, FixedPointMathLib.sqrtWad(y)); - } else { - assertLe(FixedPointMathLib.sqrtWad(y), a); - } - } - - function testSqrtWadConverged(uint256 x) public { - unchecked { - x = _bound(x, type(uint256).max / 10 ** 18, type(uint256).max); - uint256 z = (1 + FixedPointMathLib.sqrt(x)) * 10 ** 9; - z = (FixedPointMathLib.fullMulDivUnchecked(x, 10 ** 18, z) + z) >> 1; - uint256 zBefore = z; - z = (FixedPointMathLib.fullMulDivUnchecked(x, 10 ** 18, z) + z) >> 1; - assertLt(FixedPointMathLib.dist(zBefore, z), 2); - } - } - - function testSqrtBack(uint256 x) public { - unchecked { - x >>= 128; - while (x != 0) { - assertEq(FixedPointMathLib.sqrt(x * x), x); - x >>= 1; - } - } - } - - function testSqrtHashed(uint256 x) public { - testSqrtBack(uint256(keccak256(abi.encode(x)))); - } - - function testSqrtHashedSingle() public { - testSqrtHashed(123); - } - - function testMin(uint256 x, uint256 y) public { - uint256 z = x < y ? x : y; - assertEq(FixedPointMathLib.min(x, y), z); - } - - function testMinBrutalized(uint256 x, uint256 y) public { - uint32 xCasted; - uint32 yCasted; - /// @solidity memory-safe-assembly - assembly { - xCasted := x - yCasted := y - } - uint256 expected = xCasted < yCasted ? xCasted : yCasted; - assertEq(FixedPointMathLib.min(xCasted, yCasted), expected); - assertEq(FixedPointMathLib.min(uint32(x), uint32(y)), expected); - expected = uint32(x) < uint32(y) ? uint32(x) : uint32(y); - assertEq(FixedPointMathLib.min(xCasted, yCasted), expected); - } - - function testMinSigned(int256 x, int256 y) public { - int256 z = x < y ? x : y; - assertEq(FixedPointMathLib.min(x, y), z); - } - - function testMax(uint256 x, uint256 y) public { - uint256 z = x > y ? x : y; - assertEq(FixedPointMathLib.max(x, y), z); - } - - function testMaxSigned(int256 x, int256 y) public { - int256 z = x > y ? x : y; - assertEq(FixedPointMathLib.max(x, y), z); - } - - function testMaxCasted(uint32 x, uint32 y, uint256 brutalizer) public { - uint32 z = x > y ? x : y; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, brutalizer) - mstore(0x20, 1) - x := or(shl(32, keccak256(0x00, 0x40)), x) - mstore(0x20, 2) - y := or(shl(32, keccak256(0x00, 0x40)), y) - } - assertTrue(FixedPointMathLib.max(x, y) == z); - } - - function testZeroFloorSub(uint256 x, uint256 y) public { - uint256 z = x > y ? x - y : 0; - assertEq(FixedPointMathLib.zeroFloorSub(x, y), z); - } - - function testZeroFloorSubCasted(uint32 x, uint32 y, uint256 brutalizer) public { - uint256 z = x > y ? x - y : 0; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, brutalizer) - mstore(0x20, 1) - x := or(shl(32, keccak256(0x00, 0x40)), x) - mstore(0x20, 2) - y := or(shl(32, keccak256(0x00, 0x40)), y) - } - assertTrue(FixedPointMathLib.zeroFloorSub(x, y) == z); - } - - function testDist(uint256 x, uint256 y) public { - uint256 z; - unchecked { - if (x > y) { - z = uint256(x - y); - } else { - z = uint256(y - x); - } - } - assertEq(FixedPointMathLib.dist(x, y), z); - } - - function testDist(int256 x, int256 y) public { - uint256 z; - unchecked { - if (x > y) { - z = uint256(x - y); - assert(uint256(x) - uint256(y) == z); - } else { - z = uint256(y - x); - assert(uint256(y) - uint256(x) == z); - } - } - assertEq(FixedPointMathLib.dist(x, y), z); - } - - function testAbs(int256 x) public { - uint256 z = uint256(x); - if (x < 0) { - if (x == type(int256).min) { - z = uint256(type(int256).max) + 1; - } else { - z = uint256(-x); - } - } - assertEq(FixedPointMathLib.abs(x), z); - } - - function testGcd(uint256 x, uint256 y) public { - assertEq(FixedPointMathLib.gcd(x, y), _gcd(x, y)); - } - - function testClamp(uint256 x, uint256 minValue, uint256 maxValue) public { - uint256 clamped = x; - if (clamped < minValue) { - clamped = minValue; - } - if (clamped > maxValue) { - clamped = maxValue; - } - assertEq(FixedPointMathLib.clamp(x, minValue, maxValue), clamped); - } - - function testClampSigned(int256 x, int256 minValue, int256 maxValue) public { - int256 clamped = x; - if (clamped < minValue) { - clamped = minValue; - } - if (clamped > maxValue) { - clamped = maxValue; - } - assertEq(FixedPointMathLib.clamp(x, minValue, maxValue), clamped); - } - - function testFactorial() public { - uint256 result = 1; - assertEq(FixedPointMathLib.factorial(0), result); - unchecked { - for (uint256 i = 1; i != 58; ++i) { - result = result * i; - assertEq(FixedPointMathLib.factorial(i), result); - } - } - vm.expectRevert(FixedPointMathLib.FactorialOverflow.selector); - this.factorial(58); - } - - function factorial(uint256 x) public pure returns (uint256) { - return FixedPointMathLib.factorial(x); - } - - function testFactorialOriginal() public { - uint256 result = 1; - assertEq(_factorialOriginal(0), result); - unchecked { - for (uint256 i = 1; i != 58; ++i) { - result = result * i; - assertEq(_factorialOriginal(i), result); - } - } - } - - function _factorialOriginal(uint256 x) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := 1 - for {} x {} { - result := mul(result, x) - x := sub(x, 1) - } - } - } - - function _gcd(uint256 x, uint256 y) internal pure returns (uint256 result) { - if (y == 0) { - return x; - } else { - return _gcd(y, x % y); - } - } - - function testRawAdd(uint256 x, uint256 y) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := add(x, y) - } - assertEq(FixedPointMathLib.rawAdd(x, y), z); - } - - function testRawAdd(int256 x, int256 y) public { - int256 z; - /// @solidity memory-safe-assembly - assembly { - z := add(x, y) - } - assertEq(FixedPointMathLib.rawAdd(x, y), z); - } - - function testRawSub(uint256 x, uint256 y) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := sub(x, y) - } - assertEq(FixedPointMathLib.rawSub(x, y), z); - } - - function testRawSub(int256 x, int256 y) public { - int256 z; - /// @solidity memory-safe-assembly - assembly { - z := sub(x, y) - } - assertEq(FixedPointMathLib.rawSub(x, y), z); - } - - function testRawMul(uint256 x, uint256 y) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - } - assertEq(FixedPointMathLib.rawMul(x, y), z); - } - - function testRawMul(int256 x, int256 y) public { - int256 z; - /// @solidity memory-safe-assembly - assembly { - z := mul(x, y) - } - assertEq(FixedPointMathLib.rawMul(x, y), z); - } - - function testRawDiv(uint256 x, uint256 y) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := div(x, y) - } - assertEq(FixedPointMathLib.rawDiv(x, y), z); - } - - function testRawSDiv(int256 x, int256 y) public { - int256 z; - /// @solidity memory-safe-assembly - assembly { - z := sdiv(x, y) - } - assertEq(FixedPointMathLib.rawSDiv(x, y), z); - } - - function testRawMod(uint256 x, uint256 y) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := mod(x, y) - } - assertEq(FixedPointMathLib.rawMod(x, y), z); - } - - function testRawSMod(int256 x, int256 y) public { - int256 z; - /// @solidity memory-safe-assembly - assembly { - z := smod(x, y) - } - assertEq(FixedPointMathLib.rawSMod(x, y), z); - } - - function testRawAddMod(uint256 x, uint256 y, uint256 denominator) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := addmod(x, y, denominator) - } - assertEq(FixedPointMathLib.rawAddMod(x, y, denominator), z); - } - - function testRawMulMod(uint256 x, uint256 y, uint256 denominator) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := mulmod(x, y, denominator) - } - assertEq(FixedPointMathLib.rawMulMod(x, y, denominator), z); - } - - function testLog10() public { - assertEq(FixedPointMathLib.log10(0), 0); - assertEq(FixedPointMathLib.log10(1), 0); - assertEq(FixedPointMathLib.log10(type(uint256).max), 77); - unchecked { - for (uint256 i = 1; i <= 77; ++i) { - uint256 x = 10 ** i; - assertEq(FixedPointMathLib.log10(x), i); - assertEq(FixedPointMathLib.log10(x - 1), i - 1); - assertEq(FixedPointMathLib.log10(x + 1), i); - } - } - } - - function testLog10(uint256 i, uint256 j) public { - i = _bound(i, 0, 77); - uint256 low = 10 ** i; - uint256 high = i == 77 ? type(uint256).max : (10 ** (i + 1)) - 1; - uint256 x = _bound(j, low, high); - assertEq(FixedPointMathLib.log10(x), i); - } - - function testLog10Up() public { - assertEq(FixedPointMathLib.log10Up(0), 0); - assertEq(FixedPointMathLib.log10Up(1), 0); - assertEq(FixedPointMathLib.log10Up(9), 1); - assertEq(FixedPointMathLib.log10Up(10), 1); - assertEq(FixedPointMathLib.log10Up(99), 2); - assertEq(FixedPointMathLib.log10Up(100), 2); - assertEq(FixedPointMathLib.log10Up(999), 3); - assertEq(FixedPointMathLib.log10Up(1000), 3); - assertEq(FixedPointMathLib.log10Up(10 ** 77), 77); - assertEq(FixedPointMathLib.log10Up(10 ** 77 + 1), 78); - assertEq(FixedPointMathLib.log10Up(type(uint256).max), 78); - } - - function testLog256() public { - assertEq(FixedPointMathLib.log256(0), 0); - assertEq(FixedPointMathLib.log256(1), 0); - assertEq(FixedPointMathLib.log256(256), 1); - assertEq(FixedPointMathLib.log256(type(uint256).max), 31); - unchecked { - for (uint256 i = 1; i <= 31; ++i) { - uint256 x = 256 ** i; - assertEq(FixedPointMathLib.log256(x), i); - assertEq(FixedPointMathLib.log256(x - 1), i - 1); - assertEq(FixedPointMathLib.log256(x + 1), i); - } - } - } - - function testLog256(uint256 i, uint256 j) public { - i = _bound(i, 0, 31); - uint256 low = 256 ** i; - uint256 high = i == 31 ? type(uint256).max : (256 ** (i + 1)) - 1; - uint256 x = _bound(j, low, high); - assertEq(FixedPointMathLib.log256(x), i); - } - - function testLog256Up() public { - assertEq(FixedPointMathLib.log256Up(0), 0); - assertEq(FixedPointMathLib.log256Up(0x01), 0); - assertEq(FixedPointMathLib.log256Up(0x02), 1); - assertEq(FixedPointMathLib.log256Up(0xff), 1); - assertEq(FixedPointMathLib.log256Up(0x0100), 1); - assertEq(FixedPointMathLib.log256Up(0x0101), 2); - assertEq(FixedPointMathLib.log256Up(0xffff), 2); - assertEq(FixedPointMathLib.log256Up(0x010000), 2); - assertEq(FixedPointMathLib.log256Up(0x010001), 3); - assertEq(FixedPointMathLib.log256Up(type(uint256).max - 1), 32); - assertEq(FixedPointMathLib.log256Up(type(uint256).max), 32); - } - - function testSci() public { - _testSci(0, 0, 0); - _testSci(1, 1, 0); - _testSci(13, 13, 0); - _testSci(130, 13, 1); - _testSci(1300, 13, 2); - unchecked { - uint256 a = 103; - uint256 exponent = 0; - uint256 m = 1; - uint256 n = 78 - FixedPointMathLib.log10Up(a); - for (uint256 i; i < n; ++i) { - _testSci(a * m, a, exponent); - exponent += 1; - m *= 10; - } - } - _testSci(10 ** 77, 1, 77); - _testSci(2 * (10 ** 76), 2, 76); - _testSci(9 * (10 ** 76), 9, 76); - unchecked { - for (uint256 i; i < 32; ++i) { - testSci(11 + i * i * 100); - } - for (uint256 i; i < 500; ++i) { - _testSci(0, 0, 0); - } - } - unchecked { - uint256 x = 30000000000000000000000000000000000000000000000001; - _testSci(x, x, 0); - } - } - - function testSci(uint256 a) public { - unchecked { - while (a % 10 == 0) a = _random(); - uint256 exponent = 0; - uint256 m = 1; - uint256 n = 78 - FixedPointMathLib.log10Up(a); - for (uint256 i; i < n; ++i) { - _testSci(a * m, a, exponent); - uint256 x = a * 10 ** exponent; - assertEq(x, a * m); - exponent += 1; - m *= 10; - } - } - } - - function testSci2(uint256 x) public { - unchecked { - (uint256 mantissa, uint256 exponent) = FixedPointMathLib.sci(x); - assertEq(x % 10 ** exponent, 0); - if (x != 0) { - assertTrue(x % 10 ** (exponent + 1) > 0); - assertTrue(mantissa % 10 != 0); - } else { - assertEq(mantissa, 0); - assertEq(exponent, 0); - } - } - } - - function _testSci(uint256 x, uint256 expectedMantissa, uint256 expectedExponent) internal { - (uint256 mantissa, uint256 exponent) = FixedPointMathLib.sci(x); - assertEq(mantissa, expectedMantissa); - assertEq(exponent, expectedExponent); - } - - function unpackSci(uint256 packed) public pure returns (uint256) { - return FixedPointMathLib.unpackSci(packed); - } - - function packSci(uint256 x) public pure returns (uint256) { - return FixedPointMathLib.packSci(x); - } - - function testPackUnpackSci(uint256) public { - unchecked { - uint256 x = (_random() & 0x1) * 10 ** (_random() % 70); - uint8 packed = uint8(FixedPointMathLib.packSci(x)); - uint256 unpacked = FixedPointMathLib.unpackSci(packed); - assertEq(unpacked, x); - } - unchecked { - uint256 x = (_random() & 0x1ff) * 10 ** (_random() % 70); - uint16 packed = uint16(FixedPointMathLib.packSci(x)); - uint256 unpacked = FixedPointMathLib.unpackSci(packed); - assertEq(unpacked, x); - } - unchecked { - uint256 x = (_random() & 0x1ffffff) * 10 ** (_random() % 70); - uint32 packed = uint32(FixedPointMathLib.packSci(x)); - uint256 unpacked = FixedPointMathLib.unpackSci(packed); - assertEq(unpacked, x); - } - unchecked { - uint256 x = (_random() & 0x1ffffffffffffff) * 10 ** (_random() % 60); - uint64 packed = uint64(FixedPointMathLib.packSci(x)); - uint256 unpacked = FixedPointMathLib.unpackSci(packed); - assertEq(unpacked, x); - } - unchecked { - uint256 x = (_random() * 10 ** (_random() % 78)) & ((1 << 249) - 1); - uint256 packed = FixedPointMathLib.packSci(x); - uint256 unpacked = FixedPointMathLib.unpackSci(packed); - assertEq(unpacked, x); - } - } - - function testPackUnpackSci() public { - uint256 mantissaSize = 249; - unchecked { - for (uint256 i; i <= mantissaSize; ++i) { - uint256 x = (1 << i) - 1; - uint256 packed = FixedPointMathLib.packSci(x); - uint256 unpacked = FixedPointMathLib.unpackSci(packed); - assertEq(unpacked, x); - } - } - unchecked { - uint256 x = (1 << (mantissaSize + 1)) - 1; - vm.expectRevert(FixedPointMathLib.MantissaOverflow.selector); - this.packSci(x); - } - } - - function testLerpUint(uint256 a, uint256 b, uint256 t, uint256 begin, uint256 end) public { - assertEq( - _lerpUintOriginal(a, b, t, begin, end), FixedPointMathLib.lerp(a, b, t, begin, end) - ); - } - - function testLerpInt(int256 a, int256 b, int256 t, int256 begin, int256 end) public { - assertEq(_lerpIntOriginal(a, b, t, begin, end), FixedPointMathLib.lerp(a, b, t, begin, end)); - } - - function testLerpUint() public { - uint256 a = 100; - uint256 b = 200; - - assertEq(FixedPointMathLib.lerp(a, b, 0, 5, 10), 100); - assertEq(FixedPointMathLib.lerp(a, b, 5, 5, 10), 100); - assertEq(FixedPointMathLib.lerp(a, b, 10, 5, 10), 200); - assertEq(FixedPointMathLib.lerp(a, b, 15, 5, 10), 200); - assertEq(FixedPointMathLib.lerp(a, b, 6, 5, 10), 120); - assertEq(FixedPointMathLib.lerp(a, b, 9, 5, 10), 180); - - assertEq(FixedPointMathLib.lerp(b, a, 0, 5, 10), 200); - assertEq(FixedPointMathLib.lerp(b, a, 5, 5, 10), 200); - assertEq(FixedPointMathLib.lerp(b, a, 10, 5, 10), 100); - assertEq(FixedPointMathLib.lerp(b, a, 15, 5, 10), 100); - assertEq(FixedPointMathLib.lerp(b, a, 6, 5, 10), 180); - assertEq(FixedPointMathLib.lerp(b, a, 9, 5, 10), 120); - - assertEq(FixedPointMathLib.lerp(b, a, 0, 10, 5), 100); - assertEq(FixedPointMathLib.lerp(b, a, 5, 10, 5), 100); - assertEq(FixedPointMathLib.lerp(b, a, 10, 10, 5), 200); - assertEq(FixedPointMathLib.lerp(b, a, 15, 10, 5), 200); - assertEq(FixedPointMathLib.lerp(b, a, 6, 10, 5), 120); - assertEq(FixedPointMathLib.lerp(b, a, 9, 10, 5), 180); - - assertEq(FixedPointMathLib.lerp(a, b, 0, 10, 5), 200); - assertEq(FixedPointMathLib.lerp(a, b, 5, 10, 5), 200); - assertEq(FixedPointMathLib.lerp(a, b, 10, 10, 5), 100); - assertEq(FixedPointMathLib.lerp(a, b, 15, 10, 5), 100); - assertEq(FixedPointMathLib.lerp(a, b, 6, 10, 5), 180); - assertEq(FixedPointMathLib.lerp(a, b, 9, 10, 5), 120); - } - - function testLerpInt() public { - int256 a = -50; - int256 b = 50; - - assertEq(FixedPointMathLib.lerp(a, b, 0, 5, 10), -50); - assertEq(FixedPointMathLib.lerp(a, b, 5, 5, 10), -50); - assertEq(FixedPointMathLib.lerp(a, b, 10, 5, 10), 50); - assertEq(FixedPointMathLib.lerp(a, b, 15, 5, 10), 50); - assertEq(FixedPointMathLib.lerp(a, b, 6, 5, 10), -30); - assertEq(FixedPointMathLib.lerp(a, b, 9, 5, 10), 30); - - assertEq(FixedPointMathLib.lerp(b, a, 0, 5, 10), 50); - assertEq(FixedPointMathLib.lerp(b, a, 5, 5, 10), 50); - assertEq(FixedPointMathLib.lerp(b, a, 10, 5, 10), -50); - assertEq(FixedPointMathLib.lerp(b, a, 15, 5, 10), -50); - assertEq(FixedPointMathLib.lerp(b, a, 6, 5, 10), 30); - assertEq(FixedPointMathLib.lerp(b, a, 9, 5, 10), -30); - - assertEq(FixedPointMathLib.lerp(b, a, 0, 10, 5), -50); - assertEq(FixedPointMathLib.lerp(b, a, 5, 10, 5), -50); - assertEq(FixedPointMathLib.lerp(b, a, 10, 10, 5), 50); - assertEq(FixedPointMathLib.lerp(b, a, 15, 10, 5), 50); - assertEq(FixedPointMathLib.lerp(b, a, 6, 10, 5), -30); - assertEq(FixedPointMathLib.lerp(b, a, 9, 10, 5), 30); - - assertEq(FixedPointMathLib.lerp(a, b, 0, 10, 5), 50); - assertEq(FixedPointMathLib.lerp(a, b, 5, 10, 5), 50); - assertEq(FixedPointMathLib.lerp(a, b, 10, 10, 5), -50); - assertEq(FixedPointMathLib.lerp(a, b, 15, 10, 5), -50); - assertEq(FixedPointMathLib.lerp(a, b, 6, 10, 5), 30); - assertEq(FixedPointMathLib.lerp(a, b, 9, 10, 5), -30); - } - - function _lerpUintOriginal(uint256 a, uint256 b, uint256 t, uint256 begin, uint256 end) - internal - pure - returns (uint256) - { - if (begin == end) return t <= begin ? a : b; - if (begin < end) { - if (t <= begin) return a; - if (t >= end) return b; - } - if (begin > end) { - if (t >= begin) return a; - if (t <= end) return b; - } - uint256 delta = FixedPointMathLib.fullMulDiv( - FixedPointMathLib.dist(a, b), - FixedPointMathLib.dist(t, begin), - FixedPointMathLib.dist(end, begin) - ); - if (b > a) { - uint256 result = a + delta; - assert(a <= result && result <= b); - return result; - } - if (b < a) { - uint256 result = a - delta; - assert(a >= result && result >= b); - return result; - } - return a; - } - - function _lerpIntOriginal(int256 a, int256 b, int256 t, int256 begin, int256 end) - internal - pure - returns (int256) - { - int256 result1 = _lerpIntOriginal1(a, b, t, begin, end); - int256 result2 = _lerpIntOriginal2(a, b, t, begin, end); - assert(result1 == result2); - return result2; - } - - function _lerpIntOriginal1(int256 a, int256 b, int256 t, int256 begin, int256 end) - internal - pure - returns (int256) - { - if (begin == end) return t <= begin ? a : b; - unchecked { - uint256 w = 1 << 255; - return int256( - _lerpUintOriginal( - uint256(a) + w, - uint256(b) + w, - uint256(t) + w, - uint256(begin) + w, - uint256(end) + w - ) + w - ); - } - } - - function _lerpIntOriginal2(int256 a, int256 b, int256 t, int256 begin, int256 end) - internal - pure - returns (int256) - { - if (begin == end) return t <= begin ? a : b; - if (begin < end) { - if (t <= begin) return a; - if (t >= end) return b; - } - if (begin > end) { - if (t >= begin) return a; - if (t <= end) return b; - } - uint256 delta = FixedPointMathLib.fullMulDiv( - FixedPointMathLib.dist(a, b), - FixedPointMathLib.dist(t, begin), - FixedPointMathLib.dist(end, begin) - ); - unchecked { - if (b > a) { - int256 result = int256(uint256(a) + delta); - assert(a <= result && result <= b); - return result; - } - if (b < a) { - int256 result = int256(uint256(a) - delta); - assert(a >= result && result >= b); - return result; - } - } - return a; - } - - function testCoalesce(uint256 x, uint256 y) public { - assertEq(x == 0 ? y : x, FixedPointMathLib.coalesce(x, y)); - } - - function testCoalesce(address x, address y) public { - assertEq(x == address(0) ? y : x, FixedPointMathLib.coalesce(x, y)); - } - - function testCoalesce(bytes32 x, bytes32 y) public { - assertEq(x == bytes32(0) ? y : x, FixedPointMathLib.coalesce(x, y)); - } - - function testTernary(bool condition, uint256 x, uint256 y) public { - assertEq(condition ? x : y, FixedPointMathLib.ternary(condition, x, y)); - } - - function testTernary(bool condition, bytes32 x, bytes32 y) public { - assertEq(condition ? x : y, FixedPointMathLib.ternary(condition, x, y)); - } - - function testTernary(bool condition, address x, address y) public { - assertEq(condition ? x : y, FixedPointMathLib.ternary(condition, x, y)); - } - - function testIsEven(uint256 x) public { - assertEq(FixedPointMathLib.isEven(x), x % 2 == 0); - } - - function testFullMulEqEquivalence(uint256 a, uint256 b, uint256 x, uint256 y) public { - assertEq(_fullMulEqOriginal(a, b, x, y), FixedPointMathLib.fullMulEq(a, b, x, y)); - } - - function _fullMulEqOriginal(uint256 a, uint256 b, uint256 x, uint256 y) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let xy := mul(x, y) - let z := mulmod(x, y, not(0)) - let ab := mul(a, b) - let c := mulmod(a, b, not(0)) - result := and(eq(xy, ab), eq(sub(z, add(xy, lt(z, xy))), sub(c, add(ab, lt(c, ab))))) - } - } - - function testInvMod(uint256 a, uint256 p) public { - uint256 x = FixedPointMathLib.invMod(a, p); - if (x != 0) { - assertEq(mulmod(a, x, p), 1); - } - } - - function testInvMod() public { - uint256 a = 0xe1b81abec8db239a5c843eff0a1c4472b02982433bb3f538d4e20eb8463330dc; - uint256 n = 0x4b4ecedb4964a40fe416b16c7bd8b46092040ec42ef0aa69e59f09872f105cf3; - uint256 x = 0x164a3ce484b95d23ce8552368f477627a85a1fce9882c3011eb38eda8bcc0dd2; - assertEq(FixedPointMathLib.invMod(a, n), x); - assertEq(FixedPointMathLib.invMod(a, 0), 0); - } - - function testSaturatingAdd(uint256 x, uint256 y) public view { - bytes memory data = abi.encodeWithSignature("add(uint256,uint256)", x, y); - (bool success,) = address(this).staticcall(data); - uint256 expected = !success ? type(uint256).max : x + y; - assert(FixedPointMathLib.saturatingAdd(x, y) == expected); - } - - function testSaturatingAdd() public view { - testSaturatingAdd(123, 456); - } - - function check_SaturatingAddEquivalence(uint256 x, uint256 y) public view { - testSaturatingAdd(x, y); - } - - function add(uint256 x, uint256 y) public pure returns (uint256) { - return x + y; - } - - function testSaturatingMul(uint256 x, uint256 y) public view { - bytes memory data = abi.encodeWithSignature("mul(uint256,uint256)", x, y); - (bool success,) = address(this).staticcall(data); - uint256 expected = !success ? type(uint256).max : x * y; - assert(FixedPointMathLib.saturatingMul(x, y) == expected); - } - - function check_SaturatingMulEquivalence(uint256 x, uint256 y) public view { - testSaturatingMul(x, y); - } - - function testSaturatingMul() public view { - testSaturatingMul(123, 456); - } - - function mul(uint256 x, uint256 y) public pure returns (uint256) { - return x * y; - } - - function testMulSqrtSmall(uint256 x, uint256 y) public { - x = _bound(x, 0, 2 ** 128 - 1); - y = _bound(y, 0, 2 ** 128 - 1); - assertEq(FixedPointMathLib.mulSqrt(x, y), FixedPointMathLib.sqrt(x * y)); - } - - function testMulSqrt(uint256 x, uint256 y) public { - if (x == y) { - assertEq(FixedPointMathLib.mulSqrt(x, y), x); - return; - } - uint256 z = FixedPointMathLib.mulSqrt(x, y); - - emit LogUint("z", z); - (uint256 p0, uint256 p1) = _fullMul(x, y); - (uint256 z0, uint256 z1) = _fullMul(z, z); - - if (z == type(uint256).max) return; - (uint256 zp0, uint256 zp1) = _fullMul(z + 1, z + 1); - - assertTrue((z1 < p1) || (z1 == p1 && z0 <= p0)); - assertTrue((p1 < zp1) || (p1 == zp1 && p0 < zp0)); - } - - function _fullMul(uint256 x, uint256 y) internal pure returns (uint256 p0, uint256 p1) { - /// @solidity memory-safe-assembly - assembly { - p0 := mul(x, y) - let mm := mulmod(x, y, not(0)) - p1 := sub(mm, add(p0, lt(mm, p0))) - } - } - - function _testMulSqrt(uint256 x, uint256 y, uint256 z) public { - assertEq(FixedPointMathLib.mulSqrt(x, y), z); - assertEq(FixedPointMathLib.mulSqrt(y, x), z); - } - - function testMulSqrtDifferential(uint256 x, uint256 y) public { - assertEq(FixedPointMathLib.mulSqrt(x, y), _mulSqrtOriginal(x, y)); - } - - function _mulSqrtOriginal(uint256 x, uint256 y) internal pure returns (uint256 z) { - if (x == 0 || y == 0) return 0; - if (x == y) return x; - uint256 p = FixedPointMathLib.rawMul(x, y); - if (y == p / x) return FixedPointMathLib.sqrt(p); - uint256 sqrtX = FixedPointMathLib.sqrt(x); - uint256 sqrtY = FixedPointMathLib.sqrt(y); - for (z = FixedPointMathLib.saturatingMul(sqrtX + 1, sqrtY + 1);;) { - uint256 zNext = FixedPointMathLib.fullMulDivUnchecked(x, y, z); - zNext = FixedPointMathLib.avg(z, zNext); - if (zNext >= z) break; - z = zNext; - } - } - - function testMulSqrt() public { - // forgefmt: disable-start - this._testMulSqrt(1,40899,202); - this._testMulSqrt(2,126475466778170,15904431); - this._testMulSqrt(1,7531755327269063297785,86785686188); - this._testMulSqrt(4,1145375910940206129316611151348,2140444730368159); - this._testMulSqrt(1,6000249325576079771745702731971550324701397394,77461276297102668974080); - this._testMulSqrt(19990973968927499539515487029982657202480,351588509,2651150077078442553440984); - this._testMulSqrt(884589532366,8944067071329830864412327072945291263924221217993,2812797203510731992653280306277); - this._testMulSqrt(6,231793030923641024945144526163927788762812410599871060107884767317,1179304110711841006457676781313383); - this._testMulSqrt(7,25918817354934577870911410398594504620656949910895919963803454597218,13469659293558320924081748803885430); - this._testMulSqrt(2,6184767715379885918995468503098991544649672240672289523626396828206377,111218413182169488449746241587513722); - this._testMulSqrt(11262102866604455182725961449733527925032397745743648245810757,2289531243,160576886179084819940315039841174360); - this._testMulSqrt(2,386128680208745785717489332755004235996307094856550925460526784315796445,878781747885953518587400193470685282); - this._testMulSqrt(20,133823397008372075942399557492827432876972721009673572412945073431794356,1635991424234076331806369976651119304); - this._testMulSqrt(64385011511148092020199840672969561808819251747679314637,16788189010063055495896874,32877161414335023454300652451233783772805); - this._testMulSqrt(307695058396291282867900569126929438472472421745,16650777576165153239643978609535636374,2263484477225720726470604509270073120374679); - this._testMulSqrt(37369048817028070,403547546041382623075657545097967233546021171804178222743888832459267032,122801416718262293521136665081803979269652981); - this._testMulSqrt(108757921013865829718776238158835403990222487425921424856119171941423640,311530010377180825,184068889989727037643726419490138992138431758); - this._testMulSqrt(71968390915585988831780603371197224690006783200448692196810504,1317434458380206291313344071812603846743105529396590981616,307918232825485645925260268942424415111262027158036186068393); - this._testMulSqrt(169786846411291950176086783315992030432326301383306594102503280,262091314248283560844199184902391093238338514869222967307939442153535,210949419809600269188992711762466980237552872839406150493359215238); - this._testMulSqrt(13125530490447682132624267118512105994743022946653752643039816341671957523,2703992648396778482623576839914577810228120087337379417522074085943689092,5957460696679273501196497896950129901097275853419042552123499864438199223); - this._testMulSqrt(759343816572101418250144283506759951951139556413747077593352856047453741042,5783606897390246194179048291049046711192537808438654462819097925235107871790,2095649334935842670420229418803511179917932829424728325651967137561547960515); - this._testMulSqrt(1453693402301034209593542434097237131647588800659364354488100189009468111235,3021095182839377497836893600683197190212994171204262758821708252445961887922,2095649334935842670420229418803511179917932829424728325651967137561547960515); - this._testMulSqrt(1500322080289732537847477243966572315817180906638531006084846839970956040737,2927202227250387439989971689119336628619848415002314520835497068418776903816,2095649334935842670420229418803511179917932829424728325651967137561547960515); - this._testMulSqrt(1418188734037590650038894298784738194557827267133881612919761886151138174982,3096728968163296409290287978802863257249612545684811929660405453902456993799,2095649334935842670420229418803511179917932829424728325651967137561547960515); - this._testMulSqrt(72649803940522399886719930058523700039023197833404875144131115786317960957502,1058032812382543109188733542274803566994606781443813721786480120922367936989,8767318654082973239818507301503235653779978250722724160009440005060322575671); - this._testMulSqrt(5373922104039726654109199686576171393319670483688158333460332678277457737472,29698357225200387337129817970745776673739254860209898274723677280893657304883,12633157101301807356759851956784431867751428103301339039224348881394628761742); - this._testMulSqrt(4110435947028096136332171788401813256200194295940648314773165026203401589664,47629135145959642265403944627116611572745368779360562832098585565036412006720,13992015910147179362140946267238865150610331346635053034797342180359096262561); - this._testMulSqrt(6670439349065019066867111962665902305718250536829827331422008770563721526834,23925958995271068490107533294147958150213516645841822380228819548185161301331,12633157101301807356759851956784431867751428103301339039224348881394628761742); - this._testMulSqrt(2969132035655378982552797810065716750184480456087472143547576763384185040150,65937286344558903530415649738599306075672958462949062884739418323163356428267,13992015910147179362140946267238865150610331346635053034797342180359096262561); - this._testMulSqrt(7491404489992521390184991330802592986343520371455692604718960104437178752665,21303970244748005562096092471791804290084308713402287738808276131330039069727,12633157101301807356759851956784431867751428103301339039224348881394628761742); - this._testMulSqrt(6121895596657181220666267444651436648237333295237933576541838582595521000977,70855413278339511916656827078592824537105782268733407488004367896456997184904,20827132364970253561103779902092578934359252280464989168083476470668469620748); - this._testMulSqrt(9663464530001823655566072879594302677711586601817760096066022478590461523681,44887570208519155988166566051306580252890388816305191368753991821976222373501,20827132364970253561103779902092578934359252280464989168083476470668469620748); - this._testMulSqrt(3146233082020622571934575333002634745373987161876939823151669615808091349575,62225685168905914639685682949327855631601195004914029384687573254167511859580,13992015910147179362140946267238865150610331346635053034797342180359096262561); - this._testMulSqrt(81292148375414543538357432189784118864691517292040335173170009268459477601704,2516741501174680293198396542611706642053439931235618117323066049365884914216,14303542342233117118521903523784342299628960478384746102119577025303325649767); - this._testMulSqrt(6235952310590095577242208648287326629803669887249954646740971273060426215074,86267974483515850745154997335441073241510839437043584529161844505392388495406,23194028861118718470348997581404528819309525163067296635449034115712705381145); - this._testMulSqrt(8202270509291188368161098479682643484535231613691719026429761609950890177708,110093889479585348411203054124693950081761292952495296567025182505398163143046,30050288899302887082115267696735954136708432495128508248566789198018211109331); - this._testMulSqrt(58567595367007003434029003100140382325611053031291395486564269268008176012515,58567595367007003434029003100140382325611053031291395486564269268008176012528,58567595367007003434029003100140382325611053031291395486564269268008176012521); - this._testMulSqrt(66674750232480974592958260963213523118377591895163248013022969308057159666106,66674750232480974592958260963213523118377591895163248013022969308057159666106,66674750232480974592958260963213523118377591895163248013022969308057159666106); - this._testMulSqrt(33585912866580500017428740937261524277391765196007489833430561956127819834566,52199687981615271967060816285063413507671559301970565963089267667884242865491,41870922753304826754657295225348362266441633929084405750532911003697653673376); - this._testMulSqrt(67059371761480772870120378810526551624172903367552398549958050667166366320070,18204720352041367142096118905131984188387648432760494796813976946511020703864,34939907124967249547474326305667618125822338407481424538436068764138475863743); - this._testMulSqrt(91758599666022652235931878429035236115420549503042702161402892861112704213437,91758599666022652235931878429035236115420549503042702161402892861112704213446,91758599666022652235931878429035236115420549503042702161402892861112704213441); - this._testMulSqrt(57643576768106877450231061433780292981040727232162059949268652098179482795200,25879261867897264383063632807223059137462762609820894729277419678914890663158,38623480140765111324896240658186465312359836452286369356057144242747750076434); - this._testMulSqrt(97780904848435401688577228945316029068942540304391356583531299677110827351347,97780904848435401688577228945316029068942540304391356583531299677110827351347,97780904848435401688577228945316029068942540304391356583531299677110827351347); - this._testMulSqrt(39125312885387593452616334467597728868299242980364796136151236474971873470685,86828779128818620639494340617473793523235661436852771257233255355108198117255,58285531230925917668113509553487197292966405880544341575100636208705254025063); - this._testMulSqrt(28103463145585940293035771056326313713678024127581863885732629790555352610632,76815787111206973955699536219912347630679580756295209504314028436731758019833,46462776951867402066001606132202385212266391791890179377014155917534178988307); - this._testMulSqrt(55085887312063313304662947434367535525632525671759520071608379009942981796106,82800294118819938958395766683447025163837791408331540436336605895422829072207,67536121233270524981094905764087840435055016173869770891190734091029911998939); - this._testMulSqrt(11374112687571915868904337573234209429066724575146519193518714103220820309055,38136552227230499196160353868270595333171776294556651442476000096535825394060,20827132364970253561103779902092578934359252280464989168083476470668469620748); - this._testMulSqrt(58730317605090576282758883651000593881824017604589031401161423874294761362545,58730317605090576282758883651000593881824017604589031401161423874294761362556,58730317605090576282758883651000593881824017604589031401161423874294761362550); - this._testMulSqrt(50831499485199945339590926255329493296549952108872771415944026608406615545066,50831499485199945339590926255329493296549952108872771415944026608406615545075,50831499485199945339590926255329493296549952108872771415944026608406615545070); - this._testMulSqrt(85172087893546842302544308826796315864783084900992147451076334534702648635115,85172087893546842302544308826796315864783084900992147451076334534702648635115,85172087893546842302544308826796315864783084900992147451076334534702648635115); - this._testMulSqrt(65565054857983221818976561024613786630057794203730058177227059603745603013729,65565054857983221818976561024613786630057794203730058177227059603745603013729,65565054857983221818976561024613786630057794203730058177227059603745603013729); - this._testMulSqrt(55911495894251782213187662010802819104143247543461889936919543738942314665456,55911495894251782213187662010802819104143247543461889936919543738942314665463,55911495894251782213187662010802819104143247543461889936919543738942314665459); - this._testMulSqrt(17879363847304668652748901453932635872715480532463893033011272860213208357255,30088485217079270634851249038350032152097092409273038120371466325762898598320,23194028861118718470348997581404528819309525163067296635449034115712705381145); - this._testMulSqrt(22574079799238893389795996210248534007844658027018240720384507454263215868089,23831003504672027024172723977212295224054264531333207324229467512231849039503,23194028861118718470348997581404528819309525163067296635449034115712705381145); - this._testMulSqrt(10611306079283782718696192094919244168932152831659131747498031131196511452379,15040246427133913011360593741211490257502964477997080664156994032702222657211,12633157101301807356759851956784431867751428103301339039224348881394628761742); - this._testMulSqrt(73858585336675259861717749966041474360396794822352124567893338971277971476418,73858585336675259861717749966041474360396794822352124567893338971277971476418,73858585336675259861717749966041474360396794822352124567893338971277971476418); - this._testMulSqrt(93493926051444437853990951601184659120548710831844470529111733337613793165495,54214116350546943146180291574636539900604297425564498997024649792129389692208,71194737059858860760008503832934929635934877910339827282451164211383009505882); - this._testMulSqrt(31741633454414803277828892614935784705765176373701489896871054927885458857680,31741633454414803277828892614935784705765176373701489896871054927885458857683,31741633454414803277828892614935784705765176373701489896871054927885458857681); - this._testMulSqrt(73131310464141944405157343302384814531452681906375563388541324773631263794690,73131310464141944405157343302384814531452681906375563388541324773631263794693,73131310464141944405157343302384814531452681906375563388541324773631263794691); - this._testMulSqrt(65455015498287996254702939291233980776874205016778705952818114191323439048349,65455015498287996254702939291233980776874205016778705952818114191323439048349,65455015498287996254702939291233980776874205016778705952818114191323439048349); - this._testMulSqrt(81462032043753857067983762687246123130574773932537561797650535926862438796461,81462032043753857067983762687246123130574773932537561797650535926862438796478,81462032043753857067983762687246123130574773932537561797650535926862438796469); - this._testMulSqrt(78209457813515644067726265623499202575598482171839000555604704620897437284905,78209457813515644067726265623499202575598482171839000555604704620897437284905,78209457813515644067726265623499202575598482171839000555604704620897437284905); - this._testMulSqrt(13412474850080548643225312277495789264111309375181229577549786099110203380624,40109150684236126557038510591608000846411423768057235283250658763488731560550,23194028861118718470348997581404528819309525163067296635449034115712705381145); - this._testMulSqrt(40011146698470653129691243350367280704077684991355208240666470591824566065223,40011146698470653129691243350367280704077684991355208240666470591824566065236,40011146698470653129691243350367280704077684991355208240666470591824566065229); - this._testMulSqrt(84469863776974389618863256801434264209320466806351315058376170339221016552781,105252699476938925947685053655574147531645177588390239327939130772357535593314,94290408775102118898547330988195929704226272047925587806802926560630963930928); - this._testMulSqrt(30101390199343843269859768555851977933764901751609935209985867350357455919180,112858679561759692460068611865224624921408338260436569801949431998683320106122,58285531230925917668113509553487197292966405880544341575100636208705254025063); - this._testMulSqrt(49252281286569566201714256790755535986103544271522937010444395775245383022031,103313582627134147756455088718855511170155287731084491962378585746899181375663,71333229509639179283943164935234626333287573837435931792829607795291911850054); - this._testMulSqrt(103203975778750389840486623148704163858899099747818966282132716369708045200084,103203975778750389840486623148704163858899099747818966282132716369708045200084,103203975778750389840486623148704163858899099747818966282132716369708045200084); - this._testMulSqrt(107596843987355231847546681774981365988735519046298392541656481902159008087733,107596843987355231847546681774981365988735519046298392541656481902159008087733,107596843987355231847546681774981365988735519046298392541656481902159008087733); - this._testMulSqrt(102830484155533021557704227144831932637592583365851544616380718131012301176108,102830484155533021557704227144831932637592583365851544616380718131012301176108,102830484155533021557704227144831932637592583365851544616380718131012301176108); - this._testMulSqrt(115780671983614014435071450400947059939097134791386840528286481782155947852587,115780671983614014435071450400947059939097134791386840528286481782155947852608,115780671983614014435071450400947059939097134791386840528286481782155947852597); - this._testMulSqrt(102599946188735338018377241438053351371953655256423785960693281164040632229692,113977391922349753717143966833940674036437676311140700292665530749893373322354,108139143134969783777522484667256465358316928947625235238969806848330075092141); - this._testMulSqrt(104750355640940008131284436009813329129514270958235948287118057008845178828468,111637561575924997019627058419809811559908173308145846004665185899087410950352,108139143134969783777522484667256465358316928947625235238969806848330075092141); - // forgefmt: disable-end - } -} diff --git a/grouperBot/lib/solady/test/GasBurnerLib.t.sol b/grouperBot/lib/solady/test/GasBurnerLib.t.sol deleted file mode 100644 index 2b5b8eb..0000000 --- a/grouperBot/lib/solady/test/GasBurnerLib.t.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {GasBurnerLib} from "../src/utils/GasBurnerLib.sol"; - -contract GasBurnerLibTest is SoladyTest { - event LogGasBurn(uint256 required, uint256 actual); - - function testBurnPure() public { - _testBurnPure(0); - _testBurnPure(1); - _testBurnPure(110); - _testBurnPure(119); - _testBurnPure(120); - _testBurnPure(121); - _testBurnPure(300); - for (uint256 x = 300; x < 9000; x += 32) { - _testBurnPure(x); - } - } - - function testBurnView() public { - _testBurnView(1 * 3000); - _testBurnView(2 * 3000); - _testBurnView(3 * 3000); - _testBurnView(4 * 3000); - _testBurnView(5 * 3000); - _testBurnView(9 * 3000); - } - - function testBurn() public { - _testBurn(20000); - _testBurn(30000); - _testBurn(50000); - } - - function testBurnPure(uint256 x) public { - x = _bound(x, 0, _randomChance(512) ? 30000000 : 5000); - GasBurnerLib.burnPure(x); - } - - function testBurnView(uint256 x) public { - x = _bound(x, 0, _randomChance(512) ? 30000000 : 15000); - GasBurnerLib.burnView(x); - } - - function testBurn(uint256 x) public { - x = _bound(x, 0, _randomChance(512) ? 30000000 : 60000); - GasBurnerLib.burn(x); - } - - function testBurnPureTiming() public pure { - GasBurnerLib.burnPure(300000); - } - - function testBurnViewTiming() public view { - GasBurnerLib.burnView(300000); - } - - function testBurnTiming() public { - GasBurnerLib.burn(300000); - } - - function _testBurnPure(uint256 x) internal { - unchecked { - uint256 gasBefore = gasleft(); - GasBurnerLib.burnPure(x); - uint256 gasAfter = gasleft(); - emit LogGasBurn(x, gasBefore - gasAfter); - } - } - - function _testBurnView(uint256 x) internal { - unchecked { - uint256 gasBefore = gasleft(); - GasBurnerLib.burnView(x); - uint256 gasAfter = gasleft(); - emit LogGasBurn(x, gasBefore - gasAfter); - } - } - - function _testBurn(uint256 x) internal { - unchecked { - uint256 gasBefore = gasleft(); - GasBurnerLib.burn(x); - uint256 gasAfter = gasleft(); - emit LogGasBurn(x, gasBefore - gasAfter); - } - } -} diff --git a/grouperBot/lib/solady/test/Initializable.t.sol b/grouperBot/lib/solady/test/Initializable.t.sol deleted file mode 100644 index b7b5255..0000000 --- a/grouperBot/lib/solady/test/Initializable.t.sol +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MockInitializable, Initializable} from "./utils/mocks/MockInitializable.sol"; - -contract InitializableTest is SoladyTest { - event Initialized(uint64 version); - - MockInitializable m; - - function setUp() public { - MockInitializable.Args memory a; - m = new MockInitializable(a); - } - - function _args() internal returns (MockInitializable.Args memory a) { - a.x = _random(); - a.version = uint64(_bound(_random(), 1, type(uint64).max)); - a.checkOnlyDuringInitializing = _random() & 1 == 0; - a.recurse = _random() & 1 == 0; - } - - function _expectEmitInitialized(uint64 version) internal { - vm.expectEmit(true, true, true, true); - emit Initialized(version); - } - - function testInitialize() public { - MockInitializable.Args memory a; - a.x = 123; - m.initialize(a); - assertEq(m.x(), a.x); - _checkVersion(1); - } - - function _checkVersion(uint64 version) internal { - assertEq(m.version(), version); - assertFalse(m.isInitializing()); - } - - function testInitializeReinititalize(uint256) public { - MockInitializable.Args memory a = _args(); - - if (a.recurse) { - vm.expectRevert(Initializable.InvalidInitialization.selector); - if (_random() & 1 == 0) { - m.initialize(a); - } else { - m.reinitialize(a); - } - return; - } - - if (_random() & 1 == 0) { - _expectEmitInitialized(1); - m.initialize(a); - a.version = 1; - } else { - _expectEmitInitialized(a.version); - m.reinitialize(a); - } - assertEq(m.x(), a.x); - _checkVersion(a.version); - - if (_random() & 1 == 0) { - vm.expectRevert(Initializable.InvalidInitialization.selector); - m.initialize(a); - } - if (_random() & 1 == 0) { - vm.expectRevert(Initializable.InvalidInitialization.selector); - m.reinitialize(a); - } - if (_random() & 1 == 0) { - a.version = m.version(); - uint64 newVersion = uint64(_random()); - if (newVersion > a.version) { - a.version = newVersion; - m.reinitialize(a); - _checkVersion(a.version); - } - } - } - - function testOnlyInitializing() public { - vm.expectRevert(Initializable.NotInitializing.selector); - m.onlyDuringInitializing(); - } - - function testDisableInitializers() public { - _expectEmitInitialized(type(uint64).max); - m.disableInitializers(); - _checkVersion(type(uint64).max); - m.disableInitializers(); - _checkVersion(type(uint64).max); - - MockInitializable.Args memory a; - vm.expectRevert(Initializable.InvalidInitialization.selector); - m.initialize(a); - vm.expectRevert(Initializable.InvalidInitialization.selector); - m.reinitialize(a); - } - - function testInitializableConstructor() public { - MockInitializable.Args memory a; - a.initializeMulti = true; - m = new MockInitializable(a); - _checkVersion(1); - - vm.expectRevert(Initializable.InvalidInitialization.selector); - m.initialize(a); - a.version = 2; - m.reinitialize(a); - _checkVersion(2); - - a.disableInitializers = true; - _expectEmitInitialized(type(uint64).max); - m = new MockInitializable(a); - _checkVersion(type(uint64).max); - vm.expectRevert(Initializable.InvalidInitialization.selector); - m.initialize(a); - vm.expectRevert(Initializable.InvalidInitialization.selector); - m.reinitialize(a); - } - - function testInitializeInititalizerTrick( - bool initializing, - uint64 initializedVersion, - uint16 codeSize - ) public { - bool isTopLevelCall = !initializing; - bool initialSetup = initializedVersion == 0 && isTopLevelCall; - bool construction = initializedVersion == 1 && codeSize == 0; - bool expected = !initialSetup && !construction; - bool computed; - uint256 i; - /// @solidity memory-safe-assembly - assembly { - i := or(initializing, shl(1, initializedVersion)) - if i { if iszero(lt(codeSize, eq(shr(1, i), 1))) { computed := 1 } } - } - assertEq(computed, expected); - } - - function testInitializeReinititalizerTrick( - bool initializing, - uint64 initializedVersion, - uint64 version - ) public { - bool expected = initializing == true || initializedVersion >= version; - bool computed; - /// @solidity memory-safe-assembly - assembly { - let i := or(initializing, shl(1, initializedVersion)) - computed := iszero(lt(and(i, 1), lt(shr(1, i), version))) - } - assertEq(computed, expected); - } -} diff --git a/grouperBot/lib/solady/test/JSONParserLib.t.sol b/grouperBot/lib/solady/test/JSONParserLib.t.sol deleted file mode 100644 index 32475ed..0000000 --- a/grouperBot/lib/solady/test/JSONParserLib.t.sol +++ /dev/null @@ -1,816 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {JSONParserLib} from "../src/utils/JSONParserLib.sol"; -import {LibString} from "../src/utils/LibString.sol"; -import {Base64} from "../src/utils/Base64.sol"; - -contract JSONParserLibTest is SoladyTest { - using JSONParserLib for *; - - function testParseInvalidReverts() public { - _checkParseReverts(""); - _checkParseReverts("e"); - _checkParseReverts("abc"); - _checkParseReverts("1,2"); - _checkParseReverts("["); - _checkParseReverts("]"); - _checkParseReverts("{"); - _checkParseReverts("}"); - _checkParseReverts("[[]"); - _checkParseReverts("[]["); - _checkParseReverts("[][]"); - _checkParseReverts("[],[]"); - _checkParseReverts("[1,2"); - _checkParseReverts("1,2]"); - _checkParseReverts("[1"); - _checkParseReverts("1]"); - _checkParseReverts("[1,"); - _checkParseReverts("{}{"); - _checkParseReverts("{}{}"); - _checkParseReverts("{},{}"); - _checkParseReverts("{]"); - _checkParseReverts("{{}"); - _checkParseReverts("{}}"); - _checkParseReverts("[,]"); - _checkParseReverts("[0,]"); - _checkParseReverts("[0,1,]"); - _checkParseReverts("[0,,]"); - _checkParseReverts("[0,,1]"); - _checkParseReverts("[,0]"); - _checkParseReverts("{,}"); - _checkParseReverts('{"a"}'); - _checkParseReverts('{"a":"A",}'); - _checkParseReverts('{"a":"A","b":"B",}'); - _checkParseReverts('{"a":"A"b":"B"}'); - _checkParseReverts('{"a":"A",,"b":"B"}'); - _checkParseReverts('{,"a":"A","b":"B"}'); - _checkParseReverts('{"a"::"A"}'); - _checkParseReverts('{"a","A"}'); - _checkParseReverts("{1}"); - _checkParseReverts("{:}"); - } - - function testParseInvalidNumberReverts() public { - _checkParseReverts("01234567890"); - _checkParseReverts("-1.234567890e-a"); - _checkParseReverts("-1.234567890e-"); - _checkParseReverts("-1.234567890e+a"); - _checkParseReverts("-1.234567890e+"); - _checkParseReverts("-1.234567890z"); - _checkParseReverts("-1.234567890e"); - _checkParseReverts("-00.234567890"); - _checkParseReverts("-.234567890"); - _checkParseReverts("-00"); - _checkParseReverts("--0"); - _checkParseReverts("00"); - _checkParseReverts("0."); - _checkParseReverts("0..12"); - _checkParseReverts("0.0e"); - _checkParseReverts("."); - _checkParseReverts("-"); - _checkParseReverts("+"); - _checkParseReverts("e"); - _checkParseReverts("+123"); - _checkParseReverts(".123"); - _checkParseReverts("e123"); - _checkParseReverts("1 e 1"); - _checkParseReverts("-1.e+0"); - _checkParseReverts("0x"); - } - - function _checkParseReverts(string memory trimmed) internal { - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.parsedValue(trimmed); - string memory s = trimmed; - for (uint256 i; i != 4; ++i) { - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.parsedValue(_padWhiteSpace(s, i)); - } - } - - function parsedValue(string memory s) public view miniBrutalizeMemory returns (string memory) { - s = s.parse().value(); - _checkMemory(s); - return s; - } - - function testParseNumber() public { - _checkParseNumber("0"); - _checkParseNumber("-0"); - _checkParseNumber("-1.2e+0"); - _checkParseNumber("-1.2e+00"); - _checkParseNumber("-1.2e+001"); - _checkParseNumber("-1.2e+22"); - _checkParseNumber("-1.2e-22"); - _checkParseNumber("-1.2e22"); - _checkParseNumber("0.1"); - _checkParseNumber("0.123"); - _checkParseNumber("12345678901234567890123456789012345678901234567890"); - _checkParseNumber("12345e12345678901234567890123456789012345678901234567890"); - _checkParseNumber("1234567890"); - _checkParseNumber("123"); - _checkParseNumber("1"); - } - - function _checkParseNumber(string memory trimmed) internal { - _checkSoloNumber(trimmed.parse(), trimmed); - string memory s = trimmed; - for (uint256 i; i != 4; ++i) { - _checkSoloNumber(_padWhiteSpace(s, i).parse(), trimmed); - } - } - - function _checkSoloNumber(JSONParserLib.Item memory item, string memory trimmed) internal { - for (uint256 i; i != 2; ++i) { - assertEq(item.getType(), JSONParserLib.TYPE_NUMBER); - assertEq(item.isNumber(), true); - assertEq(item.value(), trimmed); - _checkItemIsSolo(item); - } - } - - function testParseEmptyArrays() public { - _checkParseEmptyArray("[]"); - _checkParseEmptyArray("[ ]"); - _checkParseEmptyArray("[ ]"); - } - - function _checkParseEmptyArray(string memory trimmed) internal { - _checkSoloEmptyArray(trimmed.parse(), trimmed); - string memory s = trimmed; - for (uint256 i; i != 16; ++i) { - _checkSoloEmptyArray(_padWhiteSpace(s, i).parse(), trimmed); - } - } - - function _checkSoloEmptyArray(JSONParserLib.Item memory item, string memory trimmed) internal { - for (uint256 i; i != 2; ++i) { - assertEq(item.getType(), JSONParserLib.TYPE_ARRAY); - assertEq(item.isArray(), true); - assertEq(item.value(), trimmed); - _checkItemIsSolo(item); - } - } - - function testParseEmptyObjects() public { - _checkParseEmptyObject("{}"); - _checkParseEmptyObject("{ }"); - _checkParseEmptyObject("{ }"); - } - - function _checkParseEmptyObject(string memory trimmed) internal { - _checkSoloEmptyObject(trimmed.parse(), trimmed); - string memory s = trimmed; - for (uint256 i; i != 16; ++i) { - _checkSoloEmptyObject(_padWhiteSpace(s, i).parse(), trimmed); - } - } - - function _checkSoloEmptyObject(JSONParserLib.Item memory item, string memory trimmed) - internal - { - for (uint256 i; i != 2; ++i) { - assertEq(item.getType(), JSONParserLib.TYPE_OBJECT); - assertEq(item.isObject(), true); - assertEq(item.value(), trimmed); - _checkItemIsSolo(item); - } - } - - function _padWhiteSpace(string memory s, uint256 r) internal pure returns (string memory) { - unchecked { - uint256 q = r; - r = r % 3; - string memory p = r == 0 ? " " : r == 1 ? "\t" : r == 2 ? "\r" : "\n"; - q = 1 + q / 3; - for (uint256 i; i != q; ++i) { - s = string(abi.encodePacked(p, s, p)); - } - return s; - } - } - - function testParseSimpleUintArray() public { - string memory s; - JSONParserLib.Item memory item; - - for (uint256 k; k != 9; ++k) { - uint256 o = k == 0 ? 0 : 1 << (17 * k); - string memory p = _padWhiteSpace("", k); - for (uint256 j; j != 5; ++j) { - s = "["; - for (uint256 i; i != j; ++i) { - string memory x = LibString.toString(o + i); - if (i == 0) { - s = string(abi.encodePacked(s, p, x)); - } else { - s = string(abi.encodePacked(s, p, ",", p, x)); - } - } - s = string(abi.encodePacked(s, "]")); - item = s.parse(); - assertEq(item.isArray(), true); - assertEq(item.size(), j); - for (uint256 i; i != j; ++i) { - string memory x = LibString.toString(o + i); - assertEq(item.children()[i].value(), x); - assertEq(item.children()[i].parent()._data, item._data); - assertEq(item.children()[i].parent().isArray(), true); - assertEq(item.at(i)._data, item.children()[i]._data); - assertEq(item.at(LibString.toString(i))._data, 0); - } - } - } - } - - function testEmptyItem() public { - JSONParserLib.Item memory item; - assertEq(item.value(), ""); - assertEq(item.isUndefined(), true); - assertEq(item.parent().isUndefined(), true); - assertEq(item.parent().parent().isUndefined(), true); - assertEq(item.key(), ""); - assertEq(item.at(0).isUndefined(), true); - assertEq(item.at(0).at(0).isUndefined(), true); - } - - function testParseSimpleArray() public { - string memory s = '["hehe",12,"haha"]'; - JSONParserLib.Item memory item = s.parse(); - - assertEq(item.isArray(), true); - assertEq(item.size(), 3); - _checkItemHasNoParent(item); - - assertEq(item.children()[0].value(), '"hehe"'); - assertEq(item.children()[0].index(), 0); - assertEq(item.children()[0].getType(), JSONParserLib.TYPE_STRING); - assertEq(item.children()[0].key(), ""); - assertEq(item.children()[0].parent()._data, item._data); - assertEq(item.children()[0].parent().isArray(), true); - - assertEq(item.children()[1].value(), "12"); - assertEq(item.children()[1].index(), 1); - assertEq(item.children()[1].key(), ""); - assertEq(item.children()[1].getType(), JSONParserLib.TYPE_NUMBER); - assertEq(item.children()[1].parent()._data, item._data); - assertEq(item.children()[1].parent().isArray(), true); - - assertEq(item.children()[2].value(), '"haha"'); - assertEq(item.children()[2].index(), 2); - assertEq(item.children()[2].getType(), JSONParserLib.TYPE_STRING); - assertEq(item.children()[2].key(), ""); - assertEq(item.children()[2].parent()._data, item._data); - assertEq(item.children()[2].parent().isArray(), true); - - assertEq(item.at(0)._data, item.children()[0]._data); - assertEq(item.at(1)._data, item.children()[1]._data); - assertEq(item.at(2)._data, item.children()[2]._data); - assertEq(item.at(3)._data, 0); - } - - function testParseSpecials() public miniBrutalizeMemory { - string memory s; - JSONParserLib.Item memory item; - - for (uint256 k; k < 9; ++k) { - s = _padWhiteSpace("true", k); - item = s.parse(); - assertEq(item.getType(), JSONParserLib.TYPE_BOOLEAN); - assertEq(item.isBoolean(), true); - assertEq(item.isNull(), false); - assertEq(item.value(), "true"); - assertEq(item.parent().isUndefined(), true); - _checkItemIsSolo(item); - - s = _padWhiteSpace("false", k); - item = s.parse(); - assertEq(item.getType(), JSONParserLib.TYPE_BOOLEAN); - assertEq(item.isBoolean(), true); - assertEq(item.isNull(), false); - assertEq(item.value(), "false"); - _checkItemIsSolo(item); - - s = _padWhiteSpace("null", k); - item = s.parse(); - assertEq(item.getType(), JSONParserLib.TYPE_NULL); - assertEq(item.isBoolean(), false); - assertEq(item.isNull(), true); - assertEq(item.value(), "null"); - _checkItemIsSolo(item); - } - - for (uint256 k; k != 4; ++k) { - if (k == 0) s = "[true,false,null]"; - if (k == 1) s = "[ true , false , null ]"; - if (k == 2) s = '{"A":true,"B":false,"C":null}'; - if (k == 3) s = '{ "A" : true , "B" : false , "C" : null }'; - item = s.parse(); - assertEq(item.size(), 3); - assertEq(item.children()[0].getType(), JSONParserLib.TYPE_BOOLEAN); - assertEq(item.children()[0].value(), "true"); - assertEq(item.children()[1].getType(), JSONParserLib.TYPE_BOOLEAN); - assertEq(item.children()[1].value(), "false"); - assertEq(item.children()[2].getType(), JSONParserLib.TYPE_NULL); - assertEq(item.children()[2].value(), "null"); - if (k == 0 || k == 1) { - for (uint256 i; i != 3; ++i) { - assertEq(item.children()[i].parent()._data, item._data); - assertEq(item.children()[i].parent().isArray(), true); - assertEq(item.children()[i].parent().isArray(), true); - assertEq(item.children()[i].index(), i); - assertEq(item.children()[i].key(), ""); - } - } - if (k == 2 || k == 3) { - for (uint256 i; i != 3; ++i) { - assertEq(item.children()[i].parent()._data, item._data); - assertEq(item.children()[i].parent().isObject(), true); - assertEq(item.children()[i].index(), 0); - } - assertEq(item.children()[0].key(), '"A"'); - assertEq(item.children()[1].key(), '"B"'); - assertEq(item.children()[2].key(), '"C"'); - } - } - } - - function testParseObject() public { - string memory s; - JSONParserLib.Item memory item; - - s = '{"b": "B", "_": "x", "hehe": "HEHE", "_": "y", "v": 12345, "_": "z"}'; - item = s.parse(); - - assertEq(item.isObject(), true); - assertEq(item.size(), 6); - - for (uint256 i; i < item.size(); ++i) { - assertEq(item.at(i).isUndefined(), true); - assertEq(item.children()[i].parent()._data, item._data); - } - assertEq(item.at('"_"').value(), '"z"'); - assertEq(item.at('"b"').value(), '"B"'); - assertEq(item.at('"v"').value(), "12345"); - assertEq(item.at('"hehe"').value(), '"HEHE"'); - assertEq(item.at('"m"').value(), ""); - assertEq(item.at('"m"').isUndefined(), true); - } - - function testParseValidObjectDoesNotRevert(string memory key, string memory value) public { - _limitStringLength(key); - _limitStringLength(value); - string memory s = string( - abi.encodePacked( - '{"', LibString.escapeJSON(key), '":"', LibString.escapeJSON(value), '"}' - ) - ); - this.parsedValue(s); - } - - function testParseRecursiveObject() public miniBrutalizeMemory { - string memory s; - JSONParserLib.Item memory item; - - s = '{ "": [1,2, {"m": "M"}, {},[]], "X": {"hehe": "1", "h": [true,false, null], "": 0} }'; - item = s.parse(); - - assertEq(item.isObject(), true); - assertEq(item.children()[0].key(), '""'); - assertEq(item.children()[0].index(), 0); - assertEq(item.children()[0].children()[0].value(), "1"); - assertEq(item.children()[0].children()[1].value(), "2"); - assertEq(item.children()[0].children()[2].value(), '{"m": "M"}'); - assertEq(item.children()[0].children()[2].children()[0].key(), '"m"'); - assertEq(item.children()[0].children()[2].children()[0].value(), '"M"'); - - JSONParserLib.Item memory c = item.children()[0].children()[2].children()[0]; - assertEq(c.parent().parent().parent()._data, item._data); - assertEq(c.parent().parent().parent().value(), item.value()); - assertEq(c.parent().parent().parent().parent().isUndefined(), true); - - assertEq(item.children()[1].key(), '"X"'); - assertEq(item.children()[1].index(), 0); - assertEq(item.children()[1].value(), '{"hehe": "1", "h": [true,false, null], "": 0}'); - assertEq(item.children()[1].children()[0].key(), '"hehe"'); - assertEq(item.children()[1].children()[0].value(), '"1"'); - - assertEq(item.children()[1].children()[1].key(), '"h"'); - assertEq(item.children()[1].children()[1].value(), "[true,false, null]"); - assertEq(item.children()[1].children()[1].children()[0].value(), "true"); - assertEq(item.children()[1].children()[1].children()[0].isBoolean(), true); - assertEq(item.children()[1].children()[1].children()[1].value(), "false"); - assertEq(item.children()[1].children()[1].children()[1].isBoolean(), true); - assertEq(item.children()[1].children()[1].children()[2].value(), "null"); - assertEq(item.children()[1].children()[1].children()[2].isNull(), true); - - assertEq(item.children()[1].children()[2].key(), '""'); - assertEq(item.children()[1].children()[2].value(), "0"); - assertEq(item.children()[1].children()[2].size(), 0); - - s = "[[[[[[[]]]]]]]"; - item = s.parse(); - assertEq(item.isArray(), true); - - s = '{"a":[[[{"z":"Z"}]]]}'; - item = s.parse(); - assertEq(item.isObject(), true); - } - - function testParseString() public { - _checkParseString('""'); - _checkParseString('"a"'); - _checkParseString('"ab"'); - _checkParseString('"012345678901234567890123456789"'); - _checkParseString('"0123456789012345678901234567890"'); - _checkParseString('"01234567890123456789012345678901"'); - _checkParseString('"012345678901234567890123456789012"'); - _checkParseString('"0123456789012345678901234567890123"'); - _checkParseString('" d"'); - _checkParseString('"d "'); - _checkParseString('" d "'); - _checkParseString('"\\""'); - _checkParseString('"\\\\"'); - _checkParseString('"\\/"'); - _checkParseString('"\\b"'); - _checkParseString('"\\f"'); - _checkParseString('"\\n"'); - _checkParseString('"\\r"'); - _checkParseString('"\\t"'); - _checkParseString('" \\u1234 \\"\\"\\\\ \\b\\f \\n\\r "'); - _checkParseString('"\\u1234"'); - _checkParseString('"\\uabcd"'); - _checkParseString('"\\uABCD"'); - _checkParseString('"\\uef00"'); - _checkParseString('"\\u00EF"'); - _checkParseString('"\\u1234 "'); - _checkParseString('"\\uabcd "'); - _checkParseString('"\\uABCD "'); - _checkParseString('"\\uef00 "'); - _checkParseString('"\\u00EF "'); - } - - function _checkParseString(string memory s) internal { - JSONParserLib.Item memory item; - assertEq(this.parsedValue(s), s); - for (uint256 k; k != 4; ++k) { - item = _padWhiteSpace(s, k).parse(); - assertEq(item.value(), s); - assertEq(item.isString(), true); - assertEq(item.value(), s); - _checkItemIsSolo(item); - } - } - - function testParseInvalidStringReverts() public { - _checkParseReverts('"'); - _checkParseReverts('"""'); - _checkParseReverts('""""'); - _checkParseReverts('"""""'); - _checkParseReverts('"abc" "'); - _checkParseReverts('"abc" ""'); - _checkParseReverts('"abc""abc"'); - _checkParseReverts('"\\"'); - _checkParseReverts('"\\\\\\"'); - _checkParseReverts('"\\u"'); - _checkParseReverts('"\\u1"'); - _checkParseReverts('"\\u12"'); - _checkParseReverts('"\\u123"'); - _checkParseReverts('"\\uxxxx"'); - _checkParseReverts('"\\u012g"'); - _checkParseReverts('"\\u1234'); - } - - function _checkItemIsSolo(JSONParserLib.Item memory item) internal { - _checkItemHasNoParent(item); - assertEq(item.size(), 0); - } - - function _checkItemHasNoParent(JSONParserLib.Item memory item) internal { - assertEq(item.parent().isUndefined(), true); - assertEq(item.parent()._data, 0); - assertEq(item.key(), ""); - assertEq(item.index(), 0); - assertEq(item.parent().isObject(), false); - assertEq(item.parent().isArray(), false); - assertEq(item.isUndefined(), false); - } - - function testParseGas() public { - string memory s = - '{"animation_url":"","artist":"Daniel Allan","artwork":{"mimeType":"image/gif","uri":"ar://J5NZ-e2NUcQj1OuuhpTjAKtdW_nqwnwo5FypF_a6dE4","nft":null},"attributes":[{"trait_type":"Criteria","value":"Song Edition"}],"bpm":null,"credits":null,"description":"Criteria is an 8-track project between Daniel Allan and Reo Cragun.\\n\\nA fusion of electronic music and hip-hop - Criteria brings together the best of both worlds and is meant to bring web3 music to a wider audience.\\n\\nThe collection consists of 2500 editions with activations across Sound, Bonfire, OnCyber, Spinamp and Arpeggi.","duration":105,"external_url":"https://www.sound.xyz/danielallan/criteria","genre":"Pop","image":"ar://J5NZ-e2NUcQj1OuuhpTjAKtdW_nqwnwo5FypF_a6dE4","isrc":null,"key":null,"license":null,"locationCreated":null,"losslessAudio":"","lyrics":null,"mimeType":"audio/wave","nftSerialNumber":11,"name":"Criteria #11","originalReleaseDate":null,"project":null,"publisher":null,"recordLabel":null,"tags":null,"title":"Criteria","trackNumber":1,"version":"sound-edition-20220930","visualizer":null}'; - JSONParserLib.Item memory item = s.parse(); - assertEq(item.isObject(), true); - bytes32 expectedHash = 0x6c3276c7005f50c82624fb28f9748f0fb6f0b364234e4823178f964315b41567; - assertEq(keccak256(bytes(item.at('"description"').value())), expectedHash); - } - - function testParseUintFromHex() public { - unchecked { - for (uint256 i; i != 9; ++i) { - _checkParseUintFromHex(LibString.toString(i), i); - } - } - _checkParseUintFromHex("a", 0xa); - _checkParseUintFromHex("f", 0xf); - _checkParseUintFromHex("ff", 0xff); - _checkParseUintFromHex("fff", 0xfff); - _checkParseUintFromHex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", type(uint256).max - ); - _checkParseUintFromHex( - "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef - ); - _checkParseUintFromHex( - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - ); - _checkParseUintFromHex( - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", - 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef - ); - } - - function _checkParseUintFromHex(string memory s, uint256 x) internal { - _checkParseUintFromHexSub(LibString.lower(s), x); - _checkParseUintFromHexSub(LibString.upper(s), x); - } - - function _checkParseUintFromHexSub(string memory s, uint256 x) internal { - assertEq(this.parseUintFromHex(s), x); - assertEq(this.parseUintFromHex(LibString.concat("0x", s)), x); - assertEq(this.parseUintFromHex(LibString.concat("0x0", s)), x); - assertEq(this.parseUintFromHex(LibString.concat("0X00", s)), x); - assertEq(this.parseUintFromHex(LibString.concat("0x000", s)), x); - assertEq(this.parseUintFromHex(LibString.concat("0X", s)), x); - assertEq(this.parseUintFromHex(LibString.concat("0", s)), x); - assertEq(this.parseUintFromHex(LibString.concat("00", s)), x); - assertEq(this.parseUintFromHex(LibString.concat("000", s)), x); - } - - function parseUintFromHex(string memory s) public pure returns (uint256) { - return s.parseUintFromHex(); - } - - function testParseInvalidUintFromHexReverts() public { - _checkParseInvalidUintFromHexReverts(""); - _checkParseInvalidUintFromHexReverts("+"); - _checkParseInvalidUintFromHexReverts(" 0"); - _checkParseInvalidUintFromHexReverts("0 "); - _checkParseInvalidUintFromHexReverts(" 12"); - _checkParseInvalidUintFromHexReverts("00x12"); - _checkParseInvalidUintFromHexReverts(" 0x12"); - _checkParseInvalidUintFromHexReverts("-0x12"); - _checkParseInvalidUintFromHexReverts("0x123g"); - _checkParseInvalidUintFromHexReverts("123g"); - _checkParseInvalidUintFromHexReverts("z"); - _checkParseInvalidUintFromHexReverts( - "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - _checkParseInvalidUintFromHexReverts( - "10000000000000000000000000000000000000000000000000000000000000000" - ); - _checkParseInvalidUintFromHexReverts( - "ff0000000000000000000000000000000000000000000000000000000000000000" - ); - } - - function _checkParseInvalidUintFromHexReverts(string memory s) internal { - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.parseUintFromHex(s); - } - - function testParseUint() public { - assertEq(this.parseUint("0"), 0); - assertEq(this.parseUint("1"), 1); - assertEq(this.parseUint("123"), 123); - assertEq(this.parseUint("0123"), 123); - assertEq(this.parseUint("000123"), 123); - assertEq(this.parseUint("12345678901234567890"), 12345678901234567890); - string memory s; - s = "115792089237316195423570985008687907853269984665640564039457584007913129639935"; - assertEq(this.parseUint(s), type(uint256).max); - } - - function testParseInvalidUintReverts() public { - _checkParseInvalidUintReverts(""); - _checkParseInvalidUintReverts("-"); - _checkParseInvalidUintReverts("a"); - _checkParseInvalidUintReverts(" "); - _checkParseInvalidUintReverts(" 123 "); - _checkParseInvalidUintReverts("123:"); - _checkParseInvalidUintReverts(":"); - string memory s; - s = "115792089237316195423570985008687907853269984665640564039457584007913129639936"; - _checkParseInvalidUintReverts(s); - s = "115792089237316195423570985008687907853269984665640564039457584007913129639937"; - _checkParseInvalidUintReverts(s); - s = "115792089237316195423570985008687907853269984665640564039457584007913129639999"; - _checkParseInvalidUintReverts(s); - s = "115792089237316195423570985008687907853269984665640564039457584007913129640001"; - _checkParseInvalidUintReverts(s); - s = "115792089237316195423570985008687907853269984665640564039457584007913129640035"; - _checkParseInvalidUintReverts(s); - s = "215792089237316195423570985008687907853269984665640564039457584007913129639935"; - _checkParseInvalidUintReverts(s); - s = "222222222222222222222222222222222222222222222222222222222222222222222222222222"; - _checkParseInvalidUintReverts(s); - s = "1215792089237316195423570985008687907853269984665640564039457584007913129639935"; - _checkParseInvalidUintReverts(s); - } - - function _checkParseInvalidUintReverts(string memory s) internal { - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.parseUint(s); - } - - function parseUint(string memory s) public view miniBrutalizeMemory returns (uint256) { - return s.parseUint(); - } - - function testParseInt() public { - _checkParseInt("0", 0); - _checkParseInt("1", 1); - _checkParseInt("+1", 1); - _checkParseInt("+01", 1); - _checkParseInt("+001", 1); - _checkParseInt("+0", 0); - _checkParseInt("+1", 1); - _checkParseInt("+12", 12); - _checkParseInt("-12", -12); - string memory s; - s = "-57896044618658097711785492504343953926634992332820282019728792003956564819967"; - _checkParseInt(s, -type(int256).max); - s = "-57896044618658097711785492504343953926634992332820282019728792003956564819968"; - _checkParseInt(s, type(int256).min); - s = "+57896044618658097711785492504343953926634992332820282019728792003956564819967"; - _checkParseInt(s, type(int256).max); - s = "57896044618658097711785492504343953926634992332820282019728792003956564819967"; - _checkParseInt(s, type(int256).max); - } - - function testParseInt(int256 val) public { - assertEq(this.parseInt(LibString.toString(val)), val); - } - - function testParseIntTrick(uint256 x, bool isNegative) public { - bool expected = !(isNegative ? x <= (1 << 255) : x < (1 << 255)); - bool computed; - /// @solidity memory-safe-assembly - assembly { - computed := iszero(lt(x, add(shl(255, 1), isNegative))) - } - assertEq(computed, expected); - } - - function testParseInvalidIntReverts() public { - _checkParseInvalidIntReverts(""); - _checkParseInvalidIntReverts("-"); - _checkParseInvalidIntReverts("+"); - _checkParseInvalidIntReverts("--"); - _checkParseInvalidIntReverts("++"); - _checkParseInvalidIntReverts("a"); - _checkParseInvalidIntReverts(" "); - _checkParseInvalidIntReverts(" 123 "); - _checkParseInvalidIntReverts("123:"); - _checkParseInvalidIntReverts(":"); - _checkParseInvalidIntReverts(":123"); - string memory s; - s = "-57896044618658097711785492504343953926634992332820282019728792003956564819969"; - _checkParseInvalidIntReverts(s); - s = "+57896044618658097711785492504343953926634992332820282019728792003956564819968"; - _checkParseInvalidIntReverts(s); - } - - function testParseIntReverts(uint256 val) public { - val = _bound(val, uint256(1 << 255) + 1, type(uint256).max); - - string memory s = LibString.toString(val); - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.parseInt(s); - - string memory s1 = LibString.concat("-", s); - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.parseInt(s1); - } - - function _checkParseInt(string memory s, int256 x) internal { - bytes32 hashBefore = keccak256(bytes(s)); - assertEq(this.parseInt(s), x); - assertEq(keccak256(bytes(s)), hashBefore); - } - - function _checkParseInvalidIntReverts(string memory s) internal { - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.parseInt(s); - } - - function parseInt(string memory s) public view miniBrutalizeMemory returns (int256) { - return s.parseInt(); - } - - function testDecodeString() public { - assertEq(this.decodeString('""'), ""); - assertEq(this.decodeString('"abc"'), "abc"); - assertEq(this.decodeString('" abc "'), " abc "); - assertEq(this.decodeString('"\\""'), '"'); - assertEq(this.decodeString('"\\/"'), "/"); - assertEq(this.decodeString('"\\\\"'), "\\"); - assertEq(this.decodeString('"\\b"'), hex"08"); - assertEq(this.decodeString('"\\f"'), hex"0c"); - assertEq(this.decodeString('"\\n"'), "\n"); - assertEq(this.decodeString('"\\r"'), "\r"); - assertEq(this.decodeString('"\\t"'), "\t"); - assertEq(this.decodeString('"\\u0020"'), " "); - bytes32 expectedHash; - expectedHash = 0x40b2b6558413427ef2da03b1452640d701458e0ce57114db6b7423ae3b5fe857; - assertEq(keccak256(bytes(this.decodeString('"\\u039e"'))), expectedHash); // Greek uppercase Xi. - expectedHash = 0xecab436111d5a82d983bd4630c03c83f424d2a2dd8465c31fd950b9ec8d005fb; - assertEq(keccak256(bytes(this.decodeString('"\\u2661"'))), expectedHash); // Heart. - expectedHash = 0x367c272ea502ac6e9f085c1baddc52d0ac0224f1b7d1e8621202620efa3ba084; - assertEq(keccak256(bytes(this.decodeString('"\\uD83D\\ude00"'))), expectedHash); // Smiley emoji. - } - - function testDecodeEncodedStringDoesNotRevert(string memory s) public { - _limitStringLength(s); - s = string(abi.encodePacked('"', LibString.escapeJSON(s), '"')); - this.decodeString(s); - assertEq(this.parsedValue(s), s); - } - - function _limitStringLength(string memory s) internal { - uint256 r = _random(); - /// @solidity memory-safe-assembly - assembly { - let limit := 16 - if eq(1, and(r, 3)) { limit := 80 } - let n := mload(s) - if gt(n, limit) { mstore(s, limit) } - } - } - - function testDecodeInvalidStringReverts() public { - _checkDecodeInvalidStringReverts(""); - _checkDecodeInvalidStringReverts('"'); - _checkDecodeInvalidStringReverts(' "" '); - _checkDecodeInvalidStringReverts(' ""'); - _checkDecodeInvalidStringReverts('"" '); - _checkDecodeInvalidStringReverts('"\\z"'); - _checkDecodeInvalidStringReverts('"\\u"'); - _checkDecodeInvalidStringReverts('"\\u1"'); - _checkDecodeInvalidStringReverts('"\\u111"'); - _checkDecodeInvalidStringReverts('"\\uxxxx"'); - _checkDecodeInvalidStringReverts('"\\uD83D"'); // Only half of a Smiley emoji. - } - - function _checkDecodeInvalidStringReverts(string memory s) internal { - vm.expectRevert(JSONParserLib.ParsingFailed.selector); - this.decodeString(s); - } - - function decodeString(string memory s) - public - view - miniBrutalizeMemory - returns (string memory) - { - return JSONParserLib.decodeString(s); - } - - function testParseUint(uint256 x) public { - string memory s = LibString.toString(x); - assertEq(this.parsedValue(s), s); - assertEq(this.parseUint(s), x); - } - - function testParseJWTGas() public { - string memory jwt = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"; - string[] memory jwtSplitted = LibString.split(jwt, "."); - JSONParserLib.Item memory header = - JSONParserLib.parse(string(Base64.decode(jwtSplitted[0]))); - JSONParserLib.Item memory payload = - JSONParserLib.parse(string(Base64.decode(jwtSplitted[1]))); - assertEq(jwtSplitted.length, 3); - assertEq(jwtSplitted[2], "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"); - assertEq(header.at('"alg"').value(), '"HS256"'); - assertEq(header.at('"typ"').value(), '"JWT"'); - assertEq(payload.at('"sub"').value(), '"1234567890"'); - assertEq(payload.at('"name"').value(), '"John Doe"'); - assertEq(JSONParserLib.parseUint(payload.at('"iat"').value()), 1516239022); - } - - modifier miniBrutalizeMemory() { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, gas()) - mstore(0x00, keccak256(0x00, 0x20)) - mstore(0x20, not(mload(0x00))) - codecopy(mload(0x40), 0, codesize()) - } - _; - } -} diff --git a/grouperBot/lib/solady/test/LibBit.t.sol b/grouperBot/lib/solady/test/LibBit.t.sol deleted file mode 100644 index b3fcd5c..0000000 --- a/grouperBot/lib/solady/test/LibBit.t.sol +++ /dev/null @@ -1,379 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibBit} from "../src/utils/LibBit.sol"; - -contract LibBitTest is SoladyTest { - function testFLS() public { - assertEq(LibBit.fls(0xff << 3), 10); - for (uint256 i = 1; i < 255; i++) { - assertEq(LibBit.fls((1 << i) - 1), i - 1); - assertEq(LibBit.fls((1 << i)), i); - assertEq(LibBit.fls((1 << i) + 1), i); - } - assertEq(LibBit.fls(0), 256); - } - - function testCLZ() public { - for (uint256 i = 1; i < 255; i++) { - assertEq(LibBit.clz((1 << i) - 1), 255 - (i - 1)); - assertEq(LibBit.clz((1 << i)), 255 - i); - assertEq(LibBit.clz((1 << i) + 1), 255 - i); - } - assertEq(LibBit.clz(0), 256); - } - - function testFFS() public { - assertEq(LibBit.ffs(0xff << 3), 3); - uint256 brutalizer = uint256(keccak256(abi.encode(address(this), block.timestamp))); - for (uint256 i = 0; i < 256; i++) { - assertEq(LibBit.ffs(1 << i), i); - assertEq(LibBit.ffs(type(uint256).max << i), i); - assertEq(LibBit.ffs((brutalizer | 1) << i), i); - } - assertEq(LibBit.ffs(0), 256); - } - - function testPopCount(uint256 x) public { - uint256 c; - unchecked { - for (uint256 t = x; t != 0; c++) { - t &= t - 1; - } - } - assertEq(LibBit.popCount(x), c); - } - - function testPopCount() public { - unchecked { - for (uint256 i = 1; i < 256; ++i) { - assertEq(LibBit.popCount((1 << i) | 1), 2); - } - } - } - - function testIsPo2(uint8 a, uint8 b) public { - unchecked { - uint256 x = (1 << uint256(a)) | (1 << uint256(b)); - if (a == b) { - assertTrue(LibBit.isPo2(x)); - } else { - assertFalse(LibBit.isPo2(x)); - } - } - } - - function testIsPo2(uint256 x) public { - uint256 c; - unchecked { - for (uint256 t = x; t != 0; c++) { - t &= t - 1; - } - } - assertEq(LibBit.isPo2(x), c == 1); - } - - function testIsPo2() public { - assertFalse(LibBit.isPo2(0)); - assertFalse(LibBit.isPo2(type(uint256).max)); - unchecked { - for (uint256 i; i < 256; ++i) { - uint256 x = 1 << i; - assertTrue(LibBit.isPo2(x)); - assertFalse(LibBit.isPo2(~x)); - } - } - } - - function testAnd(bool v, bool w, bool x, bool y) public { - assertEq(LibBit.and(x, y), x && y); - assertEq(LibBit.and(w, x, y), w && x && y); - assertEq(LibBit.and(v, w, x, y), v && w && x && y); - assertEq(LibBit.rawAnd(x, y), LibBit.and(x, y)); - } - - function testAnd() public { - unchecked { - for (uint256 t; t != 100; ++t) { - uint256 i = _random(); - uint256 j = _random(); - uint256 k = _random(); - bool a = i < j; - bool b = j < k; - assertEq(LibBit.and(a, b), i < j && j < k); - } - } - } - - function testOr(bool v, bool w, bool x, bool y) public { - assertEq(LibBit.or(x, y), x || y); - assertEq(LibBit.or(w, x, y), w || x || y); - assertEq(LibBit.or(v, w, x, y), v || w || x || y); - assertEq(LibBit.rawOr(x, y), LibBit.or(x, y)); - } - - function testOr() public { - unchecked { - for (uint256 t; t != 100; ++t) { - uint256 i = _random(); - uint256 j = _random(); - uint256 k = _random(); - bool a = i < j; - bool b = j < k; - assertEq(LibBit.or(a, b), i < j || j < k); - } - } - } - - function testAutoClean(uint256 x, uint256 y) public { - bool xCasted; - bool yCasted; - /// @solidity memory-safe-assembly - assembly { - xCasted := x - yCasted := y - } - bool result = LibBit.and(true, LibBit.or(xCasted, yCasted)); - assertEq(result, xCasted || yCasted); - } - - function testReturnsBool() public { - bool result; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x40b98a2f) - mstore(0x20, 123) - pop(staticcall(gas(), address(), 0x1c, 0x24, 0x00, 0x20)) - result := eq(mload(0x00), 1) - } - assertTrue(result); - } - - function returnsBool(uint256 i) public pure returns (bool b) { - /// @solidity memory-safe-assembly - assembly { - b := i - } - } - - function testPassInBool() public { - bool result; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0x59a3028a) - mstore(0x20, 1) - pop(staticcall(gas(), address(), 0x1c, 0x24, 0x00, 0x20)) - result := eq(mload(0x00), 1) - } - assertTrue(result); - } - - function acceptsBool(bool) public pure returns (bool) { - return true; - } - - function testBoolToUint(bool b) public { - uint256 z; - /// @solidity memory-safe-assembly - assembly { - z := b - } - assertEq(LibBit.toUint(b), z); - assertEq(LibBit.rawToUint(b), z); - } - - function testReverseBits() public { - uint256 x = 0xf2e857a5b8e3fec9f9c60ae71ba63813c96741bc837169cf0f29f113ede5956f; - uint256 r = 0xf6a9a7b7c88f94f0f3968ec13d82e693c81c65d8e750639f937fc71da5ea174f; - assertEq(LibBit.reverseBits(x), r); - unchecked { - for (uint256 i; i < 256; ++i) { - assertEq(LibBit.reverseBits(1 << i), (1 << 255) >> i); - } - } - } - - function testReverseBitsDifferential(uint256 x) public { - assertEq(LibBit.reverseBits(x), _reverseBitsOriginal(x)); - } - - function _reverseBitsOriginal(uint256 x) internal pure returns (uint256 r) { - unchecked { - for (uint256 i; i != 256; ++i) { - r = (r << 1) | ((x >> i) & 1); - } - } - } - - function testReverseBytes() public { - uint256 x = 0x112233445566778899aa112233445566778899aa112233445566778899aa1122; - uint256 r = 0x2211aa998877665544332211aa998877665544332211aa998877665544332211; - assertEq(LibBit.reverseBytes(x), r); - unchecked { - for (uint256 i; i < 256; i += 8) { - assertEq(LibBit.reverseBytes(0xff << i), (0xff << 248) >> i); - } - } - } - - function testReverseBytesDifferential(uint256 x) public { - assertEq(LibBit.reverseBytes(x), _reverseBytesOriginal(x)); - } - - function _reverseBytesOriginal(uint256 x) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - for { let i := 0 } lt(i, 32) { i := add(i, 1) } { mstore8(i, byte(sub(31, i), x)) } - r := mload(0x00) - } - } - - function testCommonNibblePrefix() public { - assertEq(LibBit.commonNibblePrefix(0x1, 0x2), 0); - assertEq(LibBit.commonNibblePrefix(0x1234abc, 0x1234bbb), 0x1234000); - assertEq(LibBit.commonNibblePrefix(0x1234abc, 0x1234abc), 0x1234abc); - } - - function testCommonNibblePrefixDifferential(uint256 x, uint256 y) public { - assertEq(LibBit.commonNibblePrefix(x, y), _commonNibblePrefixOriginal(x, y)); - } - - function _commonNibblePrefixOriginal(uint256 x, uint256 y) internal pure returns (uint256 z) { - uint256 m = 0xf000000000000000000000000000000000000000000000000000000000000000; - while (m != 0) { - if ((x & m) == (y & m)) z |= x & m; - else break; - m >>= 4; - } - } - - function testCommonBytePrefix() public { - assertEq(LibBit.commonBytePrefix(0xaabbcc, 0xaabbcc), 0xaabbcc); - assertEq(LibBit.commonBytePrefix(0xaabbcc, 0xaabbc0), 0xaabb00); - assertEq(LibBit.commonBytePrefix(0xaabbcc, 0xaab0c0), 0xaa0000); - assertEq(LibBit.commonBytePrefix(0xaabbcc, 0xa0b0c0), 0x000000); - } - - function testCommonBytePrefixDifferential(uint256 x, uint256 y) public { - assertEq(LibBit.commonBytePrefix(x, y), _commonBytePrefixOriginal(x, y)); - } - - function _commonBytePrefixOriginal(uint256 x, uint256 y) internal pure returns (uint256 z) { - uint256 m = 0xff00000000000000000000000000000000000000000000000000000000000000; - while (m != 0) { - if ((x & m) == (y & m)) z |= x & m; - else break; - m >>= 8; - } - } - - function testCommonBitPrefixDifferential(uint256 x, uint256 y) public { - assertEq(LibBit.commonBitPrefix(x, y), _commonBitPrefixOriginal(x, y)); - } - - function _commonBitPrefixOriginal(uint256 x, uint256 y) internal pure returns (uint256 z) { - uint256 m = 0x8000000000000000000000000000000000000000000000000000000000000000; - while (m != 0) { - if ((x & m) == (y & m)) z |= x & m; - else break; - m >>= 1; - } - } - - function testCountZeroBytesDifferential(uint256 x) public { - assertEq(LibBit.countZeroBytes(x), _countZeroBytesOriginal(x)); - } - - function testCountZeroBytes() public { - uint256 x = 0xff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff; - x |= uint256(uint160(address(this))) << 16; - assertEq(LibBit.countZeroBytes(x), 2); - } - - function _countZeroBytesOriginal(uint256 x) internal pure returns (uint256 c) { - unchecked { - for (uint256 i; i < 32; ++i) { - c += (x & (0xff << (i * 8))) == 0 ? 1 : 0; - } - return c; - } - } - - function testCountZeroBytesDifferential(bytes32) public { - testCountZeroBytesDifferential(_randomSmallBytes()); - } - - function testCountZeroBytesDifferential(bytes memory s) public { - assertEq(LibBit.countZeroBytes(s), _countZeroBytesOriginal(s)); - } - - function testCountZeroBytesCalldataDifferential(bytes32) public { - this.testCountZeroBytesCalldataDifferential(_randomSmallBytes()); - } - - function testCountZeroBytesCalldataDifferential(bytes calldata s) public { - assertEq(LibBit.countZeroBytesCalldata(s), _countZeroBytesOriginal(s)); - } - - function _countZeroBytesOriginal(bytes memory s) internal pure returns (uint256 c) { - unchecked { - for (uint256 i; i < s.length; ++i) { - c += uint8(s[i]) == 0 ? 1 : 0; - } - return c; - } - } - - function _randomSmallBytes() internal returns (bytes memory) { - uint256 n = _bound(_random(), 0, 100); - uint256 r = _randomUniform(); - uint256 x = r >> 248; - bytes memory s = new bytes(n); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - if and(1, shr(i, r)) { mstore8(add(add(s, 0x20), i), x) } - } - } - return s; - } - - function testToNibblesGas() public { - bytes memory s = hex"123456789abcdef123456789abcdef123456789abcdef123456789abcdef"; - bytes memory expected = - hex"0102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0f"; - assertEq(LibBit.toNibbles(s), expected); - } - - function testToNibblesDifferential(uint256 r, bytes memory s) public { - if (r & 0x01 == 0) { - _brutalizeMemory(); - _misalignFreeMemoryPointer(); - } - bytes memory computed = LibBit.toNibbles(s); - _checkMemory(computed); - assertEq(computed, _toNibblesOriginal(s)); - } - - // Original code from Optimism (MIT-licensed): https://github.com/ethereum-optimism/optimism/blob/1bfc93f7c1fe1846217795a1f6051e1b0260f597/packages/contracts-bedrock/src/libraries/Bytes.sol#L94 - function _toNibblesOriginal(bytes memory input) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let bytesLength := mload(input) - let nibblesLength := shl(0x01, bytesLength) - mstore(0x40, add(result, and(not(0x1f), add(nibblesLength, 0x3f)))) - mstore(result, nibblesLength) - let bytesStart := add(input, 0x20) - let nibblesStart := add(result, 0x20) - for { let i := 0x00 } lt(i, bytesLength) { i := add(i, 0x01) } { - let offset := add(nibblesStart, shl(0x01, i)) - let b := byte(0x00, mload(add(bytesStart, i))) - mstore8(offset, shr(0x04, b)) - mstore8(add(offset, 0x01), and(b, 0x0F)) - } - } - } -} diff --git a/grouperBot/lib/solady/test/LibBitmap.t.sol b/grouperBot/lib/solady/test/LibBitmap.t.sol deleted file mode 100644 index dcbeee6..0000000 --- a/grouperBot/lib/solady/test/LibBitmap.t.sol +++ /dev/null @@ -1,414 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibBitmap} from "../src/utils/LibBitmap.sol"; -import {LibBit} from "../src/utils/LibBit.sol"; - -contract LibBitmapTest is SoladyTest { - using LibBitmap for LibBitmap.Bitmap; - - error AlreadyClaimed(); - - LibBitmap.Bitmap bitmap; - - function get(uint256 index) public view returns (bool result) { - result = bitmap.get(index); - } - - function set(uint256 index) public { - bitmap.set(index); - } - - function unset(uint256 index) public { - bitmap.unset(index); - } - - function toggle(uint256 index) public { - bitmap.toggle(index); - } - - function setTo(uint256 index, bool shouldSet) public { - bitmap.setTo(index, shouldSet); - } - - function claimWithGetSet(uint256 index) public { - if (bitmap.get(index)) { - revert AlreadyClaimed(); - } - bitmap.set(index); - } - - function claimWithToggle(uint256 index) public { - if (bitmap.toggle(index) == false) { - revert AlreadyClaimed(); - } - } - - function testBitmapGet() public { - testBitmapGet(111111); - } - - function testBitmapGet(uint256 index) public { - assertFalse(get(index)); - } - - function testBitmapSetAndGet(uint256 index) public { - set(index); - bool result = get(index); - bool resultIsOne; - /// @solidity memory-safe-assembly - assembly { - resultIsOne := eq(result, 1) - } - assertTrue(result); - assertTrue(resultIsOne); - } - - function testBitmapSet() public { - testBitmapSet(222222); - } - - function testBitmapSet(uint256 index) public { - set(index); - assertTrue(get(index)); - } - - function testBitmapUnset() public { - testBitmapSet(333333); - } - - function testBitmapUnset(uint256 index) public { - set(index); - assertTrue(get(index)); - unset(index); - assertFalse(get(index)); - } - - function testBitmapSetTo() public { - testBitmapSetTo(555555, true, 0); - testBitmapSetTo(555555, false, 0); - } - - function testBitmapSetTo(uint256 index, bool shouldSet, uint256 randomness) public { - bool shouldSetBrutalized; - /// @solidity memory-safe-assembly - assembly { - if shouldSet { shouldSetBrutalized := or(iszero(randomness), randomness) } - } - setTo(index, shouldSetBrutalized); - assertEq(get(index), shouldSet); - } - - function testBitmapSetTo(uint256 index, uint256 randomness) public { - randomness = _random(); - unchecked { - for (uint256 i; i < 5; ++i) { - bool shouldSet; - /// @solidity memory-safe-assembly - assembly { - shouldSet := and(shr(i, randomness), 1) - } - testBitmapSetTo(index, shouldSet, _random()); - } - } - } - - function testBitmapToggle() public { - testBitmapToggle(777777, true); - testBitmapToggle(777777, false); - } - - function testBitmapToggle(uint256 index, bool initialValue) public { - setTo(index, initialValue); - assertEq(get(index), initialValue); - toggle(index); - assertEq(get(index), !initialValue); - } - - function testBitmapClaimWithGetSet() public { - uint256 index = 888888; - this.claimWithGetSet(index); - vm.expectRevert(AlreadyClaimed.selector); - this.claimWithGetSet(index); - } - - function testBitmapClaimWithToggle() public { - uint256 index = 999999; - this.claimWithToggle(index); - vm.expectRevert(AlreadyClaimed.selector); - this.claimWithToggle(index); - } - - function testBitmapSetBatchWithinSingleBucket() public { - _testBitmapSetBatch(257, 30); - } - - function testBitmapSetBatchAcrossMultipleBuckets() public { - _testBitmapSetBatch(10, 512); - } - - function testBitmapSetBatch() public { - unchecked { - for (uint256 i; i < 8; ++i) { - uint256 start = _random(); - uint256 amount = _random(); - _testBitmapSetBatch(start, amount); - } - } - } - - function testBitmapUnsetBatchWithinSingleBucket() public { - _testBitmapUnsetBatch(257, 30); - } - - function testBitmapUnsetBatchAcrossMultipleBuckets() public { - _testBitmapUnsetBatch(10, 512); - } - - function testBitmapUnsetBatch() public { - unchecked { - for (uint256 i; i < 8; ++i) { - uint256 start = _random(); - uint256 amount = _random(); - _testBitmapUnsetBatch(start, amount); - } - } - } - - function testBitmapPopCountWithinSingleBucket() public { - _testBitmapPopCount(1, 150); - } - - function testBitmapPopCountAcrossMultipleBuckets() public { - _testBitmapPopCount(10, 512); - } - - function testBitmapPopCount(uint256, uint256 start, uint256 amount) public { - unchecked { - uint256 n = 1000; - uint256 expectedCount; - _resetBitmap(0, n / 256 + 1); - - (start, amount) = _boundStartAndAmount(start, amount, n); - - uint256 jPrev = 0xff + 1; - uint256 j = _random() & 0xff; - while (true) { - bitmap.set(j); - if (j != jPrev && start <= j && j < start + amount) { - expectedCount += 1; - } - if (start + amount <= j && _random() & 7 == 0) break; - jPrev = j; - j += _random() & 0xff; - } - assertEq(bitmap.popCount(start, amount), expectedCount); - } - } - - function testBitmapPopCount() public { - unchecked { - for (uint256 i; i < 8; ++i) { - uint256 start = _random(); - uint256 amount = _random(); - testBitmapPopCount(start, amount, _random()); - } - } - } - - function testBitmapFindFirstUnset() public { - assertEq(bitmap.findFirstUnset(0, 1000), 0); - assertEq(bitmap.findFirstUnset(1, 1000), 1); - assertEq(bitmap.findFirstUnset(255, 1000), 255); - assertEq(bitmap.findFirstUnset(256, 1000), 256); - bitmap.set(0); - assertEq(bitmap.findFirstUnset(0, 1000), 1); - bitmap.map[0] = type(uint256).max; - assertEq(bitmap.findFirstUnset(0, 1000), 256); - bitmap.set(256); - assertEq(bitmap.findFirstUnset(0, 1000), 257); - assertEq(bitmap.findFirstUnset(0, 255), LibBitmap.NOT_FOUND); - assertEq(bitmap.findFirstUnset(0, 256), LibBitmap.NOT_FOUND); - assertEq(bitmap.findFirstUnset(0, 257), 257); - assertEq(bitmap.findFirstUnset(10, 9), LibBitmap.NOT_FOUND); - assertEq(bitmap.findFirstUnset(1000, 9), LibBitmap.NOT_FOUND); - } - - function testBitmapFindFirstUnset(uint256 begin, uint256 upTo, bytes32) public { - unchecked { - for (uint256 i; i != 5; ++i) { - bitmap.map[i] = type(uint256).max; - } - } - - do { - begin = _bound(_random(), 0, 1000); - upTo = _bound(_random(), 0, 1000); - } while (begin > upTo); - - uint256 expected = _bound(_random(), 0, 1000); - bitmap.unset(expected); - assertEq( - bitmap.findFirstUnset(begin, upTo), - expected < begin || expected > upTo ? LibBitmap.NOT_FOUND : expected - ); - - while (_randomChance(4)) { - uint256 nextExpected = _bound(_random(), 0, 1000); - bitmap.unset(nextExpected); - if (nextExpected < expected) expected = nextExpected; - assertEq(bitmap.findFirstUnset(0, 1000), expected); - } - - if (_randomChance(8)) { - do { - begin = _bound(_random(), 0, 1000); - upTo = _bound(_random(), 0, 1000); - } while (begin <= upTo); - - assertEq(bitmap.findFirstUnset(begin, upTo), LibBitmap.NOT_FOUND); - } - } - - function testBitmapFindLastSet() public { - unchecked { - bitmap.unsetBatch(0, 2000); - bitmap.set(1000); - for (uint256 i = 0; i < 1000; ++i) { - assertEq(bitmap.findLastSet(i), LibBitmap.NOT_FOUND); - } - bitmap.set(100); - bitmap.set(10); - for (uint256 i = 0; i < 10; ++i) { - assertEq(bitmap.findLastSet(i), LibBitmap.NOT_FOUND); - } - for (uint256 i = 10; i < 100; ++i) { - assertEq(bitmap.findLastSet(i), 10); - } - for (uint256 i = 100; i < 600; ++i) { - assertEq(bitmap.findLastSet(i), 100); - } - for (uint256 i = 1000; i < 1100; ++i) { - assertEq(bitmap.findLastSet(i), 1000); - } - bitmap.set(0); - for (uint256 i = 0; i < 10; ++i) { - assertEq(bitmap.findLastSet(i), 0); - } - } - } - - function testBitmapFindLastSet2() public { - unchecked { - assertEq(bitmap.findLastSet(100), LibBitmap.NOT_FOUND); - bitmap.set(0); - assertEq(bitmap.findLastSet(100), 0); - assertEq(bitmap.findLastSet(0), 0); - } - } - - function testBitmapFindLastSet(uint256 upTo, bytes32) public { - uint256 n = 1000; - uint256 randomness; - unchecked { - _resetBitmap(0, n / 256 + 1); - upTo = upTo % n; - randomness = _random() % n; - } - bitmap.set(randomness); - if (randomness <= upTo) { - assertEq(bitmap.findLastSet(upTo), randomness); - uint256 nextLcg = _random(); - bitmap.set(nextLcg); - if (nextLcg <= upTo) { - assertEq(bitmap.findLastSet(upTo), (randomness < nextLcg ? nextLcg : randomness)); - } - } else { - assertEq(bitmap.findLastSet(upTo), LibBitmap.NOT_FOUND); - uint256 nextLcg = _random(); - bitmap.set(nextLcg); - if (nextLcg <= upTo) { - assertEq(bitmap.findLastSet(upTo), nextLcg); - } else { - assertEq(bitmap.findLastSet(upTo), LibBitmap.NOT_FOUND); - } - } - } - - function _testBitmapSetBatch(uint256 start, uint256 amount) internal { - uint256 n = 1000; - (start, amount) = _boundStartAndAmount(start, amount, n); - - unchecked { - _resetBitmap(0, n / 256 + 1); - bitmap.setBatch(start, amount); - for (uint256 i; i < n; ++i) { - if (i < start) { - assertFalse(bitmap.get(i)); - } else if (i < start + amount) { - assertTrue(bitmap.get(i)); - } else { - assertFalse(bitmap.get(i)); - } - } - } - } - - function _testBitmapUnsetBatch(uint256 start, uint256 amount) internal { - uint256 n = 1000; - (start, amount) = _boundStartAndAmount(start, amount, n); - - unchecked { - _resetBitmap(type(uint256).max, n / 256 + 1); - bitmap.unsetBatch(start, amount); - for (uint256 i; i < n; ++i) { - if (i < start) { - assertTrue(bitmap.get(i)); - } else if (i < start + amount) { - assertFalse(bitmap.get(i)); - } else { - assertTrue(bitmap.get(i)); - } - } - } - } - - function _testBitmapPopCount(uint256 start, uint256 amount) internal { - uint256 n = 1000; - (start, amount) = _boundStartAndAmount(start, amount, n); - - unchecked { - _resetBitmap(0, n / 256 + 1); - bitmap.setBatch(start, amount); - assertEq(bitmap.popCount(0, n), amount); - if (start > 0) { - assertEq(bitmap.popCount(0, start - 1), 0); - } - if (start + amount < n) { - assertEq(bitmap.popCount(start + amount, n - (start + amount)), 0); - } - } - } - - function _boundStartAndAmount(uint256 start, uint256 amount, uint256 n) - private - pure - returns (uint256 boundedStart, uint256 boundedAmount) - { - unchecked { - boundedStart = start % n; - uint256 end = boundedStart + (amount % n); - if (end > n) end = n; - boundedAmount = end - boundedStart; - } - } - - function _resetBitmap(uint256 bucketValue, uint256 bucketEnd) private { - unchecked { - for (uint256 i; i < bucketEnd; ++i) { - bitmap.map[i] = bucketValue; - } - } - } -} diff --git a/grouperBot/lib/solady/test/LibBytes.t.sol b/grouperBot/lib/solady/test/LibBytes.t.sol deleted file mode 100644 index a1285f8..0000000 --- a/grouperBot/lib/solady/test/LibBytes.t.sol +++ /dev/null @@ -1,420 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibBytes} from "../src/utils/LibBytes.sol"; - -contract LibBytesTest is SoladyTest { - function testLoad(bytes memory a) public { - if (a.length < 32) a = abi.encodePacked(a, new bytes(32)); - uint256 o = _bound(_random(), 0, a.length - 32); - bytes memory expected = LibBytes.slice(a, o, o + 32); - assertEq(abi.encode(LibBytes.load(a, o)), expected); - this._testLoadCalldata(a); - } - - function _testLoadCalldata(bytes calldata a) public { - uint256 o = _bound(_random(), 0, a.length - 32); - bytes memory expected = LibBytes.slice(a, o, o + 32); - assertEq(abi.encode(LibBytes.loadCalldata(a, o)), expected); - } - - function testTruncate(bytes memory a, uint256 n) public { - bytes memory sliced = LibBytes.slice(a, 0, n); - bytes memory truncated = LibBytes.truncate(a, n); - assertEq(truncated, sliced); - assertEq(a, sliced); - } - - function testTruncatedCalldata(bytes calldata a, uint256 n) public { - bytes memory sliced = LibBytes.slice(a, 0, n); - bytes memory truncated = LibBytes.truncatedCalldata(a, n); - assertEq(truncated, sliced); - } - - function testSliceCalldata(bytes calldata a, uint256 start, uint256 end) public { - bytes memory aCopy = a; - assertEq(LibBytes.sliceCalldata(a, start, end), LibBytes.slice(aCopy, start, end)); - assertEq(LibBytes.sliceCalldata(a, start), LibBytes.slice(aCopy, start)); - } - - function testSliceCalldata() public { - bytes memory data = hex"12f712c77281c66267d947165237893ba5eca3e5481727fe76d4511ce1b564f5"; - this.testSliceCalldata(data, 1, 11); - } - - function testEmptyCalldata() public { - assertEq(LibBytes.emptyCalldata(), ""); - } - - function testDirectReturn() public { - uint256 seed = 123; - bytes[] memory expected = _generateBytesArray(seed); - bytes[] memory computed = this.generateBytesArray(seed, false); - unchecked { - for (uint256 i; i != expected.length; ++i) { - _checkMemory(computed[i]); - assertEq(computed[i], expected[i]); - } - assertEq(computed.length, expected.length); - } - } - - function testDirectReturn(uint256 seed) public { - bytes[] memory expected = _generateBytesArray(seed); - (bool success, bytes memory encoded) = address(this).call( - abi.encodeWithSignature("generateBytesArray(uint256,bool)", seed, true) - ); - assertTrue(success); - bytes[] memory computed; - /// @solidity memory-safe-assembly - assembly { - let o := add(encoded, 0x20) - computed := add(o, mload(o)) - for { let i := 0 } lt(i, mload(computed)) { i := add(i, 1) } { - let c := add(add(0x20, computed), shl(5, i)) - mstore(c, add(add(0x20, computed), mload(c))) - } - } - unchecked { - for (uint256 i; i != expected.length; ++i) { - _checkMemory(computed[i]); - assertEq(computed[i], expected[i]); - } - assertEq(computed.length, expected.length); - } - if (seed & 0xf == 0) { - assertEq(abi.encode(expected), abi.encode(this.generateBytesArray(seed, true))); - } - } - - function generateBytesArray(uint256 seed, bool brutalized) - public - view - returns (bytes[] memory) - { - if (brutalized) { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - LibBytes.directReturn(_generateBytesArray(seed)); - } - - function _generateBytesArray(uint256 seed) internal pure returns (bytes[] memory a) { - bytes memory before = "hehe"; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, seed) - mstore(0x20, 0) - function _next() -> _r { - _r := keccak256(0x00, 0x40) - mstore(0x20, _r) - } - function _nextBytes() -> _b { - _b := mload(0x40) - let n_ := and(_next(), 0x7f) - mstore(_b, n_) - for { let i_ := 0 } lt(i_, n_) { i_ := add(i_, 0x20) } { - mstore(add(add(_b, 0x20), i_), _next()) - } - if and(1, _next()) { - mstore(0x40, add(n_, add(_b, 0x20))) - leave - } - mstore(add(n_, add(_b, 0x20)), 0) - mstore(0x40, add(n_, add(_b, 0x40))) - } - let n := and(_next(), 7) - a := mload(0x40) - mstore(a, n) - mstore(0x40, add(add(a, 0x20), shl(5, n))) - for { let i := 0 } lt(i, n) { i := add(1, i) } { - if iszero(and(7, _next())) { - mstore(add(add(a, 0x20), shl(5, i)), before) - continue - } - mstore(add(add(a, 0x20), shl(5, i)), _nextBytes()) - } - } - } - - function testCmp() public { - assertEq(LibBytes.cmp("", ""), 0); - assertEq(LibBytes.cmp("abc", "abc"), 0); - assertEq(LibBytes.cmp("abcd", "abc"), 1); - assertEq(LibBytes.cmp("abb", "abc"), -1); - assertEq( - LibBytes.cmp( - "0123456789012345678901234567890123456789abb", - "0123456789012345678901234567890123456789abc" - ), - -1 - ); - } - - function testCmpDifferential(bytes memory a, bytes memory b) public { - if (_randomChance(32)) { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - if (_randomChance(256)) { - a = b; - } - if (_randomChance(16)) { - a = abi.encodePacked(a, b); - } - if (_randomChance(16)) { - b = abi.encodePacked(b, a); - } - bytes32 aHash = keccak256(a); - bytes32 bHash = keccak256(b); - if (_randomChance(8)) { - a = _brutalizeRightPadding(a); - } - if (_randomChance(8)) { - b = _brutalizeRightPadding(b); - } - int256 computed = LibBytes.cmp(a, b); - int256 expected = cmpOriginal(a, b); - assertEq(computed, expected); - assertEq(keccak256(a), aHash); - assertEq(keccak256(b), bHash); - } - - struct SampleDynamicStruct { - address target; - uint256 value; - bytes data; - } - - struct SampleStaticSubStruct { - uint256 x; - uint256 y; - } - - struct SampleStaticStruct { - SampleStaticSubStruct a; - SampleStaticSubStruct b; - } - - function testStaticStructInCalldata() public { - SampleStaticStruct memory s; - s.a.x = 1; - s.a.y = 2; - s.b.x = 3; - s.b.y = 4; - - SampleDynamicStruct memory u; - u.target = address(0xaaa); - u.value = 123; - u.data = "hehe"; - - this._testStaticStructInCalldata(abi.encode(s, u), 0x20 * 0, s); - this._testStaticStructInCalldata(abi.encode(u, s, u), 0x20 * 1, s); - this._testStaticStructInCalldata(abi.encode(u, u, s, u, s), 0x20 * 2, s); - this._testStaticStructInCalldata(abi.encode(u, u, s, u, s), 0x20 * 2 + 0x20 * 4 + 0x20, s); - } - - function _testStaticStructInCalldata( - bytes calldata encoded, - uint256 offset, - SampleStaticStruct memory expected - ) public { - bytes calldata p = LibBytes.staticStructInCalldata(encoded, offset); - assertEq(uint256(LibBytes.loadCalldata(p, 0x00)), expected.a.x); - assertEq(uint256(LibBytes.loadCalldata(p, 0x20)), expected.a.y); - assertEq(uint256(LibBytes.loadCalldata(p, 0x40)), expected.b.x); - assertEq(uint256(LibBytes.loadCalldata(p, 0x60)), expected.b.y); - } - - function testDynamicStructInCalldata() public { - SampleDynamicStruct memory u; - u.target = address(1); - u.value = 123; - u.data = "hehe"; - bytes memory encoded = abi.encode(u); - this._testDynamicStructInCalldata(encoded, 0x00, u); - } - - function testDynamicStructInCalldata2() public { - SampleDynamicStruct memory u; - u.target = address(1); - u.value = 123; - u.data = "hehe"; - - SampleStaticStruct memory s; - s.a.x = _random(); - s.a.y = _random(); - s.b.x = _random(); - s.b.y = _random(); - this._testDynamicStructInCalldata(abi.encode(s, u), 0x80, u); - this._testDynamicStructInCalldata(abi.encode(s, u, s), 0x80, u); - this._testDynamicStructInCalldata(abi.encode(s, s, u), 0x80 * 2, u); - } - - function testDynamicStructInCalldata(bytes32) public { - SampleDynamicStruct memory u; - u.target = _randomHashedAddress(); - u.value = _randomUniform(); - u.data = _truncateBytes(_randomBytes(), 100); - bytes memory encoded; - encoded = abi.encode(u); - this._testDynamicStructInCalldata(encoded, 0x00, u); - encoded = abi.encode(uint256(1), u); - this._testDynamicStructInCalldata(encoded, 0x20, u); - encoded = abi.encode(uint256(1), uint256(2), u); - if (_randomChance(32)) encoded = abi.encodePacked(encoded, _randomBytes()); - this._testDynamicStructInCalldata(encoded, 0x40, u); - } - - function _testDynamicStructInCalldata( - bytes calldata encoded, - uint256 offset, - SampleDynamicStruct memory expected - ) public { - bytes calldata p = LibBytes.dynamicStructInCalldata(encoded, offset); - assertEq(uint256(LibBytes.loadCalldata(p, 0x00)), uint160(expected.target)); - assertEq(uint256(LibBytes.loadCalldata(p, 0x20)), expected.value); - assertEq(LibBytes.bytesInCalldata(p, 0x40), expected.data); - } - - function testBytesInCalldata() public { - this._testBytesInCalldata(abi.encode("hello"), 0x00, "hello"); - } - - function testBytesInCalldata(bytes32) public { - bytes memory u = _truncateBytes(_randomBytes(), 100); - this._testBytesInCalldata(abi.encode(u), 0x00, u); - this._testBytesInCalldata(abi.encode(uint256(1), u), 0x20, u); - if (_randomChance(16)) { - bytes memory encoded = abi.encode(uint256(1), uint256(2), u); - if (_randomChance(32)) encoded = abi.encodePacked(encoded, _randomBytes()); - this._testBytesInCalldata(encoded, 0x40, u); - } - } - - function _testBytesInCalldata(bytes calldata encoded, uint256 offset, bytes memory expected) - public - { - assertEq(LibBytes.bytesInCalldata(encoded, offset), expected); - } - - function _brutalizeRightPadding(bytes memory s) internal returns (bytes memory result) { - uint256 n = s.length; - result = abi.encodePacked(s, _randomUniform(), _randomUniform()); - /// @solidity memory-safe-assembly - assembly { - mstore(result, n) - } - } - - function cmpOriginal(bytes memory a, bytes memory b) internal pure returns (int256) { - uint256 minLen = a.length < b.length ? a.length : b.length; - for (uint256 i; i < minLen; ++i) { - uint8 x = uint8(a[i]); - uint8 y = uint8(b[i]); - if (x < y) return -1; - if (x > y) return 1; - } - if (a.length < b.length) return -1; - if (a.length > b.length) return 1; - return 0; - } - - function testIndexOfByteDifferential(bytes memory subject, bytes1 needle, uint256 from) - public - { - if (_randomChance(2)) _brutalizeMemory(); - if (_randomChance(2)) _misalignFreeMemoryPointer(); - if (_randomChance(2)) { - bytes memory empty; - subject = empty; - } - from = _bound(from, 0, subject.length * 2); - uint256 computed = LibBytes.indexOfByte(subject, needle, from); - uint256 expected = _indexOfByteOriginal(subject, needle, from); - assertEq(computed, expected); - } - - function testIndexOfByte() public { - bytes memory subject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - assertEq(LibBytes.indexOfByte("", "a"), LibBytes.NOT_FOUND); - assertEq(LibBytes.indexOfByte("", "a", 1), LibBytes.NOT_FOUND); - assertEq(LibBytes.indexOfByte(subject, "a"), 0); - assertEq(LibBytes.indexOfByte(subject, "a", 1), LibBytes.NOT_FOUND); - assertEq(LibBytes.indexOfByte(subject, "b"), 1); - assertEq(LibBytes.indexOfByte(subject, "X"), 49); - assertEq(LibBytes.indexOfByte(subject, "q"), 16); - assertEq(LibBytes.indexOfByte(subject, "q", 16), 16); - assertEq(LibBytes.indexOfByte(subject, "q", 17), LibBytes.NOT_FOUND); - assertEq(LibBytes.indexOfByte(subject, "q", 17), LibBytes.NOT_FOUND); - assertEq(LibBytes.indexOfByte("abcabcabc", "a", 0), 0); - assertEq(LibBytes.indexOfByte("abcabcabc", "a", 1), 3); - } - - function _indexOfByteOriginal(bytes memory subject, bytes1 needle, uint256 from) - internal - pure - returns (uint256) - { - unchecked { - for (uint256 i; i < subject.length; ++i) { - if (i >= from) { - if (subject[i] == needle) return i; - } - } - return type(uint256).max; - } - } - - function testBytes32ToAddress(bytes32 x) public { - uint256 msb = uint256(x) >> 96; - uint256 lsb = (uint256(x) << 96) >> 96; - assertEq(uint160(LibBytes.msbToAddress(x)), msb); - assertEq(uint160(LibBytes.lsbToAddress(x)), lsb); - } - - function testCheckInCalldata(bytes memory child) public view { - this.checkInCalldata(child, abi.encode(child)); - } - - function testCheckInCalldata() public pure { - LibBytes.checkInCalldata(msg.data, msg.data); - } - - function checkInCalldata(bytes calldata expectedChild, bytes calldata encoded) public pure { - bytes calldata child; - /// @solidity memory-safe-assembly - assembly { - child.offset := add(0x20, add(encoded.offset, calldataload(encoded.offset))) - child.length := calldataload(add(encoded.offset, calldataload(encoded.offset))) - } - LibBytes.checkInCalldata(child, encoded); - LibBytes.checkInCalldata(child, msg.data); - LibBytes.checkInCalldata(encoded, msg.data); - require(keccak256(expectedChild) == keccak256(child)); - } - - function testCheckInCalldata(bytes[] memory children) public view { - this.checkInCalldata(children, abi.encode(children)); - } - - function checkInCalldata(bytes[] calldata expectedChildren, bytes calldata encoded) - public - pure - { - bytes[] calldata children; - /// @solidity memory-safe-assembly - assembly { - children.offset := add(0x20, add(encoded.offset, calldataload(encoded.offset))) - children.length := calldataload(add(encoded.offset, calldataload(encoded.offset))) - } - LibBytes.checkInCalldata(children, encoded); - LibBytes.checkInCalldata(expectedChildren, msg.data); - LibBytes.checkInCalldata(children, msg.data); - require(expectedChildren.length == children.length); - for (uint256 i; i < children.length; ++i) { - require(keccak256(expectedChildren[i]) == keccak256(children[i])); - } - } -} diff --git a/grouperBot/lib/solady/test/LibCWIA.t.sol b/grouperBot/lib/solady/test/LibCWIA.t.sol deleted file mode 100644 index ef585a8..0000000 --- a/grouperBot/lib/solady/test/LibCWIA.t.sol +++ /dev/null @@ -1,314 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibCWIA} from "../src/utils/legacy/LibCWIA.sol"; -import {CWIA} from "../src/utils/legacy/CWIA.sol"; -import {SafeTransferLib} from "../src/utils/SafeTransferLib.sol"; - -contract LibCWIATest is SoladyTest, CWIA { - error CustomError(uint256 currentValue); - - event ReceiveETH(uint256 amount); - - uint256 public value; - - mapping(bytes32 => bool) saltIsUsed; - - function setValue(uint256 value_) public { - value = value_; - } - - function revertWithError() public view { - revert CustomError(value); - } - - function getCalldataHash() public pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - let extraLength := shr(0xf0, calldataload(sub(calldatasize(), 2))) - if iszero(lt(extraLength, 2)) { - let offset := sub(calldatasize(), extraLength) - let m := mload(0x40) - calldatacopy(m, offset, sub(extraLength, 2)) - result := keccak256(m, sub(extraLength, 2)) - } - } - } - - function _canReceiveETHCorrectly(address clone, uint256 deposit) internal { - deposit = deposit % 1 ether; - - vm.deal(address(this), deposit * 2); - - vm.expectEmit(true, true, true, true); - emit ReceiveETH(deposit); - SafeTransferLib.safeTransferETH(clone, deposit); - assertEq(clone.balance, deposit); - - vm.expectEmit(true, true, true, true); - emit ReceiveETH(deposit); - payable(clone).transfer(deposit); - assertEq(clone.balance, deposit * 2); - } - - function _shouldBehaveLikeClone(address clone, uint256 value_) internal { - assertTrue(clone != address(0)); - - uint256 thisValue = this.value(); - if (thisValue == value_) { - value_ ^= 1; - } - LibCWIATest(clone).setValue(value_); - assertEq(value_, LibCWIATest(clone).value()); - assertEq(thisValue, this.value()); - vm.expectRevert(abi.encodeWithSelector(CustomError.selector, value_)); - LibCWIATest(clone).revertWithError(); - } - - function getArgBytes(uint256 argOffset, uint256 length) public pure returns (bytes memory) { - return _getArgBytes(argOffset, length); - } - - function getArgAddress(uint256 argOffset) public pure returns (address) { - return _getArgAddress(argOffset); - } - - function getArgUint256(uint256 argOffset) public pure returns (uint256) { - uint256 result = _getArgUint256(argOffset); - unchecked { - require(bytes32(result) == _getArgBytes32(argOffset)); - require(uint248(result) == _getArgUint248(argOffset + 1)); - require(uint240(result) == _getArgUint240(argOffset + 2)); - require(uint232(result) == _getArgUint232(argOffset + 3)); - require(uint224(result) == _getArgUint224(argOffset + 4)); - require(uint216(result) == _getArgUint216(argOffset + 5)); - require(uint208(result) == _getArgUint208(argOffset + 6)); - require(uint200(result) == _getArgUint200(argOffset + 7)); - require(uint192(result) == _getArgUint192(argOffset + 8)); - require(uint184(result) == _getArgUint184(argOffset + 9)); - require(uint176(result) == _getArgUint176(argOffset + 10)); - require(uint168(result) == _getArgUint168(argOffset + 11)); - require(uint160(result) == _getArgUint160(argOffset + 12)); - require(uint152(result) == _getArgUint152(argOffset + 13)); - require(uint144(result) == _getArgUint144(argOffset + 14)); - require(uint136(result) == _getArgUint136(argOffset + 15)); - require(uint128(result) == _getArgUint128(argOffset + 16)); - require(uint120(result) == _getArgUint120(argOffset + 17)); - require(uint112(result) == _getArgUint112(argOffset + 18)); - require(uint104(result) == _getArgUint104(argOffset + 19)); - require(uint96(result) == _getArgUint96(argOffset + 20)); - require(uint88(result) == _getArgUint88(argOffset + 21)); - require(uint80(result) == _getArgUint80(argOffset + 22)); - require(uint72(result) == _getArgUint72(argOffset + 23)); - require(uint64(result) == _getArgUint64(argOffset + 24)); - require(uint56(result) == _getArgUint56(argOffset + 25)); - require(uint48(result) == _getArgUint48(argOffset + 26)); - require(uint40(result) == _getArgUint40(argOffset + 27)); - require(uint32(result) == _getArgUint32(argOffset + 28)); - require(uint24(result) == _getArgUint24(argOffset + 29)); - require(uint16(result) == _getArgUint16(argOffset + 30)); - require(uint8(result) == _getArgUint8(argOffset + 31)); - } - return result; - } - - function getArgUint256Array(uint256 argOffset, uint256 length) - public - pure - returns (uint256[] memory) - { - uint256[] memory result = _getArgUint256Array(argOffset, length); - bytes32 hash = keccak256(abi.encode(_getArgBytes32Array(argOffset, length))); - require(keccak256(abi.encode(result)) == hash); - return result; - } - - function getArgUint64(uint256 argOffset) public pure returns (uint64) { - return _getArgUint64(argOffset); - } - - function getArgUint8(uint256 argOffset) public pure returns (uint8) { - return _getArgUint8(argOffset); - } - - function testCloneWithImmutableArgs( - uint256 value_, - address argAddress, - uint256 argUint256, - uint256[] memory argUint256Array, - uint64 argUint64, - uint8 argUint8 - ) public { - bytes memory data = - abi.encodePacked(argAddress, argUint256, argUint256Array, argUint64, argUint8); - LibCWIATest clone = LibCWIATest(LibCWIA.clone(address(this), data)); - _shouldBehaveLikeClone(address(clone), value_); - - // For avoiding stack too deep. Also, no risk of overflow. - unchecked { - uint256 argOffset; - assertEq(clone.getArgAddress(argOffset), argAddress); - argOffset += 20; - assertEq(clone.getArgUint256(argOffset), argUint256); - argOffset += 32; - assertEq(clone.getArgUint256Array(argOffset, argUint256Array.length), argUint256Array); - argOffset += 32 * argUint256Array.length; - assertEq(clone.getArgUint64(argOffset), argUint64); - argOffset += 8; - assertEq(clone.getArgUint8(argOffset), argUint8); - } - } - - function testCloneWithImmutableArgs() public { - uint256[] memory argUint256Array = new uint256[](2); - argUint256Array[0] = 111; - argUint256Array[1] = 222; - testCloneWithImmutableArgs(1, address(uint160(0xB00Ba5)), 8, argUint256Array, 7, 6); - } - - function testCloneDeteministicWithImmutableArgs( - address argAddress, - uint256 argUint256, - uint256[] memory argUint256Array, - bytes memory argBytes, - uint64 argUint64, - uint8 argUint8, - uint256 deposit - ) public { - bytes memory data; - bytes32 salt; - - // For avoiding stack too deep. - unchecked { - // Recycle for the salt. - salt = bytes32(argUint256 + 123); - - data = abi.encodePacked( - argUint256, - argAddress, - argUint256, - argUint256Array, - argBytes, - argUint64, - argUint8, - argUint256 - ); - - bytes32 saltKey = keccak256(abi.encode(data, salt)); - if (saltIsUsed[saltKey]) { - vm.expectRevert(LibCWIA.DeploymentFailed.selector); - LibCWIATest(this.cloneDeterministic(address(this), data, salt)); - return; - } - saltIsUsed[saltKey] = true; - } - - bytes32 dataHashBefore = keccak256(data); - - LibCWIATest clone = LibCWIATest(this.cloneDeterministic(address(this), data, salt)); - // Check that memory management is done properly. - assertEq(keccak256(data), dataHashBefore); - - _shouldBehaveLikeClone(address(clone), argUint256); - _canReceiveETHCorrectly(address(clone), deposit); - - // For avoiding stack too deep. Also, no risk of overflow. - unchecked { - uint256 argOffset; - assertEq(clone.getArgUint256(argOffset), argUint256); - argOffset += (256 / 8); - assertEq(clone.getArgAddress(argOffset), argAddress); - argOffset += (160 / 8); - assertEq(clone.getArgUint256(argOffset), argUint256); - argOffset += (256 / 8); - assertEq(clone.getArgUint256Array(argOffset, argUint256Array.length), argUint256Array); - argOffset += (256 / 8) * argUint256Array.length; - assertEq(clone.getArgBytes(argOffset, argBytes.length), argBytes); - argOffset += (8 / 8) * argBytes.length; - assertEq(clone.getArgUint64(argOffset), argUint64); - argOffset += (64 / 8); - assertEq(clone.getArgUint8(argOffset), argUint8); - argOffset += (8 / 8); - assertEq(clone.getArgUint256(argOffset), argUint256); - } - - { - address predicted = - LibCWIA.predictDeterministicAddress(address(this), data, salt, address(this)); - assertEq(address(clone), predicted); - } - - // Check that memory management is done properly. - assertEq(keccak256(data), dataHashBefore); - - assertEq(clone.getCalldataHash(), dataHashBefore); - } - - function testCloneDeteministicWithImmutableArgs() public { - uint256[] memory argUint256Array = new uint256[](2); - argUint256Array[0] = uint256(keccak256("zero")); - argUint256Array[1] = uint256(keccak256("one")); - bytes memory argBytes = bytes("Teehee"); - testCloneDeteministicWithImmutableArgs( - address(uint160(uint256(keccak256("argAddress")))), - uint256(keccak256("argUint256")), - argUint256Array, - argBytes, - uint64(uint256(keccak256("argUint64"))), - uint8(uint256(keccak256("argUint8"))), - uint256(keccak256("deposit")) - ); - } - - function testCloneWithImmutableArgsRevertsIfDataTooBig() public { - uint256 n = 0xff9b; - bytes memory data = _dummyData(n); - - address clone = this.cloneDeterministic(address(this), data, bytes32(gasleft())); - _shouldBehaveLikeClone(clone, 1); - assertEq(LibCWIATest(clone).argBytesHash(), keccak256(data)); - - vm.expectRevert(); - this.cloneDeterministic(address(this), _dummyData(n + 1), bytes32(gasleft())); - } - - function argBytesHash() public pure returns (bytes32) { - return keccak256(_getArgBytes()); - } - - function _dummyData(uint256 n) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x00, n) - mstore(0x20, 1) - mstore(add(0x20, result), keccak256(0x00, 0x40)) - mstore(0x20, 2) - mstore(add(add(0x20, result), n), keccak256(0x00, 0x40)) - mstore(0x20, 3) - mstore(add(result, n), keccak256(0x00, 0x40)) - mstore(0x40, add(add(0x20, result), n)) - mstore(result, n) - } - } - - function testInitCode(address implementation, uint256 n) internal { - _brutalizeMemory(); - bytes memory data; - if ((n >> 32) & 31 > 0) data = _dummyData((n >> 128) & 0xff); - bytes memory initCode = LibCWIA.initCode(implementation, data); - _checkMemory(initCode); - _brutalizeMemory(); - bytes32 expected = LibCWIA.initCodeHash(implementation, data); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - } - - function cloneDeterministic(address implementation, bytes calldata data, bytes32 salt) - external - returns (address) - { - return LibCWIA.cloneDeterministic(_brutalized(implementation), data, salt); - } -} diff --git a/grouperBot/lib/solady/test/LibCall.t.sol b/grouperBot/lib/solady/test/LibCall.t.sol deleted file mode 100644 index cca09f2..0000000 --- a/grouperBot/lib/solady/test/LibCall.t.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibCall} from "../src/utils/LibCall.sol"; -import {LibBytes} from "../src/utils/LibBytes.sol"; - -contract HashSetter { - mapping(uint256 => bytes32) public hashes; - - function setHash(uint256 key, bytes memory data) public payable returns (bytes memory) { - hashes[key] = keccak256(data); - return abi.encodePacked(data, keccak256(data)); - } -} - -contract LibCallTest is SoladyTest { - HashSetter hashSetter; - - function setUp() public { - hashSetter = new HashSetter(); - } - - function testCallAndStaticCall(uint256 key, bytes memory data) public { - vm.deal(address(this), 1 ether); - uint256 value = _bound(_random(), 0, 1 ether); - bytes memory result = LibCall.callContract( - address(hashSetter), value, abi.encodeWithSignature("setHash(uint256,bytes)", key, data) - ); - assertEq(hashSetter.hashes(key), keccak256(data)); - assertEq(abi.decode(result, (bytes)), abi.encodePacked(data, keccak256(data))); - assertEq( - abi.decode( - LibCall.staticCallContract( - address(hashSetter), abi.encodeWithSignature("hashes(uint256)", key) - ), - (bytes32) - ), - keccak256(data) - ); - } - - function testSetSelector(bytes memory dataWithoutSelector) public { - bytes4 sel = bytes4(bytes32(_random())); - bytes memory data = abi.encodePacked(bytes4(bytes32(_random())), dataWithoutSelector); - data = this.copyAndSetSelector(sel, data); - assertEq(data, abi.encodePacked(sel, dataWithoutSelector)); - if (_randomChance(2)) { - uint256 n = _random() % 4; - vm.expectRevert(LibCall.DataTooShort.selector); - this.copyAndSetSelector(sel, LibBytes.slice(data, 0, n)); - } - } - - function copyAndSetSelector(bytes4 sel, bytes memory data) public pure returns (bytes memory) { - LibCall.setSelector(sel, data); - return data; - } -} diff --git a/grouperBot/lib/solady/test/LibClone.t.sol b/grouperBot/lib/solady/test/LibClone.t.sol deleted file mode 100644 index e1648a3..0000000 --- a/grouperBot/lib/solady/test/LibClone.t.sol +++ /dev/null @@ -1,1729 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {LibString} from "../src/utils/LibString.sol"; -import {UpgradeableBeaconTestLib} from "./UpgradeableBeacon.t.sol"; - -contract LibCloneTest is SoladyTest { - error CustomError(uint256 currentValue); - - uint256 public value; - - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - bytes32 internal constant _ERC1967_BEACON_SLOT = - 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; - - uint256 internal constant _CLONES_ARGS_MAX_LENGTH = 0xffd2; - - uint256 internal constant _ERC1967_ARGS_MAX_LENGTH = 0xffc2; - - uint256 internal constant _ERC1967I_ARGS_MAX_LENGTH = 0xffad; - - uint256 internal constant _ERC1967_BEACON_PROXY_ARGS_MAX_LENGTH = 0xffad; - - uint256 internal constant _ERC1967I_BEACON_PROXY_ARGS_MAX_LENGTH = 0xffa8; - - address internal _deployedBeacon; - - function setValue(uint256 value_) public { - value = value_; - } - - function revertWithError() public view { - revert CustomError(value); - } - - function _checkBehavesLikeProxy(address instance) internal { - assertTrue(instance != address(0)); - - uint256 v = _random(); - uint256 thisValue = this.value(); - if (thisValue == v) { - v ^= 1; - } - LibCloneTest(instance).setValue(v); - assertEq(v, LibCloneTest(instance).value()); - assertEq(thisValue, this.value()); - vm.expectRevert(abi.encodeWithSelector(CustomError.selector, v)); - LibCloneTest(instance).revertWithError(); - } - - function testDeployERC1967(bytes32) public { - address instance = LibClone.deployERC1967(address(this)); - _checkBehavesLikeProxy(instance); - _checkArgsOnERC1967(instance, ""); - _checkERC1967ImplementationSlot(instance); - assertEq(keccak256(instance.code), LibClone.ERC1967_CODE_HASH); - assertEq(instance.code.length, 61); - } - - function testDeployERC1967WithImmutableArgs(bytes32) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.deployERC1967(address(this), args); - return; - } - address instance = this.deployERC1967(address(this), args); - _checkArgsOnERC1967(instance, args); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - } - - function testDeployERC1967I(bytes32) public { - address instance = this.deployERC1967I(address(this)); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - _checkERC1967ISpecialPath(instance, address(this)); - assertEq(keccak256(instance.code), LibClone.ERC1967I_CODE_HASH); - assertEq(instance.code.length, 82); - } - - function testDeployERC1967IWithImmutableArgs(bytes32) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967I_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.deployERC1967I(address(this), args); - return; - } - address instance = this.deployERC1967I(address(this), args); - _checkArgsOnERC1967I(instance, args); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - _checkERC1967ISpecialPath(instance, address(this)); - } - - function testDeployERC1967BeaconProxy(bytes32) public { - address beacon = _beacon(); - address instance = this.deployERC1967BeaconProxy(beacon); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, beacon); - assertEq(keccak256(instance.code), LibClone.ERC1967_BEACON_PROXY_CODE_HASH); - assertEq(instance.code.length, 82); - } - - function testDeployERC1967IBeaconProxy(bytes32) public { - address beacon = _beacon(); - address instance = this.deployERC1967IBeaconProxy(beacon); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, beacon); - _checkERC1967ISpecialPath(instance, address(this)); - assertEq(keccak256(instance.code), LibClone.ERC1967I_BEACON_PROXY_CODE_HASH); - assertEq(instance.code.length, 87); - } - - function testDeployERC1967() public { - testDeployERC1967(bytes32(0)); - } - - function testDeployERC1967WithImmutableArgs() public { - testDeployERC1967WithImmutableArgs(bytes32(0)); - } - - function testDeployERC1967IWithImmutableArgs() public { - testDeployERC1967IWithImmutableArgs(bytes32(0)); - } - - function testDeployERC1967I() public { - testDeployERC1967I(bytes32(0)); - } - - function testDeployERC1967IBeaconProxy() public { - testDeployERC1967IBeaconProxy(bytes32(0)); - } - - function testDeployERC1967BeaconProxyWithImmutableArgs(address beacon, bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967_BEACON_PROXY_ARGS_MAX_LENGTH) { - if (_randomChance(2)) { - vm.expectRevert(); - this.deployERC1967BeaconProxy(beacon, args); - return; - } - if (_randomChance(2)) { - vm.expectRevert(); - this.deployDeterministicERC1967BeaconProxy(beacon, args, salt); - return; - } - vm.expectRevert(); - this.createDeterministicERC1967BeaconProxy(beacon, args, salt); - return; - } - address instance = LibClone.deployERC1967BeaconProxy(beacon); - bytes memory expected = abi.encodePacked(instance.code, args); - if (_randomChance(2)) { - instance = this.deployERC1967BeaconProxy(beacon, args); - assertEq(instance.code, expected); - } - if (_randomChance(2)) { - instance = this.deployDeterministicERC1967BeaconProxy(beacon, args, salt); - assertEq(instance.code, expected); - if (_randomChance(2)) { - vm.expectRevert(); - this.deployDeterministicERC1967BeaconProxy(beacon, args, salt); - return; - } - } - if (_randomChance(2)) { - instance = this.createDeterministicERC1967BeaconProxy(beacon, args, salt); - assertEq(instance.code, expected); - _checkArgsOnERC1967BeaconProxy(instance, args); - } - } - - function testDeployERC1967IBeaconProxyWithImmutableArgs(address beacon, bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967I_BEACON_PROXY_ARGS_MAX_LENGTH) { - if (_randomChance(2)) { - vm.expectRevert(); - this.deployERC1967IBeaconProxy(beacon, args); - return; - } - if (_randomChance(2)) { - vm.expectRevert(); - this.deployDeterministicERC1967IBeaconProxy(beacon, args, salt); - return; - } - vm.expectRevert(); - this.createDeterministicERC1967IBeaconProxy(beacon, args, salt); - return; - } - address instance = LibClone.deployERC1967IBeaconProxy(beacon); - bytes memory expected = abi.encodePacked(instance.code, args); - if (_randomChance(2)) { - instance = this.deployERC1967IBeaconProxy(beacon, args); - assertEq(instance.code, expected); - } - if (_randomChance(2)) { - instance = this.deployDeterministicERC1967IBeaconProxy(beacon, args, salt); - assertEq(instance.code, expected); - if (_randomChance(2)) { - vm.expectRevert(); - this.deployDeterministicERC1967IBeaconProxy(beacon, args, salt); - return; - } - } - if (_randomChance(2)) { - instance = this.createDeterministicERC1967IBeaconProxy(beacon, args, salt); - assertEq(instance.code, expected); - _checkArgsOnERC1967IBeaconProxy(instance, args); - } - } - - function testDeployERC1967BeaconProxyWithImmutableArgs() public { - address beacon = _beacon(); - bytes memory args = "123456789"; - address instance = LibClone.deployERC1967BeaconProxy(beacon, args); - _checkBehavesLikeProxy(instance); - _checkArgsOnERC1967BeaconProxy(instance, args); - } - - function testDeployERC1967IBeaconProxyWithImmutableArgs() public { - address beacon = _beacon(); - bytes memory args = "123456789"; - address instance = LibClone.deployERC1967IBeaconProxy(beacon, args); - _checkBehavesLikeProxy(instance); - _checkERC1967ISpecialPath(instance, address(this)); - _checkArgsOnERC1967IBeaconProxy(instance, args); - } - - function testImplemenationOf(address implementation) public { - _maybeBrutalizeMemory(); - bytes memory args = _truncateBytes(_randomBytes(), _ERC1967I_BEACON_PROXY_ARGS_MAX_LENGTH); - address instance; - if (_randomChance(8)) { - _maybeBrutalizeMemory(); - instance = LibClone.clone(implementation); - assertEq(LibClone.implementationOf(instance), implementation); - } - if (_randomChance(8)) { - _maybeBrutalizeMemory(); - instance = LibClone.clone(implementation, args); - assertEq(LibClone.implementationOf(instance), implementation); - } - if (_randomChance(8)) { - _maybeBrutalizeMemory(); - instance = LibClone.deployERC1967I(implementation); - assertEq(LibClone.implementationOf(instance), implementation); - } - if (_randomChance(8)) { - _maybeBrutalizeMemory(); - instance = LibClone.deployERC1967I(implementation, args); - assertEq(LibClone.implementationOf(instance), implementation); - } - if (_randomChance(8)) { - _maybeBrutalizeMemory(); - instance = LibClone.deployERC1967IBeaconProxy(_beacon()); - assertEq(LibClone.implementationOf(instance), address(this)); - } - if (_randomChance(8)) { - _maybeBrutalizeMemory(); - instance = LibClone.deployERC1967IBeaconProxy(_beacon(), args); - assertEq(LibClone.implementationOf(instance), address(this)); - } - if (_randomChance(8)) { - _maybeBrutalizeMemory(); - assertEq(LibClone.implementationOf(address(this)), address(0)); - assertEq(LibClone.implementationOf(implementation), address(0)); - } - _checkMemory(); - } - - function testImplemenationOfGas() public { - address implementation = address(123); - bytes memory args = "1234564789"; - address instance; - - instance = LibClone.clone(implementation); - assertEq(LibClone.implementationOf(instance), implementation); - - instance = LibClone.clone(implementation, args); - assertEq(LibClone.implementationOf(instance), implementation); - - instance = LibClone.deployERC1967I(implementation); - assertEq(LibClone.implementationOf(instance), implementation); - - instance = LibClone.deployERC1967I(implementation, args); - assertEq(LibClone.implementationOf(instance), implementation); - - instance = LibClone.deployERC1967IBeaconProxy(_beacon()); - assertEq(LibClone.implementationOf(instance), address(this)); - - instance = LibClone.deployERC1967IBeaconProxy(_beacon(), args); - assertEq(LibClone.implementationOf(instance), address(this)); - - assertEq(LibClone.implementationOf(address(this)), address(0)); - assertEq(LibClone.implementationOf(implementation), address(0)); - } - - function testClone(uint256) public { - _checkBehavesLikeProxy(this.clone(address(this))); - } - - function testClone() public { - testClone(1); - } - - function testCloneWithImmutableArgs() public { - testCloneWithImmutableArgs(1); - } - - function testCloneWithImmutableArgs(uint256) public { - bytes memory args = _randomBytes(); - if (args.length > _CLONES_ARGS_MAX_LENGTH) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.clone(address(this), args); - return; - } - address instance = this.clone(address(this), args); - _checkArgsOnClone(instance, args); - _checkBehavesLikeProxy(instance); - } - - function argsOnClone(address instance) public view returns (bytes memory) { - return LibClone.argsOnClone(instance); - } - - function argsOnClone(address instance, uint256 start) public view returns (bytes memory) { - return LibClone.argsOnClone(instance, start); - } - - function argsOnClone(address instance, uint256 start, uint256 end) - public - view - returns (bytes memory) - { - return LibClone.argsOnClone(instance, start, end); - } - - function argsOnERC1967(address instance) public view returns (bytes memory) { - return LibClone.argsOnERC1967(instance); - } - - function argsOnERC1967(address instance, uint256 start) public view returns (bytes memory) { - return LibClone.argsOnERC1967(instance, start); - } - - function argsOnERC1967(address instance, uint256 start, uint256 end) - public - view - returns (bytes memory) - { - return LibClone.argsOnERC1967(instance, start, end); - } - - function argsOnERC1967I(address instance) public view returns (bytes memory) { - return LibClone.argsOnERC1967I(instance); - } - - function argsOnERC1967I(address instance, uint256 start) public view returns (bytes memory) { - return LibClone.argsOnERC1967I(instance, start); - } - - function argsOnERC1967I(address instance, uint256 start, uint256 end) - public - view - returns (bytes memory) - { - return LibClone.argsOnERC1967I(instance, start, end); - } - - function argsOnERC1967BeaconProxy(address instance) public view returns (bytes memory) { - return LibClone.argsOnERC1967BeaconProxy(instance); - } - - function argsOnERC1967BeaconProxy(address instance, uint256 start) - public - view - returns (bytes memory) - { - return LibClone.argsOnERC1967BeaconProxy(instance, start); - } - - function argsOnERC1967BeaconProxy(address instance, uint256 start, uint256 end) - public - view - returns (bytes memory) - { - return LibClone.argsOnERC1967BeaconProxy(instance, start, end); - } - - function argsOnERC1967IBeaconProxy(address instance) public view returns (bytes memory) { - return LibClone.argsOnERC1967IBeaconProxy(instance); - } - - function argsOnERC1967IBeaconProxy(address instance, uint256 start) - public - view - returns (bytes memory) - { - return LibClone.argsOnERC1967IBeaconProxy(instance, start); - } - - function argsOnERC1967IBeaconProxy(address instance, uint256 start, uint256 end) - public - view - returns (bytes memory) - { - return LibClone.argsOnERC1967IBeaconProxy(instance, start, end); - } - - function testSlicingRevertsOnZeroCodeAddress(address instance) public { - while (instance.code.length != 0) instance = _randomNonZeroAddress(); - if (_randomChance(4)) { - _maybeBrutalizeMemory(); - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnClone(instance)); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnClone(instance, _random())); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnClone(instance, _random(), _random())); - return; - } - instance = LibClone.clone(address(this), ""); - assertEq(LibClone.argsOnClone(instance), ""); - assertEq(LibClone.argsOnClone(instance, _random()), ""); - assertEq(LibClone.argsOnClone(instance, _random(), _random()), ""); - return; - } - if (_randomChance(4)) { - _maybeBrutalizeMemory(); - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967(instance)); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967(instance, _random())); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967(instance, _random(), _random())); - return; - } - instance = LibClone.deployERC1967(address(this), ""); - assertEq(LibClone.argsOnERC1967(instance), ""); - assertEq(LibClone.argsOnERC1967(instance, _random()), ""); - assertEq(LibClone.argsOnERC1967(instance, _random(), _random()), ""); - return; - } - if (_randomChance(4)) { - _maybeBrutalizeMemory(); - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967I(instance)); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967I(instance, _random())); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967I(instance, _random(), _random())); - return; - } - instance = LibClone.deployERC1967I(address(this), ""); - assertEq(LibClone.argsOnERC1967I(instance), ""); - assertEq(LibClone.argsOnERC1967I(instance, _random()), ""); - assertEq(LibClone.argsOnERC1967I(instance, _random(), _random()), ""); - return; - } - if (_randomChance(4)) { - _maybeBrutalizeMemory(); - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967BeaconProxy(instance)); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967BeaconProxy(instance, _random())); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967BeaconProxy(instance, _random(), _random())); - return; - } - instance = LibClone.deployERC1967BeaconProxy(address(this), ""); - assertEq(LibClone.argsOnERC1967BeaconProxy(instance), ""); - assertEq(LibClone.argsOnERC1967BeaconProxy(instance, _random()), ""); - assertEq(LibClone.argsOnERC1967BeaconProxy(instance, _random(), _random()), ""); - return; - } - if (_randomChance(4)) { - _maybeBrutalizeMemory(); - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967IBeaconProxy(instance)); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967IBeaconProxy(instance, _random())); - return; - } - if (_randomChance(4)) { - vm.expectRevert(); - _mustCompute(this.argsOnERC1967IBeaconProxy(instance, _random(), _random())); - return; - } - instance = LibClone.deployERC1967IBeaconProxy(address(this), ""); - assertEq(LibClone.argsOnERC1967IBeaconProxy(instance), ""); - assertEq(LibClone.argsOnERC1967IBeaconProxy(instance, _random()), ""); - assertEq(LibClone.argsOnERC1967IBeaconProxy(instance, _random(), _random()), ""); - return; - } - } - - function _mustCompute(bytes memory s) internal { - /// @solidity memory-safe-assembly - assembly { - if eq(keccak256(s, 0x80), 123) { sstore(keccak256(0x00, 0x21), 1) } - } - } - - function testCloneWithImmutableArgsSlicing() public { - bytes memory args = "1234567890123456789012345678901234567890123456789012345678901234"; - address instance = LibClone.clone(address(this), args); - assertEq(LibClone.argsOnClone(instance), args); - assertEq(LibClone.argsOnClone(instance, 32), "34567890123456789012345678901234"); - assertEq(LibClone.argsOnClone(instance, 0, 64), args); - assertEq(LibClone.argsOnClone(instance, 0, 65), args); - assertEq(LibClone.argsOnClone(instance, 0, 32), "12345678901234567890123456789012"); - assertEq(LibClone.argsOnClone(instance, 1, 32), "2345678901234567890123456789012"); - } - - function testCloneDeterministic(bytes32 salt) public { - address instance = this.cloneDeterministic(address(this), salt); - _checkBehavesLikeProxy(instance); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.testCloneDeterministic(salt); - } - } - - function testCreateDeterministicCloneWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _CLONES_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.createDeterministicClone(address(this), args, salt); - return; - } - address instance = this.createDeterministicClone(address(this), args, salt); - _checkArgsOnClone(instance, args); - _checkBehavesLikeProxy(instance); - if (_randomChance(32)) { - this.createDeterministicClone(address(this), args, salt); - } - } - - function testCloneDeterministicWithImmutableArgs() public { - testCloneDeterministicWithImmutableArgs(bytes32(0)); - } - - function testCloneDeterministicWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _CLONES_ARGS_MAX_LENGTH) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.cloneDeterministic(address(this), args, salt); - return; - } - address instance = this.cloneDeterministic(address(this), args, salt); - _checkBehavesLikeProxy(instance); - _checkArgsOnClone(instance, args); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.cloneDeterministic(address(this), args, salt); - } - } - - function testCloneDeterministic() public { - testCloneDeterministic(keccak256("b")); - } - - function testDeployDeterministicERC1967(bytes32 salt) public { - address instance = this.deployDeterministicERC1967(address(this), salt); - _checkBehavesLikeProxy(instance); - _checkArgsOnERC1967(instance, ""); - _checkERC1967ImplementationSlot(instance); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.testDeployDeterministicERC1967(salt); - } - } - - function testDeployDeterministicERC1967WithImmutableArgs() public { - testDeployDeterministicERC1967WithImmutableArgs(bytes32(0)); - } - - function testDeployDeterministicERC1967WithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.deployDeterministicERC1967(address(this), args, salt); - return; - } - address instance = this.deployDeterministicERC1967(address(this), args, salt); - _checkArgsOnERC1967(instance, args); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.deployDeterministicERC1967(address(this), args, salt); - } - } - - function testDeployDeterministicERC1967() public { - testDeployDeterministicERC1967(bytes32(0)); - } - - function testDeployDeterministicERC1967I() public { - testDeployDeterministicERC1967I(bytes32(0)); - } - - function testDeployDeterministicERC1967I(bytes32 salt) public { - address instance = this.deployDeterministicERC1967I(address(this), salt); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.testDeployDeterministicERC1967I(salt); - } - } - - function testDeployDeterministicERC1967IWithImmutableArgs() public { - testDeployDeterministicERC1967I(bytes32(0)); - } - - function testDeployDeterministicERC1967IWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967I_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.deployDeterministicERC1967I(address(this), args, salt); - return; - } - address instance = this.deployDeterministicERC1967I(address(this), args, salt); - _checkArgsOnERC1967I(instance, args); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.deployDeterministicERC1967I(address(this), args, salt); - } - } - - function testDeployDeterministicERC1967BeaconProxy(bytes32 salt) public { - address instance = this.deployDeterministicERC1967BeaconProxy(_beacon(), salt); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, _beacon()); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.testDeployDeterministicERC1967BeaconProxy(salt); - } - } - - function testDeployDeterministicERC1967IBeaconProxy(bytes32 salt) public { - address instance = this.deployDeterministicERC1967IBeaconProxy(_beacon(), salt); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, _beacon()); - _checkERC1967ISpecialPath(instance, address(this)); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.testDeployDeterministicERC1967IBeaconProxy(salt); - } - } - - function testDeployDeterministicERC1967BeaconProxyWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967_BEACON_PROXY_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.deployDeterministicERC1967BeaconProxy(address(this), args, salt); - return; - } - address instance = this.deployDeterministicERC1967BeaconProxy(_beacon(), args, salt); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, _beacon()); - _checkArgsOnERC1967BeaconProxy(instance, args); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.deployDeterministicERC1967BeaconProxy(_beacon(), args, salt); - } - } - - function testDeployDeterministicERC1967IBeaconProxyWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967I_BEACON_PROXY_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.deployDeterministicERC1967IBeaconProxy(address(this), args, salt); - return; - } - address instance = this.deployDeterministicERC1967IBeaconProxy(_beacon(), args, salt); - _checkBehavesLikeProxy(instance); - _checkArgsOnERC1967IBeaconProxy(instance, args); - _checkERC1967BeaconSlot(instance, _beacon()); - _checkERC1967ISpecialPath(instance, address(this)); - if (_randomChance(32)) { - vm.expectRevert(LibClone.DeploymentFailed.selector); - this.deployDeterministicERC1967IBeaconProxy(_beacon(), args, salt); - } - } - - function testCreateDeterministicERC1967(bytes32 salt) public { - address instance = this.createDeterministicERC1967(address(this), salt); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - if (_randomChance(32)) { - this.testCreateDeterministicERC1967(salt); - } - } - - function testCreateDeterministicERC1967WithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.createDeterministicERC1967(address(this), args, salt); - return; - } - address instance = this.createDeterministicERC1967(address(this), args, salt); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - _checkArgsOnERC1967(instance, args); - if (_randomChance(32)) { - this.createDeterministicERC1967(address(this), args, salt); - } - } - - function testCreateDeterministicERC1967I(bytes32 salt) public { - address instance = this.createDeterministicERC1967I(address(this), salt); - _checkBehavesLikeProxy(instance); - _checkERC1967ImplementationSlot(instance); - if (_randomChance(32)) { - this.testCreateDeterministicERC1967I(salt); - } - } - - function testCreateDeterministicERC1967IWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967I_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.createDeterministicERC1967I(address(this), args, salt); - return; - } - address instance = this.createDeterministicERC1967I(address(this), args, salt); - _checkBehavesLikeProxy(instance); - _checkArgsOnERC1967I(instance, args); - _checkERC1967ImplementationSlot(instance); - if (_randomChance(32)) { - this.createDeterministicERC1967I(address(this), args, salt); - } - } - - function testCreateDeterministicERC1967BeaconProxy(bytes32 salt) public { - address instance = this.createDeterministicERC1967BeaconProxy(_beacon(), salt); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, _beacon()); - if (_randomChance(32)) { - this.testCreateDeterministicERC1967BeaconProxy(salt); - } - } - - function testCreateDeterministicERC1967IBeaconProxy(bytes32 salt) public { - address instance = this.createDeterministicERC1967IBeaconProxy(_beacon(), salt); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, _beacon()); - if (_randomChance(32)) { - this.testCreateDeterministicERC1967IBeaconProxy(salt); - } - } - - function testCreateDeterministicERC1967BeaconProxyWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967_BEACON_PROXY_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.createDeterministicERC1967BeaconProxy(address(this), args, salt); - return; - } - - address instance = this.createDeterministicERC1967BeaconProxy(_beacon(), args, salt); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, _beacon()); - if (_randomChance(32)) { - this.createDeterministicERC1967BeaconProxy(_beacon(), args, salt); - } - } - - function testCreateDeterministicERC1967IBeaconProxyWithImmutableArgs(bytes32 salt) public { - bytes memory args = _randomBytes(); - if (args.length > _ERC1967I_BEACON_PROXY_ARGS_MAX_LENGTH) { - vm.expectRevert(); - this.createDeterministicERC1967IBeaconProxy(address(this), args, salt); - return; - } - - address instance = this.createDeterministicERC1967IBeaconProxy(_beacon(), args, salt); - _checkBehavesLikeProxy(instance); - _checkERC1967BeaconSlot(instance, _beacon()); - _checkERC1967ISpecialPath(instance, address(this)); - if (_randomChance(32)) { - this.createDeterministicERC1967IBeaconProxy(_beacon(), args, salt); - } - } - - function testStartsWith(uint256) public { - uint256 noise = _random() >> 160; - this.checkStartsWith(bytes32(noise), address(0)); - - address by = _randomNonZeroAddress(); - this.checkStartsWith(bytes32((uint256(uint160(by)) << 96) | noise), by); - - address notBy; - while (by == notBy) notBy = _randomNonZeroAddress(); - vm.expectRevert(LibClone.SaltDoesNotStartWith.selector); - this.checkStartsWith(bytes32((uint256(uint160(by)) << 96) | noise), notBy); - } - - function checkStartsWith(bytes32 salt, address by) public pure { - LibClone.checkStartsWith(salt, _brutalized(by)); - } - - function testInitialDeposit() public { - vm.deal(address(this), 1 ether); - address t = address(this); - assertEq(LibClone.clone(123, t).balance, 123); - assertEq(LibClone.cloneDeterministic(123, t, bytes32(gasleft())).balance, 123); - assertEq(LibClone.clone(123, t, "").balance, 123); - assertEq(LibClone.cloneDeterministic(123, t, "", bytes32(gasleft())).balance, 123); - assertEq(LibClone.deployERC1967(123, t).balance, 123); - assertEq(LibClone.deployDeterministicERC1967(123, t, bytes32(gasleft())).balance, 123); - assertEq(LibClone.deployERC1967I(123, t).balance, 123); - assertEq(LibClone.deployDeterministicERC1967I(123, t, bytes32(gasleft())).balance, 123); - assertEq(LibClone.deployERC1967I(123, t, "").balance, 123); - assertEq(LibClone.deployDeterministicERC1967I(123, t, "", bytes32(gasleft())).balance, 123); - assertEq(LibClone.deployERC1967BeaconProxy(123, t).balance, 123); - assertEq( - LibClone.deployDeterministicERC1967BeaconProxy(123, t, bytes32(gasleft())).balance, 123 - ); - assertEq(LibClone.deployERC1967IBeaconProxy(123, t, "").balance, 123); - assertEq( - LibClone.deployDeterministicERC1967IBeaconProxy(123, t, "", bytes32(gasleft())).balance, - 123 - ); - } - - function testInitCode(address implementation) public { - if (_randomChance(4)) _testInitCode(implementation); - if (_randomChance(4)) _testInitCodeWithImmutableArgs(implementation); - if (_randomChance(4)) _testInitCode_PUSH0(implementation); - if (_randomChance(4)) _testInitCodeERC1967(implementation); - if (_randomChance(4)) _testInitCodeERC1967WithImmutableArgs(implementation); - if (_randomChance(4)) _testInitCodeERC1967I(implementation); - if (_randomChance(4)) _testInitCodeERC1967IWithImmutableArgs(implementation); - if (_randomChance(4)) _testInitCodeERC1967BeaconProxy(implementation); - if (_randomChance(4)) _testInitCodeERC1967BeaconProxyWithImmutableArgs(implementation); - if (_randomChance(4)) _testInitCodeERC1967IBeaconProxy(implementation); - if (_randomChance(4)) _testInitCodeERC1967IBeaconProxyWithImmutableArgs(implementation); - } - - function _testInitCode(address implementation) internal { - _misalignFreeMemoryPointer(); - _maybeBrutalizeMemory(); - bytes memory initCode = LibClone.initCode(_brutalized(implementation)); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHash(_brutalized(implementation)); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - } - - function _testInitCodeWithImmutableArgs(address implementation) internal { - _maybeBrutalizeMemory(); - bytes memory args = _randomBytesForCloneImmutableArgs(); - bytes memory initCode = LibClone.initCode(_brutalized(implementation), args); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHash(_brutalized(implementation), args); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - if (_randomChance(32)) { - assertEq(initCode, _initCodeOfClonesWithImmutableArgs(implementation, args)); - } - } - - function _testInitCode_PUSH0(address implementation) internal { - _maybeBrutalizeMemory(); - bytes memory initCode = LibClone.initCode_PUSH0(_brutalized(implementation)); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHash_PUSH0(_brutalized(implementation)); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - } - - function _testInitCodeERC1967(address implementation) internal { - _maybeBrutalizeMemory(); - bytes memory initCode = LibClone.initCodeERC1967(_brutalized(implementation)); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967(_brutalized(implementation)); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - } - - function _testInitCodeERC1967WithImmutableArgs(address implementation) internal { - _maybeBrutalizeMemory(); - bytes memory args = _randomBytesForERC1967ImmutableArgs(); - bytes memory initCode = LibClone.initCodeERC1967(_brutalized(implementation), args); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967(_brutalized(implementation), args); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - if (_randomChance(32)) { - assertEq(initCode, _initCodeOfERC1967WithImmutableArgs(implementation, args)); - } - } - - function _testInitCodeERC1967I(address implementation) internal { - _maybeBrutalizeMemory(); - bytes memory initCode = LibClone.initCodeERC1967I(_brutalized(implementation)); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967I(_brutalized(implementation)); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - } - - function _testInitCodeERC1967IWithImmutableArgs(address implementation) internal { - _maybeBrutalizeMemory(); - bytes memory args = _randomBytesForERC1967IImmutableArgs(); - bytes memory initCode = LibClone.initCodeERC1967I(_brutalized(implementation), args); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967I(_brutalized(implementation), args); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - if (_randomChance(32)) { - assertEq(initCode, _initCodeOfERC1967IWithImmutableArgs(implementation, args)); - } - } - - function _testInitCodeERC1967BeaconProxy(address beacon) internal { - _maybeBrutalizeMemory(); - bytes memory initCode = LibClone.initCodeERC1967BeaconProxy(_brutalized(beacon)); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967BeaconProxy(_brutalized(beacon)); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - } - - function _testInitCodeERC1967BeaconProxyWithImmutableArgs(address beacon) internal { - _maybeBrutalizeMemory(); - bytes memory args = _randomBytesForERC1967BeconProxyImmutableArgs(); - bytes memory initCode = LibClone.initCodeERC1967BeaconProxy(_brutalized(beacon), args); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967BeaconProxy(_brutalized(beacon), args); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - if (_randomChance(32)) { - assertEq(initCode, _initCodeOfERC1967BeaconProxyWithImmutableArgs(beacon, args)); - } - } - - function _testInitCodeERC1967IBeaconProxy(address beacon) internal { - _maybeBrutalizeMemory(); - bytes memory initCode = LibClone.initCodeERC1967IBeaconProxy(_brutalized(beacon)); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967IBeaconProxy(_brutalized(beacon)); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - } - - function _testInitCodeERC1967IBeaconProxyWithImmutableArgs(address beacon) internal { - _maybeBrutalizeMemory(); - bytes memory args = _randomBytesForERC1967IBeconProxyImmutableArgs(); - bytes memory initCode = LibClone.initCodeERC1967IBeaconProxy(_brutalized(beacon), args); - _checkMemory(initCode); - _maybeBrutalizeMemory(); - bytes32 expected = LibClone.initCodeHashERC1967IBeaconProxy(_brutalized(beacon), args); - _checkMemory(initCode); - assertEq(keccak256(initCode), expected); - if (_randomChance(32)) { - assertEq(initCode, _initCodeOfERC1967IBeaconProxyWithImmutableArgs(beacon, args)); - } - } - - function _initCodeOfClonesWithImmutableArgs(address implementation, bytes memory args) - internal - pure - returns (bytes memory) - { - return abi.encodePacked( - hex"61", - uint16(args.length + 0x2d), - hex"3d81600a3d39f3363d3d373d3d3d363d73", - implementation, - hex"5af43d82803e903d91602b57fd5bf3", - args - ); - } - - function _initCodeOfERC1967WithImmutableArgs(address implementation, bytes memory args) - internal - pure - returns (bytes memory) - { - return abi.encodePacked( - hex"61", - uint16(args.length + 0x3d), - hex"3d8160233d3973", - implementation, - hex"60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3", - args - ); - } - - function _initCodeOfERC1967IWithImmutableArgs(address implementation, bytes memory args) - internal - pure - returns (bytes memory) - { - return abi.encodePacked( - hex"61", - uint16(args.length + 0x52), - hex"3d8160233d3973", - implementation, - hex"600f5155f3365814604357363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3", - args - ); - } - - function _initCodeOfERC1967BeaconProxyWithImmutableArgs(address beacon, bytes memory args) - internal - pure - returns (bytes memory) - { - return abi.encodePacked( - hex"61", - uint16(args.length + 0x52), - hex"3d8160233d3973", - beacon, - hex"60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3", - args - ); - } - - function _initCodeOfERC1967IBeaconProxy(address beacon) internal pure returns (bytes memory) { - return abi.encodePacked( - hex"60573d8160233d3973", - beacon, - hex"60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3" - ); - } - - function _initCodeOfERC1967IBeaconProxyWithImmutableArgs(address beacon, bytes memory args) - internal - pure - returns (bytes memory) - { - return abi.encodePacked( - hex"61", - uint16(args.length + 0x57), - hex"3d8160233d3973", - beacon, - hex"60195155f3363d3d373d3d363d602036600436635c60da1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50545afa361460525736515af43d600060013e6052573d6001fd5b3d6001f3", - args - ); - } - - function testERC1967BootstrapInitCode(address authorizedUpgrader) public { - bytes memory c = LibClone.initCodeERC1967Bootstrap(authorizedUpgrader); - bytes memory expected = abi.encodePacked( - hex"606880600a3d393df3fe3373", - authorizedUpgrader, - hex"0338573d3560601c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55601436116049575b005b363d3d373d3d6014360360143d3560601c5af46047573d6000383e3d38fd" - ); - assertEq(c, expected); - } - - function testERC1967BootstrapGuard(address implementation, bytes32 salt) public { - address authorizedUpgrader = _randomNonZeroAddress(); - address bootstrap = LibClone.erc1967Bootstrap(authorizedUpgrader); - address instance = this.deployDeterministicERC1967I(bootstrap, salt); - assertEq(LibClone.implementationOf(instance), bootstrap); - bytes memory bootstrapCode = address(bootstrap).code; - assertEq(uint8(bootstrapCode[bootstrapCode.length - 1]), uint8(0xfd)); - if (_randomChance(2)) { - vm.prank(authorizedUpgrader); - LibClone.bootstrapERC1967(instance, implementation); - assertEq(LibClone.implementationOf(instance), implementation); - } else { - vm.expectRevert(); - LibClone.bootstrapERC1967(instance, implementation); - } - } - - function testERC1967Bootstrap(address implementation, bytes32 salt) public { - address bootstrap = LibClone.predictDeterministicAddressERC1967Bootstrap(); - assertEq(LibClone.erc1967Bootstrap(), bootstrap); - if (_randomChance(2)) { - assertEq(LibClone.erc1967Bootstrap(), bootstrap); - } - - address instance; - if (_randomChance(2)) { - instance = LibClone.predictDeterministicAddressERC1967(bootstrap, salt, address(this)); - assertEq(this.deployDeterministicERC1967(bootstrap, salt), instance); - } else { - instance = LibClone.predictDeterministicAddressERC1967I(bootstrap, salt, address(this)); - assertEq(this.deployDeterministicERC1967I(bootstrap, salt), instance); - } - - if (_randomChance(2)) { - LibClone.bootstrapERC1967(instance, implementation); - assertEq( - vm.load(instance, _ERC1967_IMPLEMENTATION_SLOT), - bytes32(uint256(uint160(implementation))) - ); - } else if (_randomChance(2)) { - LibClone.bootstrapERC1967(instance, address(this)); - assertEq( - vm.load(instance, _ERC1967_IMPLEMENTATION_SLOT), - bytes32(uint256(uint160(address(this)))) - ); - _checkBehavesLikeProxy(instance); - } else if (_randomChance(2)) { - uint256 x = _random(); - this.bootstrapERC1967AndCall( - instance, address(this), abi.encodeWithSignature("setValue(uint256)", x) - ); - assertEq(LibCloneTest(instance).value(), x); - assertEq( - vm.load(instance, _ERC1967_IMPLEMENTATION_SLOT), - bytes32(uint256(uint160(address(this)))) - ); - _checkBehavesLikeProxy(instance); - } else { - vm.expectRevert(abi.encodeWithSelector(CustomError.selector, uint256(0))); - this.bootstrapERC1967AndCall( - instance, address(this), abi.encodeWithSignature("revertWithError()") - ); - assertEq( - vm.load(instance, _ERC1967_IMPLEMENTATION_SLOT), - bytes32(uint256(uint160(bootstrap))) - ); - } - } - - function bootstrapERC1967AndCall(address instance, address implementation, bytes memory data) - public - { - LibClone.bootstrapERC1967AndCall(instance, implementation, data); - } - - function _beacon() internal returns (address result) { - if (_deployedBeacon != address(0)) return _deployedBeacon; - if (_randomChance(2)) { - result = UpgradeableBeaconTestLib.deployYulBeacon(address(this), address(this)); - } else { - result = UpgradeableBeaconTestLib.deploySolidityBeacon(address(this), address(this)); - } - _deployedBeacon = result; - } - - function testERC1967BeaconProxyGasBehavior(uint256 gasBudget, uint256 value_) public { - address instance = this.deployERC1967BeaconProxy(_beacon()); - LibCloneTest(instance).setValue(value_); - gasBudget = _randomChance(2) ? gasBudget % 3000 : gasBudget % 30000; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, value_) - let hash := keccak256(0x00, 0x40) - mstore(0x20, hash) - mstore(0x00, 0x3fa4f245) // `value()`. - switch staticcall(gasBudget, instance, 0x1c, 0x04, 0x20, 0x20) - case 0 { if iszero(eq(mload(0x20), hash)) { invalid() } } - default { if iszero(eq(mload(0x20), value_)) { invalid() } } - - mstore(0x20, hash) - mstore(0x00, 0x57eca1a5) // `revertWithError()`. - switch staticcall(gasBudget, instance, 0x1c, 0x04, 0x20, 0x20) - case 0 { - if iszero(or(iszero(returndatasize()), eq(returndatasize(), 0x24))) { invalid() } - } - default { invalid() } - } - } - - function testERC1967IBeaconProxyGasBehavior(uint256 gasBudget, uint256 value_) public { - address instance = this.deployERC1967IBeaconProxy(_beacon()); - LibCloneTest(instance).setValue(value_); - gasBudget = _randomChance(2) ? gasBudget % 3000 : gasBudget % 30000; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, value_) - let hash := keccak256(0x00, 0x40) - mstore(0x20, hash) - mstore(0x00, 0x3fa4f245) // `value()`. - switch staticcall(gasBudget, instance, 0x1c, 0x04, 0x20, 0x20) - case 0 { if iszero(eq(mload(0x20), hash)) { invalid() } } - default { if iszero(eq(mload(0x20), value_)) { invalid() } } - - mstore(0x20, hash) - mstore(0x00, 0x57eca1a5) // `revertWithError()`. - switch staticcall(gasBudget, instance, 0x1c, 0x04, 0x20, 0x20) - case 0 { - if iszero(or(iszero(returndatasize()), eq(returndatasize(), 0x24))) { invalid() } - } - default { invalid() } - } - } - - function _randomBytesForERC1967BeconProxyImmutableArgs() - internal - returns (bytes memory result) - { - return _truncateBytes(_randomBytes(), _ERC1967_BEACON_PROXY_ARGS_MAX_LENGTH); - } - - function _randomBytesForERC1967IBeconProxyImmutableArgs() - internal - returns (bytes memory result) - { - return _truncateBytes(_randomBytes(), _ERC1967I_BEACON_PROXY_ARGS_MAX_LENGTH); - } - - function _randomBytesForERC1967ImmutableArgs() internal returns (bytes memory result) { - return _truncateBytes(_randomBytes(), _ERC1967_ARGS_MAX_LENGTH); - } - - function _randomBytesForERC1967IImmutableArgs() internal returns (bytes memory result) { - return _truncateBytes(_randomBytes(), _ERC1967I_ARGS_MAX_LENGTH); - } - - function _randomBytesForCloneImmutableArgs() internal returns (bytes memory result) { - return _truncateBytes(_randomBytes(), _CLONES_ARGS_MAX_LENGTH); - } - - function _checkArgsOnERC1967BeaconProxy(address instance, bytes memory args) internal { - _maybeBrutalizeMemory(); - bytes memory retrievedArgs = LibClone.argsOnERC1967BeaconProxy(instance); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, args); - (uint256 start, uint256 end) = _randomStartAndEnd(args); - _maybeBrutalizeMemory(); - retrievedArgs = LibClone.argsOnERC1967BeaconProxy(instance, start, end); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start, end))); - retrievedArgs = LibClone.argsOnERC1967BeaconProxy(instance, start); - _maybeBrutalizeMemory(); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start))); - } - - function _checkArgsOnERC1967IBeaconProxy(address instance, bytes memory args) internal { - _maybeBrutalizeMemory(); - bytes memory retrievedArgs = LibClone.argsOnERC1967IBeaconProxy(instance); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, args); - (uint256 start, uint256 end) = _randomStartAndEnd(args); - _maybeBrutalizeMemory(); - retrievedArgs = LibClone.argsOnERC1967IBeaconProxy(instance, start, end); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start, end))); - retrievedArgs = LibClone.argsOnERC1967IBeaconProxy(instance, start); - _maybeBrutalizeMemory(); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start))); - } - - function _checkArgsOnERC1967(address instance, bytes memory args) internal { - _maybeBrutalizeMemory(); - bytes memory retrievedArgs = LibClone.argsOnERC1967(instance); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, args); - assertEq( - instance.code, - abi.encodePacked( - hex"363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3", - args - ) - ); - (uint256 start, uint256 end) = _randomStartAndEnd(args); - _maybeBrutalizeMemory(); - retrievedArgs = LibClone.argsOnERC1967(instance, start, end); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start, end))); - retrievedArgs = LibClone.argsOnERC1967(instance, start); - _maybeBrutalizeMemory(); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start))); - } - - function _checkArgsOnERC1967I(address instance, bytes memory args) internal { - _maybeBrutalizeMemory(); - bytes memory retrievedArgs = LibClone.argsOnERC1967I(instance); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, args); - assertEq( - instance.code, - abi.encodePacked( - hex"365814604357363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3", - args - ) - ); - (uint256 start, uint256 end) = _randomStartAndEnd(args); - _maybeBrutalizeMemory(); - retrievedArgs = LibClone.argsOnERC1967I(instance, start, end); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start, end))); - retrievedArgs = LibClone.argsOnERC1967I(instance, start); - _maybeBrutalizeMemory(); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start))); - } - - function _checkArgsOnClone(address instance, bytes memory args) internal { - _maybeBrutalizeMemory(); - bytes memory retrievedArgs = LibClone.argsOnClone(instance); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, args); - assertEq( - instance.code, - abi.encodePacked( - hex"363d3d373d3d3d363d73", address(this), hex"5af43d82803e903d91602b57fd5bf3", args - ) - ); - (uint256 start, uint256 end) = _randomStartAndEnd(args); - retrievedArgs = LibClone.argsOnClone(instance, start, end); - _maybeBrutalizeMemory(); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start, end))); - retrievedArgs = LibClone.argsOnClone(instance, start); - _maybeBrutalizeMemory(); - _checkMemory(retrievedArgs); - assertEq(retrievedArgs, bytes(LibString.slice(string(args), start))); - } - - function _randomStartAndEnd(bytes memory args) internal returns (uint256 start, uint256 end) { - unchecked { - if (_randomChance(2)) { - uint256 n = args.length + 2; - start = _bound(_random(), 0, n); - end = _bound(_random(), 0, n); - } else { - start = _random(); - end = _random(); - } - } - } - - function _checkERC1967ImplementationSlot(address instance) internal { - _checkERC1967ImplementationSlot(instance, address(this)); - } - - function _checkERC1967ImplementationSlot(address instance, address expected) internal { - assertEq( - vm.load(instance, _ERC1967_IMPLEMENTATION_SLOT), bytes32(uint256(uint160(expected))) - ); - } - - function _checkERC1967BeaconSlot(address instance, address expected) internal { - assertEq(vm.load(instance, _ERC1967_BEACON_SLOT), bytes32(uint256(uint160(expected)))); - } - - function _checkERC1967ISpecialPath(address instance, address expected) internal { - (, bytes memory returnData) = instance.call("c"); - assertEq(abi.decode(returnData, (address)), expected); - } - - function clone(address implementation) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.clone(_brutalized(implementation)); - } - - function clone(address implementation, bytes memory args) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.clone(_brutalized(implementation), args); - } - - function cloneDeterministic(address implementation, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.cloneDeterministic(_brutalized(implementation), salt); - address predicted = - LibClone.predictDeterministicAddress(implementation, salt, address(this)); - assertEq(instance, predicted); - } - - function cloneDeterministic(address implementation, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.cloneDeterministic(_brutalized(implementation), args, salt); - address predicted = - LibClone.predictDeterministicAddress(implementation, args, salt, address(this)); - assertEq(instance, predicted); - } - - function createDeterministicClone(address implementation, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = - LibClone.predictDeterministicAddress(implementation, args, salt, address(this)); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicClone(_brutalized(implementation), args, salt); - assertEq(alreadyDeployed, deployed); - assertEq(instance, predicted); - } - - function createDeterministicERC1967(address implementation, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = - LibClone.predictDeterministicAddressERC1967(implementation, salt, address(this)); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967(_brutalized(implementation), salt); - assertEq(alreadyDeployed, deployed); - assertEq(instance, predicted); - } - - function createDeterministicERC1967(address implementation, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = - LibClone.predictDeterministicAddressERC1967(implementation, args, salt, address(this)); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967(_brutalized(implementation), args, salt); - assertEq(alreadyDeployed, deployed); - assertEq(instance, predicted); - } - - function createDeterministicERC1967I(address implementation, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = - LibClone.predictDeterministicAddressERC1967I(implementation, salt, address(this)); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967I(_brutalized(implementation), salt); - assertEq(alreadyDeployed, deployed); - assertEq(instance, predicted); - } - - function createDeterministicERC1967I(address implementation, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = - LibClone.predictDeterministicAddressERC1967I(implementation, args, salt, address(this)); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967I(_brutalized(implementation), args, salt); - assertEq(alreadyDeployed, deployed); - assertEq(instance, predicted); - } - - function deployERC1967(address implementation, bytes calldata args) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployERC1967(_brutalized(implementation), args); - } - - function deployDeterministicERC1967(address implementation, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967(_brutalized(implementation), salt); - address predicted = - LibClone.predictDeterministicAddressERC1967(implementation, salt, address(this)); - assertEq(instance, predicted); - } - - function deployERC1967I(address implementation) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployERC1967I(_brutalized(implementation)); - } - - function deployERC1967I(address implementation, bytes memory args) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployERC1967I(_brutalized(implementation), args); - } - - function deployDeterministicERC1967I(address implementation, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967I(_brutalized(implementation), salt); - address predicted = - LibClone.predictDeterministicAddressERC1967I(implementation, salt, address(this)); - assertEq(instance, predicted); - } - - function deployDeterministicERC1967I(address implementation, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967I(_brutalized(implementation), args, salt); - address predicted = - LibClone.predictDeterministicAddressERC1967I(implementation, args, salt, address(this)); - assertEq(instance, predicted); - } - - function deployDeterministicERC1967(address implementation, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967(_brutalized(implementation), args, salt); - address predicted = - LibClone.predictDeterministicAddressERC1967(implementation, args, salt, address(this)); - assertEq(instance, predicted); - } - - function deployERC1967BeaconProxy(address beacon) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployERC1967BeaconProxy(_brutalized(beacon)); - } - - function deployERC1967IBeaconProxy(address beacon) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployERC1967IBeaconProxy(_brutalized(beacon)); - } - - function deployDeterministicERC1967BeaconProxy(address beacon, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967BeaconProxy(_brutalized(beacon), salt); - address predicted = - LibClone.predictDeterministicAddressERC1967BeaconProxy(beacon, salt, address(this)); - assertEq(instance, predicted); - } - - function deployDeterministicERC1967IBeaconProxy(address beacon, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967IBeaconProxy(_brutalized(beacon), salt); - address predicted = - LibClone.predictDeterministicAddressERC1967IBeaconProxy(beacon, salt, address(this)); - assertEq(instance, predicted); - } - - function deployDeterministicERC1967IBeaconProxy(address beacon, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967IBeaconProxy(_brutalized(beacon), args, salt); - address predicted = LibClone.predictDeterministicAddressERC1967IBeaconProxy( - beacon, args, salt, address(this) - ); - assertEq(instance, predicted); - } - - function createDeterministicERC1967BeaconProxy(address beacon, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = - LibClone.predictDeterministicAddressERC1967BeaconProxy(beacon, salt, address(this)); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967BeaconProxy(_brutalized(beacon), salt); - assertEq(deployed, alreadyDeployed); - assertEq(instance, predicted); - } - - function createDeterministicERC1967IBeaconProxy(address beacon, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = - LibClone.predictDeterministicAddressERC1967IBeaconProxy(beacon, salt, address(this)); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967IBeaconProxy(_brutalized(beacon), salt); - assertEq(deployed, alreadyDeployed); - assertEq(instance, predicted); - } - - function deployERC1967BeaconProxy(address beacon, bytes memory args) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployERC1967BeaconProxy(_brutalized(beacon), args); - } - - function deployERC1967IBeaconProxy(address beacon, bytes memory args) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployERC1967IBeaconProxy(_brutalized(beacon), args); - } - - function deployDeterministicERC1967BeaconProxy(address beacon, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - instance = LibClone.deployDeterministicERC1967BeaconProxy(_brutalized(beacon), args, salt); - address predicted = LibClone.predictDeterministicAddressERC1967BeaconProxy( - beacon, args, salt, address(this) - ); - assertEq(instance, predicted); - } - - function createDeterministicERC1967BeaconProxy(address beacon, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = LibClone.predictDeterministicAddressERC1967BeaconProxy( - beacon, args, salt, address(this) - ); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967BeaconProxy(_brutalized(beacon), args, salt); - assertEq(deployed, alreadyDeployed); - assertEq(instance, predicted); - } - - function createDeterministicERC1967IBeaconProxy(address beacon, bytes memory args, bytes32 salt) - external - maybeBrutalizeMemory - returns (address instance) - { - address predicted = LibClone.predictDeterministicAddressERC1967IBeaconProxy( - beacon, args, salt, address(this) - ); - bool alreadyDeployed = predicted.code.length != 0; - bool deployed; - (deployed, instance) = - LibClone.createDeterministicERC1967IBeaconProxy(_brutalized(beacon), args, salt); - assertEq(deployed, alreadyDeployed); - assertEq(instance, predicted); - } - - modifier maybeBrutalizeMemory() { - _maybeBrutalizeMemory(); - _; - _checkMemory(); - } - - function _maybeBrutalizeMemory() internal { - if (_randomChance(2)) _misalignFreeMemoryPointer(); - if (_randomChance(16)) _brutalizeMemory(); - } -} diff --git a/grouperBot/lib/solady/test/LibERC6551.t.sol b/grouperBot/lib/solady/test/LibERC6551.t.sol deleted file mode 100644 index 05ad566..0000000 --- a/grouperBot/lib/solady/test/LibERC6551.t.sol +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibERC6551} from "../src/accounts/LibERC6551.sol"; - -interface IERC6551Registry { - event ERC6551AccountCreated( - address account, - address indexed implementation, - bytes32 salt, - uint256 chainId, - address indexed tokenContract, - uint256 indexed tokenId - ); - - error AccountCreationFailed(); - - function createAccount( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) external returns (address account); - - function account( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) external view returns (address account); -} - -contract LibERC6551Test is SoladyTest { - function setUp() public { - vm.etch(LibERC6551.REGISTRY, LibERC6551.REGISTRY_BYTECODE); - } - - function testInitCodeHash( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) public { - bytes memory initCode = - LibERC6551.initCode(implementation, salt, chainId, tokenContract, tokenId); - if (_randomChance(8)) _brutalizeMemory(); - bytes32 initCodeHash = - LibERC6551.initCodeHash(implementation, salt, chainId, tokenContract, tokenId); - if (_randomChance(8)) _brutalizeMemory(); - assertEq(initCodeHash, keccak256(initCode)); - } - - function testComputeAccountAddress( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) public { - IERC6551Registry registry = IERC6551Registry(LibERC6551.REGISTRY); - address a = registry.account( - _brutalized(implementation), salt, chainId, _brutalized(tokenContract), tokenId - ); - if (_randomChance(8)) _brutalizeMemory(); - if (_randomChance(8)) { - address deployed = _createAccount( - _brutalized(implementation), salt, chainId, _brutalized(tokenContract), tokenId - ); - assertEq(deployed, a); - } - if (_randomChance(8)) _brutalizeMemory(); - address computed = LibERC6551.account( - _brutalized(implementation), salt, chainId, _brutalized(tokenContract), tokenId - ); - assertEq(computed, a); - _checkMemory(); - } - - function testIsERC6551Account( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) public { - if (_randomChance(8)) implementation = address(this); - - address a = _account(implementation, salt, chainId, tokenContract, tokenId); - assertEq(LibERC6551.isERC6551Account(_brutalized(a), _brutalized(implementation)), false); - - _createAccount(implementation, salt, chainId, tokenContract, tokenId); - assertEq(_createAccount(implementation, salt, chainId, tokenContract, tokenId), a); - - assertEq(LibERC6551.implementation(_brutalized(a)), _brutalized(implementation)); - assertEq( - LibERC6551.isERC6551Account(_brutalized(a), _brutalized(implementation)), - implementation.code.length != 0 - ); - _checkMemory(); - - /// @solidity memory-safe-assembly - assembly { - implementation := xor(1, implementation) - } - assertEq(LibERC6551.isERC6551Account(_brutalized(a), _brutalized(implementation)), false); - _checkMemory(); - } - - function _account( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) internal returns (address) { - if (_randomChance(2)) { - return LibERC6551.account( - _brutalized(implementation), salt, chainId, _brutalized(tokenContract), tokenId - ); - } else { - IERC6551Registry registry = IERC6551Registry(LibERC6551.REGISTRY); - return registry.account( - _brutalized(implementation), salt, chainId, _brutalized(tokenContract), tokenId - ); - } - } - - function _createAccount( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) internal returns (address) { - if (_randomChance(2)) { - return LibERC6551.createAccount( - _brutalized(implementation), salt, chainId, _brutalized(tokenContract), tokenId - ); - } else { - IERC6551Registry registry = IERC6551Registry(LibERC6551.REGISTRY); - return registry.createAccount( - _brutalized(implementation), salt, chainId, _brutalized(tokenContract), tokenId - ); - } - } - - struct _TestTemps { - bytes32 salt; - uint256 chainId; - address tokenContract; - uint256 tokenId; - } - - function testContext( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) public { - address a = _createAccount(implementation, salt, chainId, tokenContract, tokenId); - assertEq(LibERC6551.salt(_brutalized(a)), salt); - assertEq(LibERC6551.chainId(_brutalized(a)), chainId); - assertEq(LibERC6551.tokenContract(_brutalized(a)), tokenContract); - assertEq(LibERC6551.tokenId(_brutalized(a)), tokenId); - _checkMemory(); - - assertEq(LibERC6551.implementation(a), implementation); - _checkMemory(); - - _TestTemps memory t; - (t.salt, t.chainId, t.tokenContract, t.tokenId) = LibERC6551.context(a); - assertEq(t.chainId, chainId); - assertEq(t.salt, salt); - assertEq(t.tokenContract, tokenContract); - assertEq(t.tokenId, tokenId); - _checkMemory(); - } -} diff --git a/grouperBot/lib/solady/test/LibERC7579.t.sol b/grouperBot/lib/solady/test/LibERC7579.t.sol deleted file mode 100644 index 2f70702..0000000 --- a/grouperBot/lib/solady/test/LibERC7579.t.sol +++ /dev/null @@ -1,360 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibERC7579} from "../src/accounts/LibERC7579.sol"; - -contract LibERC7579Test is SoladyTest { - function testEncodeAndDecodeMode(bytes32) public { - bytes1 callType = bytes1(bytes32(_randomUniform())); - bytes1 execType = bytes1(bytes32(_randomUniform())); - bytes4 selector = bytes4(bytes32(_randomUniform())); - bytes22 payload = bytes22(bytes32(_randomUniform())); - bytes32 mode = LibERC7579.encodeMode(callType, execType, selector, payload); - assertEq(LibERC7579.getCallType(mode), callType); - assertEq(LibERC7579.getExecType(mode), execType); - assertEq(LibERC7579.getSelector(mode), selector); - assertEq(LibERC7579.getPayload(mode), payload); - for (uint256 i = 2; i < 2 + 4; ++i) { - assertEq(bytes1(mode[i]), 0); - } - } - - function testEncodeAndDecodeMode() public { - bytes32 mode = LibERC7579.encodeMode( - 0x01, 0x00, 0x11223344, 0xffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb - ); - assertEq(mode, 0x01000000000011223344ffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb); - } - - struct Call { - address target; - uint256 value; - bytes data; - } - - struct _TestTemps { - address target; - uint256 value; - bytes data; - Call[] calls; - bytes opData; - } - - function testDecodeSingle(address target, uint256 value, bytes memory data) public { - bytes memory executionData = abi.encodePacked(target, value, data); - _TestTemps memory t; - (t.target, t.value, t.data) = this.decodeSingle(executionData); - assertEq(t.target, target); - assertEq(t.value, value); - assertEq(t.data, data); - } - - function decodeSingle(bytes calldata executionData) - public - pure - returns (address, uint256, bytes memory) - { - return LibERC7579.decodeSingle(executionData); - } - - function testDecodeDelegate(address target, bytes memory data) public { - bytes memory executionData = abi.encodePacked(target, data); - _TestTemps memory t; - (t.target, t.data) = this.decodeDelegate(executionData); - assertEq(t.target, target); - assertEq(t.data, data); - } - - function decodeDelegate(bytes calldata executionData) - public - pure - returns (address, bytes memory) - { - return LibERC7579.decodeDelegate(executionData); - } - - function testReencodeBatchAsExecuteCalldata(bytes32 mode) public { - Call[] memory calls = new Call[](_randomUniform() & 3); - for (uint256 i; i != calls.length; ++i) { - Call memory c = calls[i]; - c.target = address(uint160(_randomUniform())); - c.value = _random(); - c.data = _truncateBytes(_randomBytes(), 0x1ff); - } - bytes memory executionData; - if (_randomChance(2)) { - executionData = abi.encode(calls); - } else { - executionData = abi.encode(calls, _truncateBytes(_randomBytes(), 0xff)); - } - this.subTestReencodeBatchAsExecuteCalldata(mode, executionData); - } - - function subTestReencodeBatchAsExecuteCalldata(bytes32 mode, bytes calldata executionData) - public - { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - bytes memory opData = _truncateBytes(_randomBytes(), 0x1ff); - bytes memory t = LibERC7579.reencodeBatch(executionData, opData); - _checkMemory(t); - bytes memory computed = - LibERC7579.reencodeBatchAsExecuteCalldata(mode, executionData, opData); - _checkMemory(computed); - assertEq(computed, abi.encodeWithSignature("execute(bytes32,bytes)", mode, t)); - (bool success, bytes memory results) = address(this).call(computed); - assertEq(success, true); - assertEq(abi.decode(results, (bytes32)), keccak256(abi.encode(mode, keccak256(t)))); - } - - function execute(bytes32 mode, bytes calldata executionData) public pure returns (bytes32) { - return keccak256(abi.encode(mode, keccak256(executionData))); - } - - function testDecodeBatchAndOpData(bytes32) public { - Call[] memory calls = new Call[](_randomUniform() & 3); - bytes memory opData = _truncateBytes(_randomBytes(), 0x1ff); - for (uint256 i; i != calls.length; ++i) { - Call memory c = calls[i]; - c.target = address(uint160(_randomUniform())); - c.value = _random(); - c.data = _truncateBytes(_randomBytes(), 0x1ff); - } - _TestTemps memory t; - bool useOpData = _randomChance(2); - if (useOpData) { - (t.calls, t.opData) = this.decodeBatchAndOpData(abi.encode(calls, opData)); - } else { - bytes memory executionData; - if (_randomChance(2)) { - executionData = abi.encode(calls); - } else { - executionData = abi.encode(calls, opData); - } - if (_randomChance(2)) { - t.calls = this.decodeBatch(executionData); - } else { - (t.calls, t.opData) = this.decodeBatchAndOpData(executionData); - } - } - - assertEq(t.calls.length, calls.length); - for (uint256 i; i != calls.length; ++i) { - assertEq(t.calls[i].target, calls[i].target); - assertEq(t.calls[i].value, calls[i].value); - assertEq(t.calls[i].data, calls[i].data); - } - if (useOpData) { - assertEq(t.opData, opData); - } - - if (calls.length > 0 && _randomChance(8)) { - uint256 i = _bound(_randomUniform(), 0, calls.length - 1); - (t.target, t.value, t.data) = this.decodeBatchAndGetExecution(abi.encode(calls), i); - assertEq(t.target, calls[i].target); - assertEq(t.value, calls[i].value); - assertEq(t.data, calls[i].data); - } - - if (_randomChance(2)) { - bytes memory executionData; - if (_randomChance(2)) { - executionData = abi.encode(calls); - } else { - executionData = abi.encode(calls, opData); - } - opData = _truncateBytes(_randomBytes(), 0x1ff); - (t.calls, t.opData) = this.reencodeBatchAndDecodeBatch(executionData, opData); - for (uint256 i; i != calls.length; ++i) { - assertEq(t.calls[i].target, calls[i].target); - assertEq(t.calls[i].value, calls[i].value); - assertEq(t.calls[i].data, calls[i].data); - } - assertEq(t.opData, opData); - } - } - - function reencodeBatchAndDecodeBatch(bytes calldata executionData, bytes memory opData) - public - returns (Call[] memory, bytes memory) - { - bytes memory reencoded; - if (_randomChance(2)) { - reencoded = LibERC7579.reencodeBatch(executionData, opData); - } else { - reencoded = abi.encode(abi.decode(executionData, (Call[])), opData); - } - _checkMemory(reencoded); - if (_randomChance(2)) { - return this.decodeBatchAndOpData(reencoded); - } else { - return abi.decode(reencoded, (Call[], bytes)); - } - } - - function decodeBatch(bytes calldata executionData) public pure returns (Call[] memory) { - Call[] calldata calls; - bytes32[] calldata pointers = LibERC7579.decodeBatch(executionData); - /// @solidity memory-safe-assembly - assembly { - calls.offset := pointers.offset - calls.length := pointers.length - } - return calls; - } - - function decodeBatchAndOpData(bytes calldata executionData) - public - pure - returns (Call[] memory, bytes memory) - { - Call[] calldata calls; - (bytes32[] calldata pointers, bytes calldata opData) = - LibERC7579.decodeBatchAndOpData(executionData); - /// @solidity memory-safe-assembly - assembly { - calls.offset := pointers.offset - calls.length := pointers.length - } - return (calls, opData); - } - - struct S { - bytes executionData; - bytes garbage; - } - - function testDecodeBatchEdgeCase() public { - /* - Calldata is as follows when S is passed to a function: - - 9988592b (function selector) - 0000000000000000000000000000000000000000000000000000000000000020 (offset of s) - 0000000000000000000000000000000000000000000000000000000000000040 (offset of s.executionData) - 0000000000000000000000000000000000000000000000000000000000000080 (offset of s.garbage) - 0000000000000000000000000000000000000000000000000000000000000020 (s.executionData.length) - 0000000000000000000000000000000000000000000000000000000000000040 (s.executionData) - 0000000000000000000000000000000000000000000000000000000000000020 (s.garbage.length) - 0000000000000000000000000000000000000000000000000000000000000000 (s.garbage) - */ - S memory s = S({executionData: abi.encode(uint256(0x40)), garbage: abi.encode(uint256(0))}); - - vm.expectRevert(LibERC7579.DecodingError.selector); - this.decodeBatch(s); - - vm.expectRevert(); - this.abiDecodeBatch(s); - } - - function decodeBatch(S calldata s) public pure returns (uint256) { - bytes32[] calldata pointers = LibERC7579.decodeBatch(s.executionData); - return pointers.length; - } - - function testDecodeBatchEdgeCase2() public { - (bool success,) = address(this).call( - abi.encodePacked( - bytes4(keccak256("propose2(bytes32,bytes,uint256)")), - hex"0100000000007821000100000000000000000000000000000000000000000000", - hex"0000000000000000000000000000000000000000000000000000000000000060", // offset to executionData - _randomUniform(), - uint256(32 * 5), // length of executionData (THIS SHOULD ACTUALLY BE 32 * 6 BUT WE REDUCE TO 32 * 5) - hex"0000000000000000000000000000000000000000000000000000000000000020", // offset to pointers array - hex"0000000000000000000000000000000000000000000000000000000000000004", // pointers array length - hex"0000000000000000000000000000000000000000000000000000000000000000", // offset to pointers[0] - hex"0000000000000000000000000000000000000000000000000000000000000000", // offset to pointers[1] - hex"0000000000000000000000000000000000000000000000000000000000000000", // offset to pointers[2] - hex"0000000000000000000000000000000000000000000000000000000000000000" // offset to pointers[3] - ) - ); - assertFalse(success); - } - - function propose2(bytes32, bytes calldata executionData, uint256) - public - pure - returns (uint256) - { - bytes32[] memory pointers = LibERC7579.decodeBatch(executionData); - return pointers.length; - } - - function abiDecodeBatch(S calldata s) public pure returns (uint256) { - Call[] memory pointers = abi.decode(s.executionData, (Call[])); - return pointers.length; - } - - function testDecodeBatchAndOpDataReverts(bytes32) public { - bytes memory opData = hex"3232323232323232323232323232323232323232323232323232323232323232"; - Call[] memory calls = new Call[](1); - calls[0].target = address(this); - calls[0].value = 1 ether; - calls[0].data = hex"5656565656565656565656565656565656565656565656565656565656565656"; - bytes memory executionData = abi.encode(calls, opData); - if (_randomChance(128)) { - // Check that it works. - this.decodeBatchAndOpData(executionData); - } - // 0000000000000000000000000000000000000000000000000000000000000040 : 0x20 - // 0000000000000000000000000000000000000000000000000000000000000120 : 0x40 - // 0000000000000000000000000000000000000000000000000000000000000001 : 0x60 - // 0000000000000000000000000000000000000000000000000000000000000020 : 0x80 - // 0000000000000000000000007fa9385be102ac3eac297483dd6233d62b3e1496 : 0xa0 - // 0000000000000000000000000000000000000000000000000de0b6b3a7640000 : 0xc0 - // 0000000000000000000000000000000000000000000000000000000000000060 : 0xe0 - // 0000000000000000000000000000000000000000000000000000000000000020 : 0x100 - // 5656565656565656565656565656565656565656565656565656565656565656 : 0x120 - // 0000000000000000000000000000000000000000000000000000000000000020 : 0x140 - // 3232323232323232323232323232323232323232323232323232323232323232 : 0x160 - - if (_randomChance(4)) { - _testDecodeBatchAndOpDataRevert(executionData, 0x20, 0x140); - } - if (_randomChance(4)) { - _testDecodeBatchAndOpDataRevert(executionData, 0x60, 0x02); - } - if (_randomChance(4)) { - _testDecodeBatchAndOpDataRevert(executionData, 0x40, 0x140); - } - if (_randomChance(4)) { - _testDecodeBatchAndOpDataRevert(executionData, 0x140, 0x21); - } - if (_randomChance(4)) { - _testDecodeBatchAndOpDataRevert(executionData, 0x100, 0x61); - } - if (_randomChance(4)) { - _testDecodeBatchAndOpDataRevert(executionData, 0x80, 0x1c0); - } - } - - function _testDecodeBatchAndOpDataRevert( - bytes memory executionData, - uint256 o, - uint256 startingFrom - ) internal { - uint256 r = _randomLengthOrOffset(startingFrom); - bytes memory cd = abi.encodeWithSignature("decodeBatchAndOpData(bytes)", executionData); - /// @solidity memory-safe-assembly - assembly { - mstore(add(o, add(cd, 0x44)), r) - } - (bool success,) = address(this).staticcall(cd); - assertFalse(success); - } - - function _randomLengthOrOffset(uint256 startingFrom) internal returns (uint256) { - if (_randomChance(2)) { - return _bound(_random(), startingFrom, startingFrom + 0x1ff); - } - return _bound(_random(), startingFrom, type(uint256).max); - } - - function decodeBatchAndGetExecution(bytes calldata executionData, uint256 i) - public - pure - returns (address, uint256, bytes memory) - { - return LibERC7579.getExecution(LibERC7579.decodeBatch(executionData), i); - } -} diff --git a/grouperBot/lib/solady/test/LibMap.t.sol b/grouperBot/lib/solady/test/LibMap.t.sol deleted file mode 100644 index e7022a6..0000000 --- a/grouperBot/lib/solady/test/LibMap.t.sol +++ /dev/null @@ -1,649 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibMap} from "../src/utils/LibMap.sol"; - -contract LibMapTest is SoladyTest { - using LibMap for *; - - uint8[0xffffffffffffffff] bigUint8ArrayMap; - - LibMap.Uint8Map[2] uint8s; - - LibMap.Uint16Map[2] uint16s; - - LibMap.Uint32Map[2] uint32s; - - LibMap.Uint40Map[2] uint40s; - - LibMap.Uint64Map[2] uint64s; - - LibMap.Uint128Map[2] uint128s; - - mapping(uint256 => LibMap.Uint32Map) uint32Maps; - - mapping(uint256 => mapping(uint256 => uint256)) generalMaps; - - mapping(uint256 => uint256) filled; - - struct _TestTemps { - uint256 i0; - uint256 i1; - uint256 v0; - uint256 v1; - } - - function _testTemps() internal returns (_TestTemps memory t) { - uint256 r = _random(); - t.i0 = (r >> 8) & 31; - t.i1 = (r >> 16) & 31; - t.v0 = _random(); - t.v1 = _random(); - } - - function getUint8(uint256 index) public view returns (uint8 result) { - result = uint8s[0].get(index); - } - - function setUint8(uint256 index, uint8 value) public { - uint8s[0].set(index, value); - } - - function getUint8FromBigArray(uint256 index) public view returns (uint8 result) { - result = bigUint8ArrayMap[index]; - } - - function setUint8FromBigArray(uint256 index, uint8 value) public { - bigUint8ArrayMap[index] = value; - } - - function testMapSetUint8() public { - this.setUint8(111111, 123); - } - - function testMapGetUint8() public { - assertEq(this.getUint8(222222), uint8(0)); - } - - function testMapSetUint8FromBigArray() public { - this.setUint8FromBigArray(111111, 123); - } - - function testMapGetFromBigArray() public { - assertEq(this.getUint8FromBigArray(222222), uint8(0)); - } - - function testUint8MapSetAndGet(uint256) public { - uint8 u = uint8(_random()); - uint8s[0].set(0, u); - assertEq(uint8s[0].map[0], u); - unchecked { - for (uint256 t; t < 8; ++t) { - uint256 r = _random(); - uint8 casted; - /// @solidity memory-safe-assembly - assembly { - casted := r - } - uint256 index = _random() % 32; - uint8s[0].set(index, casted); - assertEq(uint8s[0].get(index), casted); - } - } - } - - function testUint8MapSetAndGet() public { - unchecked { - for (uint256 t; t < 16; ++t) { - uint256 n = 64; - uint8 casted; - uint256 r = _random(); - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - uint8s[0].set(i, casted); - } - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - assertEq(uint8s[0].get(i), casted); - } - } - } - } - - function testUint8MapSetAndGet2(uint256) public { - _TestTemps memory t = _testTemps(); - uint8s[0].set(t.i0, uint8(t.v0)); - uint8s[1].set(t.i1, uint8(t.v1)); - assertEq(uint8s[0].get(t.i0), uint8(t.v0)); - assertEq(uint8s[1].get(t.i1), uint8(t.v1)); - } - - function testUint16MapSetAndGet(uint256) public { - uint16 u = uint16(_random()); - uint16s[0].set(0, u); - assertEq(uint16s[0].map[0], u); - unchecked { - for (uint256 t; t < 8; ++t) { - uint256 r = _random(); - uint16 casted; - /// @solidity memory-safe-assembly - assembly { - casted := r - } - uint256 index = _random() % 32; - uint16s[0].set(index, casted); - assertEq(uint16s[0].get(index), casted); - } - } - } - - function testUint16MapSetAndGet() public { - unchecked { - for (uint256 t; t < 16; ++t) { - uint256 n = 64; - uint16 casted; - uint256 r = _random(); - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - uint16s[0].set(i, casted); - } - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - assertEq(uint16s[0].get(i), casted); - } - } - } - } - - function testUint16MapSetAndGet2(uint256) public { - _TestTemps memory t = _testTemps(); - uint16s[0].set(t.i0, uint16(t.v0)); - uint16s[1].set(t.i1, uint16(t.v1)); - assertEq(uint16s[0].get(t.i0), uint16(t.v0)); - assertEq(uint16s[1].get(t.i1), uint16(t.v1)); - } - - function testUint32MapSetAndGet(uint256) public { - uint32 u = uint32(_random()); - uint32s[0].set(0, u); - assertEq(uint32s[0].map[0], u); - unchecked { - for (uint256 t; t < 8; ++t) { - uint256 r = _random(); - uint32 casted; - /// @solidity memory-safe-assembly - assembly { - casted := r - } - uint256 index = _random() % 32; - uint32s[0].set(index, casted); - assertEq(uint32s[0].get(index), casted); - } - } - } - - function testUint32MapSetAndGet() public { - unchecked { - for (uint256 t; t < 16; ++t) { - uint256 n = 64; - uint32 casted; - uint256 r = _random(); - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - uint32s[0].set(i, casted); - } - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - assertEq(uint32s[0].get(i), casted); - } - } - } - } - - function testUint32MapSetAndGet2(uint256) public { - _TestTemps memory t = _testTemps(); - uint32s[0].set(t.i0, uint32(t.v0)); - uint32s[1].set(t.i1, uint32(t.v1)); - assertEq(uint32s[0].get(t.i0), uint32(t.v0)); - assertEq(uint32s[1].get(t.i1), uint32(t.v1)); - } - - function testUint40MapSetAndGet(uint256) public { - uint40 u = uint40(_random()); - uint40s[0].set(0, u); - assertEq(uint40s[0].map[0], u); - unchecked { - for (uint256 t; t < 8; ++t) { - uint256 r = _random(); - uint40 casted; - /// @solidity memory-safe-assembly - assembly { - casted := r - } - uint256 index = _random() % 32; - uint40s[0].set(index, casted); - assertEq(uint40s[0].get(index), casted); - } - } - } - - function testUint40MapSetAndGet() public { - unchecked { - for (uint256 t; t < 16; ++t) { - uint256 n = 64; - uint40 casted; - uint256 r = _random(); - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - uint40s[0].set(i, casted); - } - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - assertEq(uint40s[0].get(i), casted); - } - } - } - } - - function testUint40MapSetAndGet2(uint256) public { - _TestTemps memory t = _testTemps(); - uint40s[0].set(t.i0, uint40(t.v0)); - uint40s[1].set(t.i1, uint40(t.v1)); - assertEq(uint40s[0].get(t.i0), uint40(t.v0)); - assertEq(uint40s[1].get(t.i1), uint40(t.v1)); - } - - function testUint64MapSetAndGet(uint256) public { - uint64 u = uint64(_random()); - uint64s[0].set(0, u); - assertEq(uint64s[0].map[0], u); - unchecked { - for (uint256 t; t < 8; ++t) { - uint256 r = _random(); - uint64 casted; - /// @solidity memory-safe-assembly - assembly { - casted := r - } - uint256 index = _random() % 32; - uint64s[0].set(index, casted); - assertEq(uint64s[0].get(index), casted); - } - } - } - - function testUint64MapSetAndGet() public { - unchecked { - for (uint256 t; t < 16; ++t) { - uint256 n = 64; - uint64 casted; - uint256 r = _random(); - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - uint64s[0].set(i, casted); - } - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - assertEq(uint64s[0].get(i), casted); - } - } - } - } - - function testUint64MapSetAndGet2(uint256) public { - _TestTemps memory t = _testTemps(); - uint64s[0].set(t.i0, uint64(t.v0)); - uint64s[1].set(t.i1, uint64(t.v1)); - assertEq(uint64s[0].get(t.i0), uint64(t.v0)); - assertEq(uint64s[1].get(t.i1), uint64(t.v1)); - } - - function testUint128MapSetAndGet(uint256) public { - uint128 u = uint128(_random()); - uint128s[0].set(0, u); - assertEq(uint128s[0].map[0], u); - unchecked { - for (uint256 t; t < 8; ++t) { - uint256 r = _random(); - uint128 casted; - /// @solidity memory-safe-assembly - assembly { - casted := r - } - uint256 index = _random() % 32; - uint128s[0].set(index, casted); - assertEq(uint128s[0].get(index), casted); - } - } - } - - function testUint128MapSetAndGet() public { - unchecked { - for (uint256 t; t < 16; ++t) { - uint256 n = 64; - uint128 casted; - uint256 r = _random(); - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - uint128s[0].set(i, casted); - } - for (uint256 i; i < n; ++i) { - /// @solidity memory-safe-assembly - assembly { - casted := or(add(mul(n, t), i), r) - } - assertEq(uint128s[0].get(i), casted); - } - } - } - } - - function testUint128MapSetAndGet2(uint256) public { - _TestTemps memory t = _testTemps(); - uint128s[0].set(t.i0, uint128(t.v0)); - uint128s[1].set(t.i1, uint128(t.v1)); - assertEq(uint128s[0].get(t.i0), uint128(t.v0)); - assertEq(uint128s[1].get(t.i1), uint128(t.v1)); - } - - function testUint32Maps(uint256) public { - unchecked { - uint256 a0 = _random(); - uint256 a1 = _randomChance(2) ? a0 + _random() % 4 : a0 - _random() % 4; - uint256 b0 = _random(); - uint256 b1 = _randomChance(2) ? b0 + _random() % 4 : b0 - _random() % 4; - if (a0 == a1 && b1 == b0) { - if (_randomChance(2)) { - if (_randomChance(2)) b1++; - else a0++; - } else { - if (_randomChance(2)) b1--; - else a0--; - } - } - uint256 c0 = _random(); - uint256 c1 = _random(); - uint32 c0Casted; - uint32 c1Casted; - /// @solidity memory-safe-assembly - assembly { - c0Casted := c0 - c1Casted := c1 - } - assertEq(uint32Maps[a0].get(b0), 0); - assertEq(uint32Maps[a1].get(b1), 0); - uint32Maps[a0].set(b0, c0Casted); - uint32Maps[a1].set(b1, c1Casted); - assertEq(uint32Maps[a0].get(b0), uint32(c0)); - assertEq(uint32Maps[a1].get(b1), uint32(c1)); - } - } - - struct _SearchSortedTestVars { - uint256 o; - uint256 n; - uint256 end; - bool found; - uint256 index; - uint256 randomIndex; - uint256 randomIndexValue; - uint256[] values; - } - - function _searchSortedTestVars(mapping(uint256 => uint256) storage map, uint256 bitWidth) - internal - returns (_SearchSortedTestVars memory t) - { - unchecked { - t.n = 1 + _random() % 7 + (_randomChance(8) ? _random() % 64 : 0); - if (_randomChance(2)) { - t.o = type(uint256).max - t.n; - t.end = t.o + t.n; - assertEq(t.end, type(uint256).max); - } else { - t.o = _random() % 4 + (_randomChance(8) ? type(uint256).max - 256 : 0); - t.end = t.o + t.n; - } - uint256 v = _random() % 4; - uint256 b = (_random() % 2) * (_random() << 7); - uint256 valueMask = (1 << bitWidth) - 1; - for (uint256 i; i != t.n; ++i) { - map.set(t.o + i, b | v, bitWidth); - filled.set((b | v) & valueMask, 1, 1); - v += 1 + _random() % 2; - } - t.randomIndex = t.o + _random() % t.n; - t.randomIndexValue = map.get(t.randomIndex, bitWidth); - - if (t.o > 0) map.set(t.o - 1, _random(), bitWidth); - if (t.end < type(uint256).max) map.set(t.end, _random(), bitWidth); - - uint256 notFoundValue = _generateNotFoundValue(t.o); - - (t.found, t.index) = map.searchSorted(notFoundValue, t.o, t.end, bitWidth); - assertFalse(t.found); - assertEq(t.index, _nearestIndexBefore(map, notFoundValue, t.o, t.n, bitWidth)); - - uint256 end = t.o - (t.o > 0 ? _random() % t.o : 0); - (t.found, t.index) = map.searchSorted(t.randomIndexValue, t.o, end, bitWidth); - assertFalse(t.found); - assertEq(t.index, t.o); - - (t.found, t.index) = map.searchSorted(t.randomIndexValue, t.o, t.end, bitWidth); - assertTrue(t.found); - assertEq(t.index, t.randomIndex); - } - } - - function _generateNotFoundValue(uint256 o) internal returns (uint256 notFoundValue) { - unchecked { - uint256 max = 32; - do { - notFoundValue = o + _random() % max; - max += 8; - } while (filled.get(notFoundValue, 1) == 1); - } - } - - function _nearestIndexBefore( - mapping(uint256 => uint256) storage map, - uint256 x, - uint256 o, - uint256 n, - uint256 bitWidth - ) internal view returns (uint256 nearestIndex) { - unchecked { - nearestIndex = o; - uint256 nearestDist = type(uint256).max; - for (uint256 i; i != n; ++i) { - uint256 y = map.get(o + i, bitWidth); - if (y > x) continue; - uint256 dist = x - y; - if (dist < nearestDist) { - nearestIndex = o + i; - nearestDist = dist; - } - } - } - } - - function testUint8MapSearchSorted(uint256) public { - unchecked { - LibMap.Uint8Map storage m = uint8s[0]; - _SearchSortedTestVars memory t = _searchSortedTestVars(m.map, 8); - assertEq(m.get(t.randomIndex), t.randomIndexValue); - (bool found, uint256 index) = m.searchSorted(uint8(t.randomIndexValue), t.o, t.end); - assertTrue(found == t.found && index == t.index); - } - } - - function testUint16MapSearchSorted(uint256) public { - unchecked { - LibMap.Uint16Map storage m = uint16s[0]; - _SearchSortedTestVars memory t = _searchSortedTestVars(m.map, 16); - assertEq(m.get(t.randomIndex), t.randomIndexValue); - (bool found, uint256 index) = m.searchSorted(uint16(t.randomIndexValue), t.o, t.end); - assertTrue(found == t.found && index == t.index); - } - } - - function testUint32MapSearchSorted(uint256) public { - unchecked { - LibMap.Uint32Map storage m = uint32s[0]; - _SearchSortedTestVars memory t = _searchSortedTestVars(m.map, 32); - assertEq(m.get(t.randomIndex), t.randomIndexValue); - (bool found, uint256 index) = m.searchSorted(uint32(t.randomIndexValue), t.o, t.end); - assertTrue(found == t.found && index == t.index); - } - } - - function testUint40MapSearchSorted(uint256) public { - unchecked { - LibMap.Uint40Map storage m = uint40s[0]; - _SearchSortedTestVars memory t = _searchSortedTestVars(m.map, 40); - assertEq(m.get(t.randomIndex), t.randomIndexValue); - (bool found, uint256 index) = m.searchSorted(uint40(t.randomIndexValue), t.o, t.end); - assertTrue(found == t.found && index == t.index); - } - } - - function testUint64MapSearchSorted(uint256) public { - unchecked { - LibMap.Uint64Map storage m = uint64s[0]; - _SearchSortedTestVars memory t = _searchSortedTestVars(m.map, 64); - assertEq(m.get(t.randomIndex), t.randomIndexValue); - (bool found, uint256 index) = m.searchSorted(uint64(t.randomIndexValue), t.o, t.end); - assertTrue(found == t.found && index == t.index); - } - } - - function testUint128MapSearchSorted(uint256) public { - unchecked { - LibMap.Uint128Map storage m = uint128s[0]; - _SearchSortedTestVars memory t = _searchSortedTestVars(m.map, 128); - assertEq(m.get(t.randomIndex), t.randomIndexValue); - (bool found, uint256 index) = m.searchSorted(uint128(t.randomIndexValue), t.o, t.end); - assertTrue(found == t.found && index == t.index); - } - } - - function testGeneralMapSearchSorted(uint256) public { - unchecked { - mapping(uint256 => uint256) storage m = generalMaps[0]; - uint256 bitWidth = _bound(_random(), 8, 256); - _searchSortedTestVars(m, bitWidth); - } - } - - function testGeneralMapFunctionsWithSmallBitWidths(uint256) public { - unchecked { - uint256 bitWidth = 1 + _random() % 6; - uint256 valueMask = (1 << bitWidth) - 1; - uint256 o = _random() % 64 + (_randomChance(8) ? type(uint256).max - 256 : 0); - uint256 n = _random() % 9; - for (uint256 k; k != 2; ++k) { - for (uint256 i; i != n; ++i) { - uint256 j = o + i * 2; - generalMaps[k].set(j, _hash(j), bitWidth); - } - } - for (uint256 k; k != 2; ++k) { - for (uint256 i; i != n; ++i) { - uint256 j = o + i * 2 + 1; - generalMaps[k].set(j, _hash(j), bitWidth); - } - } - for (uint256 k; k != 2; ++k) { - for (uint256 i; i != n; ++i) { - uint256 j = o + i * 2; - assertEq(generalMaps[k].get(j, bitWidth), _hash(j) & valueMask); - j = j + 1; - assertEq(generalMaps[k].get(j, bitWidth), _hash(j) & valueMask); - } - } - } - } - - function _hash(uint256 x) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, x) - result := keccak256(0x00, 0x20) - } - } - - function testGeneralMapFunctionsWithZeroBitWidth() public { - unchecked { - mapping(uint256 => uint256) storage m = generalMaps[0]; - for (uint256 j; j < 3; ++j) { - for (uint256 i; i < 3; ++i) { - m.set(i, j + 1, 0); - assertEq(m.get(i, 0), 0); - (bool found, uint256 index) = m.searchSorted(i, j, j + 2, 0); - assertFalse(found); - assertEq(index, j); - } - } - } - } - - function testGeneralMapFunctionsGas() public { - unchecked { - mapping(uint256 => uint256) storage m = generalMaps[0]; - for (uint256 i; i != 1000; ++i) { - m.set(i, i + 1, 32); - assertEq(m.get(i, 32), i + 1); - } - for (uint256 j = 1; j < 900; j += 37) { - (bool found, uint256 index) = m.searchSorted(j, 0, 1000, 32); - assertTrue(found); - assertEq(index, j - 1); - } - } - } - - function testFoundStatementDifferential(uint256 t, uint256 needle, uint256 index) public { - bool a; - bool b; - /// @solidity memory-safe-assembly - assembly { - a := and(eq(t, needle), iszero(iszero(index))) - b := iszero(or(xor(t, needle), iszero(index))) - } - assertEq(a, b); - } -} diff --git a/grouperBot/lib/solady/test/LibPRNG.t.sol b/grouperBot/lib/solady/test/LibPRNG.t.sol deleted file mode 100644 index f737bb6..0000000 --- a/grouperBot/lib/solady/test/LibPRNG.t.sol +++ /dev/null @@ -1,623 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibPRNG} from "../src/utils/LibPRNG.sol"; -import {LibSort} from "../src/utils/LibSort.sol"; -import {FixedPointMathLib} from "../src/utils/FixedPointMathLib.sol"; - -library RunningStatsLib { - struct RunningStats { - int256 oldM; - int256 newM; - int256 oldS; - int256 newS; - int256 n; - } - - function clear(RunningStats memory rs) internal pure { - rs.n = 0; - } - - function push(RunningStats memory rs, int256 x) internal pure { - unchecked { - if (++rs.n == 1) { - rs.newM = x; - rs.oldM = x; - rs.oldS = 0; - } else { - int256 diff = (x - rs.oldM); - rs.newM = rs.oldM + diff / rs.n; - rs.newS = rs.oldS + diff * (x - rs.newM); - rs.oldM = rs.newM; - rs.oldS = rs.newS; - } - } - } - - function mean(RunningStats memory rs) internal pure returns (int256 result) { - require(rs.n != 0, "No elements collected."); - result = rs.newM; - } - - function variance(RunningStats memory rs) internal pure returns (int256 result) { - unchecked { - require(rs.n > 1, "Insufficient elements collected."); - result = rs.newS / (rs.n - 1); - } - } - - function standardDeviation(RunningStats memory rs) internal pure returns (int256) { - return int256(FixedPointMathLib.sqrt(uint256(variance(rs)))); - } -} - -contract LibPRNGTest is SoladyTest { - using LibPRNG for *; - using RunningStatsLib for *; - - LibPRNG.LazyShuffler internal _lazyShuffler0; - LibPRNG.LazyShuffler internal _lazyShuffler1; - - function testPRNGNext() public { - unchecked { - // Super unlikely to fail. - for (uint256 i; i < 32; ++i) { - LibPRNG.PRNG memory prng; - prng.seed(i); - uint256 r0 = prng.next(); - uint256 r1 = prng.next(); - uint256 r2 = prng.next(); - assertTrue(r0 != r1); - assertTrue(r1 != r2); - prng.seed(i * 2); - uint256 r3 = prng.next(); - assertTrue(r2 != r3); - } - } - } - - function testPRNGUniform() public { - unchecked { - LibPRNG.PRNG memory prng; - for (uint256 i = 1; i < 32; ++i) { - for (uint256 j; j < 32; ++j) { - assertTrue(prng.uniform(i) < i); - } - } - for (uint256 i; i < 32; ++i) { - assertTrue(prng.uniform(0) == 0); - } - // Super unlikely to fail. - uint256 previous; - for (uint256 i = 128; i < 256; ++i) { - uint256 n = 1 << i; - for (uint256 j; j < 8; ++j) { - uint256 r = prng.uniform(n); - assertTrue(r < n); - assertTrue(r != previous); - previous = r; - } - } - } - } - - function testPRNGShuffleGas() public pure { - unchecked { - uint256[] memory a = new uint256[](10000); - LibPRNG.PRNG memory prng; - prng.shuffle(a); - } - } - - function testPRNGShuffleBytesGas() public pure { - unchecked { - bytes memory a = new bytes(10000); - LibPRNG.PRNG memory prng; - prng.shuffle(a); - } - } - - struct _TestPRNGShuffleTemps { - int256[] a; - bytes32 hashBefore; - bytes32 hashAfterShuffle; - bytes32 hashAfterSort; - RunningStatsLib.RunningStats[] rsElements; - } - - function testPRNGShuffle() public { - unchecked { - LibPRNG.PRNG memory prng; - _TestPRNGShuffleTemps memory t; - for (uint256 s = 1; s < 9; ++s) { - t.a = new int256[](1 << s); // 2, 4, 8, 16, ... - t.rsElements = new RunningStatsLib.RunningStats[](t.a.length); - for (uint256 i; i < t.a.length; ++i) { - int256 x = int256(i * FixedPointMathLib.WAD); - t.a[i] = x; - } - t.hashBefore = keccak256(abi.encode(t.a)); - for (;;) { - prng.shuffle(t.a); - t.hashAfterShuffle = keccak256(abi.encode(t.a)); - LibSort.sort(t.a); - t.hashAfterSort = keccak256(abi.encode(t.a)); - assertEq(t.hashBefore, t.hashAfterSort); - if (t.hashBefore != t.hashAfterShuffle) break; - } - } - // Checking that we won't crash. - for (uint256 n = 0; n < 2; ++n) { - uint256[] memory a = new uint256[](n); - prng.shuffle(a); - } - } - } - - function testPRNGShuffleDistribution() public { - for (uint256 t; t < 8; ++t) { - _testPRNGShuffleDistribution(); - } - } - - function _testPRNGShuffleDistribution() internal { - unchecked { - LibPRNG.PRNG memory prng; - prng.state = _random(); - _TestPRNGShuffleTemps memory t; - t.a = new int256[](8); - t.rsElements = new RunningStatsLib.RunningStats[](8); - while (true) { - for (uint256 i; i < 8; ++i) { - t.a[i] = int256(i * 1000000); - } - prng.shuffle(t.a); - for (uint256 i; i < 8; ++i) { - t.rsElements[i].push(t.a[i]); - } - bool done = true; - for (uint256 i; i < 8; ++i) { - if (FixedPointMathLib.dist(3500000, t.rsElements[i].mean()) > 350000) { - done = false; - break; - } - } - if (done) break; - } - } - } - - function testPRNGPartialShuffle() public { - for (uint256 i; i < 8; ++i) { - _testPRNGPartialShuffle(i + 123); - } - } - - function _testPRNGPartialShuffle(uint256 state) internal { - unchecked { - LibPRNG.PRNG memory prng; - prng.state = state; - for (uint256 s = 1; s < 9; ++s) { - uint256[] memory a = new uint256[](1 << s); - for (uint256 i; i < a.length; ++i) { - a[i] = i; - } - bytes32 hashBefore = keccak256(abi.encode(a)); - for (;;) { - prng.shuffle(a, _bound(_random(), 0, a.length * 2)); - bytes32 hashAfterShuffle = keccak256(abi.encode(a)); - LibSort.insertionSort(a); - bytes32 hashAfterSort = keccak256(abi.encode(a)); - assertTrue(hashBefore == hashAfterSort); - if (hashBefore != hashAfterShuffle) break; - } - } - // Checking that we won't crash. - for (uint256 n = 0; n < 2; ++n) { - uint256[] memory a = new uint256[](n); - prng.shuffle(a, _bound(_random(), 0, a.length * 2)); - } - } - } - - function testPRNGPartialShuffleDistribution() public { - _testPRNGPartialShuffleDistribution(); - _testPRNGPartialShuffleDistribution(); - _testPRNGPartialShuffleDistribution(); - } - - function _testPRNGPartialShuffleDistribution() internal { - for (uint256 k; k <= 8; ++k) { - _testPRNGPartialShuffleDistribution(k); - } - } - - function _testPRNGPartialShuffleDistribution(uint256 k) internal { - unchecked { - LibPRNG.PRNG memory prng; - prng.state = _random(); - _TestPRNGShuffleTemps memory t; - t.a = new int256[](8); - t.rsElements = new RunningStatsLib.RunningStats[](8); - while (true) { - for (uint256 i; i < 8; ++i) { - t.a[i] = int256(i * 1000000); - } - prng.shuffle(t.a, k); - for (uint256 i; i < k; ++i) { - t.rsElements[i].push(t.a[i]); - } - bool done = true; - for (uint256 i; i < k; ++i) { - if (FixedPointMathLib.dist(3500000, t.rsElements[i].mean()) > 350000) { - done = false; - break; - } - } - if (done) break; - } - } - } - - function testPRNGShuffleBytes() public { - unchecked { - LibPRNG.PRNG memory prng; - for (uint256 s = 1; s < 9; ++s) { - uint256 n = 1 << s; // 2, 4, 8, 16, ... - bytes memory a = new bytes(n); - for (uint256 i; i < n; ++i) { - a[i] = bytes1(uint8(i & 0xff)); - } - bytes32 hashBefore = keccak256(abi.encode(a)); - uint256 checksumBefore = _bytesOrderAgnosticChecksum(a); - for (uint256 i; i < 30; ++i) { - prng.shuffle(a); - assertEq(_bytesOrderAgnosticChecksum(a), checksumBefore); - bytes32 hashAfterShuffle = keccak256(abi.encode(a)); - if (hashBefore != hashAfterShuffle) break; - } - } - // Checking that we won't crash. - for (uint256 n = 0; n < 2; ++n) { - uint256[] memory a = new uint256[](n); - prng.shuffle(a); - } - } - } - - function testLCGGas() public { - unchecked { - uint256 randomness; - for (uint256 i; i < 256; i++) { - randomness = _stepLCG(randomness); - } - assertTrue(randomness != 0); - } - } - - function testPRNGGas() public { - unchecked { - LibPRNG.PRNG memory prng; - uint256 randomness; - for (uint256 i; i < 256; i++) { - randomness = prng.next(); - } - assertTrue(randomness != 0); - } - } - - function _bytesOrderAgnosticChecksum(bytes memory a) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - for { let n := mload(a) } n { n := sub(n, 1) } { - result := add(result, and(mload(add(a, n)), 0xff)) - } - } - } - - // This is for demonstrating that the gas savings - // over the `keccak256` approach isn't that much. - // The multiplier and the increment are chosen for good enough - // statistical test results. - // - // See: https://github.com/stevenang/randomness_testsuite - // See: https://www.pcg-random.org/posts/does-it-beat-the-minimal-standard.html - // - // The xorshift is required because the raw 128 lower bits - // of the LCG alone will not pass the tests. - function _stepLCG(uint256 state) private pure returns (uint256 randomness) { - /// @solidity memory-safe-assembly - assembly { - let a := 0xd6aad120322a96acae4ccfaf5fcd4bbfda3f2f3001db6837c0981639faa68d8d - state := add(mul(state, a), 83) - randomness := xor(state, shr(128, state)) - } - } - - function testStandardNormalWad() public { - LibPRNG.PRNG memory prng; - RunningStatsLib.RunningStats memory rs; - unchecked { - uint256 n = 1000; - for (uint256 i; i != n; ++i) { - uint256 gasBefore = gasleft(); - int256 x = prng.standardNormalWad(); - uint256 gasUsed = gasBefore - gasleft(); - emit LogInt("standardNormalWad", x); - emit LogUint("gasUsed", gasUsed); - rs.push(x); - } - int256 wad = int256(FixedPointMathLib.WAD); - emit LogInt("mean", rs.mean()); - int256 sd = rs.standardDeviation(); - assertLt(FixedPointMathLib.abs(rs.mean()), uint256(wad / 8)); - emit LogInt("standard deviation", sd); - assertLt(FixedPointMathLib.abs(sd - wad), uint256(wad / 8)); - } - } - - function testExponentialWad() public { - LibPRNG.PRNG memory prng; - RunningStatsLib.RunningStats memory rs; - unchecked { - uint256 n = 1000; - for (uint256 i; i != n; ++i) { - uint256 gasBefore = gasleft(); - int256 x = int256(prng.exponentialWad()); - uint256 gasUsed = gasBefore - gasleft(); - emit LogInt("exponentialWad", x); - emit LogUint("gasUsed", gasUsed); - rs.push(x); - } - int256 wad = int256(FixedPointMathLib.WAD); - emit LogInt("mean", rs.mean()); - int256 sd = rs.standardDeviation(); - assertLt(FixedPointMathLib.abs(rs.mean() - wad), uint256(wad / 8)); - emit LogInt("standard deviation", sd); - assertLt(FixedPointMathLib.abs(sd - wad), uint256(wad / 8)); - } - } - - function testLazyShufflerProducesShuffledRange(uint256 n) public { - n = _bound(n, 1, _randomChance(8) ? 50 : 10); - if (_randomChance(8)) { - _brutalizeMemory(); - } - _lazyShuffler0.initialize(n); - assertEq(_lazyShuffler0.length(), n); - assertEq(_lazyShuffler0.numShuffled(), 0); - if (_randomChance(8)) { - _lazyShuffler0.restart(); - } - assertEq(_lazyShuffler0.initialized(), true); - assertEq(_lazyShuffler1.initialized(), false); - assertEq(_lazyShuffler0.finished(), false); - uint256[] memory outputs = new uint256[](n); - unchecked { - for (uint256 i; i != n; ++i) { - assertEq(_lazyShuffler0.finished(), false); - outputs[i] = _lazyShuffler0.next(_random()); - } - if (n > 32) { - bool anyShuffled; - for (uint256 i; i != n && !anyShuffled; ++i) { - anyShuffled = outputs[i] != i; - } - assertTrue(anyShuffled); // Super unlikely to fail. - } - LibSort.sort(outputs); - for (uint256 i; i != n; ++i) { - assertEq(outputs[i], i); - } - assertEq(_lazyShuffler0.finished(), true); - } - assertEq(_lazyShuffler0.finished(), true); - } - - function testLazyShufflerProducesShuffledRange2() public { - unchecked { - _lazyShuffler0.initialize(uint32(17)); - int256 m = 16; - // This infinite loop must eventually break. - for (bool done; !done;) { - int256[] memory sums = new int256[](17); - for (int256 t; t != m; ++t) { - for (uint256 i; i != 17; ++i) { - sums[i] += int256(uint256(_lazyShuffler0.next(_random()))); - } - _lazyShuffler0.restart(); - } - int256 expectedAvgSum = 8 * m; - done = true; - uint256 thres = uint256(expectedAvgSum / 8); - for (uint256 i; i != 17; ++i) { - if (FixedPointMathLib.abs(sums[i] - expectedAvgSum) >= thres) { - done = false; - m *= 2; - break; - } - } - } - } - } - - function testLazyShufflerProducesShuffledRangeWithGrow(uint256 n, uint256 nGrow) public { - n = _bound(n, 1, 32); - nGrow = n + _bound(nGrow, 0, 32); - _lazyShuffler0.initialize(n); - uint256[] memory outputs = new uint256[](nGrow); - unchecked { - uint256 i; - while (i != n) { - outputs[i] = _lazyShuffler0.next(_random()); - ++i; - if (_randomChance(8)) break; - } - _lazyShuffler0.grow(nGrow); - while (i != nGrow) { - outputs[i] = _lazyShuffler0.next(_random()); - ++i; - } - LibSort.sort(outputs); - for (i = 0; i != nGrow; ++i) { - assertEq(outputs[i], i); - } - assertEq(_lazyShuffler0.finished(), true); - } - assertEq(_lazyShuffler0.finished(), true); - } - - function testLazyShufflerNoStorageCollisions() public { - _lazyShuffler0.initialize(16); - _lazyShuffler1.initialize(32); - uint256[] memory outputs0 = new uint256[](16); - uint256[] memory outputs1 = new uint256[](32); - unchecked { - for (uint256 i; i != 16; ++i) { - outputs0[i] = _lazyShuffler0.next(_random()); - } - for (uint256 i; i != 32; ++i) { - assertEq(_lazyShuffler1.finished(), false); - outputs1[i] = _lazyShuffler1.next(_random()); - } - assertEq(_lazyShuffler0.finished(), true); - assertEq(_lazyShuffler1.finished(), true); - LibSort.sort(outputs0); - LibSort.sort(outputs1); - for (uint256 i; i != 16; ++i) { - assertEq(outputs0[i], i); - } - for (uint256 i; i != 32; ++i) { - assertEq(outputs1[i], i); - } - } - } - - function testLazyShufflerGet() public { - _lazyShuffler0.initialize(16); - _lazyShuffler1.initialize(32); - uint256[] memory outputs0 = new uint256[](16); - uint256[] memory outputs1 = new uint256[](32); - unchecked { - for (uint256 i; i != 16; ++i) { - assertEq(_lazyShuffler0.get(i), i); - } - for (uint256 i; i != 16; ++i) { - outputs0[i] = _lazyShuffler0.next(_random()); - } - for (uint256 i; i != 32; ++i) { - assertEq(_lazyShuffler1.get(i), i); - } - for (uint256 i; i != 32; ++i) { - assertEq(_lazyShuffler1.finished(), false); - outputs1[i] = _lazyShuffler1.next(_random()); - } - for (uint256 i; i != 16; ++i) { - assertEq(_lazyShuffler0.get(i), outputs0[i]); - } - for (uint256 i; i != 32; ++i) { - assertEq(_lazyShuffler1.get(i), outputs1[i]); - } - } - } - - function testLazyShufflerGetOutOfBoundsReverts(uint256 n, uint256 i) public { - n = _bound(n, 1, 2 ** 32 - 2); - _lazyShuffler0.initialize(n); - i = _bound(i, 1, 2 ** 32 + 1); - if (i < n) { - assertEq(this.lazyShuffler0Get(i), i); - } else { - vm.expectRevert(LibPRNG.LazyShufflerGetOutOfBounds.selector); - this.lazyShuffler0Get(i); - } - } - - function testLazyShufflerRestart() public { - uint256[] memory outputs0 = new uint256[](32); - uint256[] memory outputs1 = new uint256[](32); - _lazyShuffler0.initialize(32); - assertEq(_lazyShuffler0.numShuffled(), 0); - assertEq(_lazyShuffler0.length(), 32); - for (uint256 i; i != 32; ++i) { - assertEq(_lazyShuffler0.numShuffled(), i); - outputs0[i] = _lazyShuffler0.next(_random()); - } - assertEq(_lazyShuffler0.numShuffled(), 32); - _lazyShuffler0.restart(); - assertEq(_lazyShuffler0.numShuffled(), 0); - assertEq(_lazyShuffler0.length(), 32); - for (uint256 i; i != 32; ++i) { - outputs1[i] = _lazyShuffler0.next(_random()); - } - assertTrue(keccak256(abi.encode(outputs0)) != keccak256(abi.encode(outputs1))); - LibSort.sort(outputs0); - LibSort.sort(outputs1); - for (uint256 i; i != 32; ++i) { - assertEq(outputs0[i], i); - assertEq(outputs1[i], i); - } - } - - function testLazyShufflerRevertsOnInitWithInvalidLength(uint256 n) public { - n = _bound(n, 0, 2 ** 32 + 1); - if (n == 0 || n >= 2 ** 32 - 1) { - vm.expectRevert(LibPRNG.InvalidInitialLazyShufflerLength.selector); - } - this.lazyShufflerInitialize(n); - } - - function testLazyShufflerRevertsOnGrowWithInvalidLength(uint256 n, uint256 nGrow) public { - n = _bound(n, 1, 2 ** 32 - 2); - this.lazyShufflerInitialize(n); - nGrow = _bound(n, 0, 2 ** 32 - 2); - if (nGrow < n) { - vm.expectRevert(LibPRNG.InvalidNewLazyShufflerLength.selector); - } - this.lazyShufflerGrow(n); - } - - function testLazyShufflerRevertsOnDoubleInit() public { - this.lazyShufflerInitialize(1); - vm.expectRevert(LibPRNG.LazyShufflerAlreadyInitialized.selector); - this.lazyShufflerInitialize(2); - } - - function testLazyShufflerRevertsOnZeroLengthNext() public { - vm.expectRevert(LibPRNG.LazyShuffleFinished.selector); - this.lazyShufflerNext(_random()); - } - - function testLazyShufflerRevertsOnFinishedNext(uint256 n) public { - n = _bound(n, 1, 3); - _lazyShuffler0.initialize(n); - unchecked { - for (uint256 i; i != n; ++i) { - lazyShufflerNext(_random()); - } - } - vm.expectRevert(LibPRNG.LazyShuffleFinished.selector); - this.lazyShufflerNext(_random()); - } - - function lazyShufflerInitialize(uint256 n) public { - _lazyShuffler0.initialize(n); - } - - function lazyShufflerGrow(uint256 n) public { - _lazyShuffler0.grow(n); - } - - function lazyShufflerNext(uint256 randomness) public returns (uint256) { - return _lazyShuffler0.next(randomness); - } - - function lazyShuffler0Get(uint256 i) public view returns (uint256) { - return _lazyShuffler0.get(i); - } - - function lazyShuffler1Get(uint256 i) public view returns (uint256) { - return _lazyShuffler1.get(i); - } -} diff --git a/grouperBot/lib/solady/test/LibRLP.t.sol b/grouperBot/lib/solady/test/LibRLP.t.sol deleted file mode 100644 index 0b77877..0000000 --- a/grouperBot/lib/solady/test/LibRLP.t.sol +++ /dev/null @@ -1,670 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibRLP} from "../src/utils/LibRLP.sol"; -import {FixedPointMathLib} from "../src/utils/FixedPointMathLib.sol"; - -contract LibRLPTest is SoladyTest { - using LibRLP for LibRLP.List; - - function testComputeAddressDifferential(address deployer, uint256 nonce) public { - address computed = LibRLP.computeAddress(_brutalized(deployer), nonce); - assertEq(computed, computeAddressOriginal(deployer, nonce)); - assertEq(computed, computeAddressWithRLPList(deployer, nonce)); - } - - function testComputeAddressForSmallNonces() public { - address deployer = address(1); - assertTrue(LibRLP.computeAddress(deployer, 1) != address(0)); - assertTrue(LibRLP.computeAddress(deployer, 0x7f) != address(0)); - assertTrue(LibRLP.computeAddress(deployer, 0xff) != address(0)); - } - - function testComputeAddressOriginalForSmallNonces() public { - address deployer = address(1); - assertTrue(computeAddressOriginal(deployer, 1) != address(0)); - assertTrue(computeAddressOriginal(deployer, 0x7f) != address(0)); - assertTrue(computeAddressOriginal(deployer, 0xff) != address(0)); - } - - function testComputeAddressForLargeNonces() public { - address deployer = address(1); - assertTrue(LibRLP.computeAddress(deployer, 0xffffffff) != address(0)); - assertTrue(LibRLP.computeAddress(deployer, 0xffffffffffffff) != address(0)); - assertTrue(LibRLP.computeAddress(deployer, 0xffffffffffffffff) != address(0)); - } - - function testComputeAddressOriginalForLargeNonces() public { - address deployer = address(1); - assertTrue(computeAddressOriginal(deployer, 0xffffffff) != address(0)); - assertTrue(computeAddressOriginal(deployer, 0xffffffffffffff) != address(0)); - assertTrue(computeAddressOriginal(deployer, 0xffffffffffffffff) != address(0)); - } - - function computeAddressWithRLPList(address deployer, uint256 nonce) - internal - pure - returns (address) - { - return address(uint160(uint256(keccak256(LibRLP.p(deployer).p(nonce).encode())))); - } - - function computeAddressOriginal(address deployer, uint256 nonce) - internal - pure - returns (address) - { - return address(uint160(uint256(keccak256(_computeAddressOriginal(deployer, nonce))))); - } - - function _computeAddressOriginal(address deployer, uint256 nonce) - internal - pure - returns (bytes memory) - { - // Although the theoretical allowed limit, based on EIP-2681, - // for an account nonce is 2**64-2: https://eips.ethereum.org/EIPS/eip-2681, - // we just test all the way to 2**256-1 to ensure that the computeAddress function does not revert - // for whatever nonce we provide. - - if (nonce == 0x00) { - return abi.encodePacked(uint8(0xd6), uint8(0x94), deployer, uint8(0x80)); - } - if (nonce <= 0x7f) { - return abi.encodePacked(uint8(0xd6), uint8(0x94), deployer, uint8(nonce)); - } - bytes memory ep = _ep(nonce); - uint256 n = ep.length; - return abi.encodePacked(uint8(0xd6 + n), uint8(0x94), deployer, uint8(0x80 + n), ep); - } - - function _ep(uint256 x) internal pure returns (bytes memory) { - if (x <= type(uint8).max) return abi.encodePacked(uint8(x)); - if (x <= type(uint16).max) return abi.encodePacked(uint16(x)); - if (x <= type(uint24).max) return abi.encodePacked(uint24(x)); - if (x <= type(uint32).max) return abi.encodePacked(uint32(x)); - if (x <= type(uint40).max) return abi.encodePacked(uint40(x)); - if (x <= type(uint48).max) return abi.encodePacked(uint48(x)); - if (x <= type(uint56).max) return abi.encodePacked(uint56(x)); - if (x <= type(uint64).max) return abi.encodePacked(uint64(x)); - if (x <= type(uint72).max) return abi.encodePacked(uint72(x)); - if (x <= type(uint80).max) return abi.encodePacked(uint80(x)); - if (x <= type(uint88).max) return abi.encodePacked(uint88(x)); - if (x <= type(uint96).max) return abi.encodePacked(uint96(x)); - if (x <= type(uint104).max) return abi.encodePacked(uint104(x)); - if (x <= type(uint112).max) return abi.encodePacked(uint112(x)); - if (x <= type(uint120).max) return abi.encodePacked(uint120(x)); - if (x <= type(uint128).max) return abi.encodePacked(uint128(x)); - if (x <= type(uint136).max) return abi.encodePacked(uint136(x)); - if (x <= type(uint144).max) return abi.encodePacked(uint144(x)); - if (x <= type(uint152).max) return abi.encodePacked(uint152(x)); - if (x <= type(uint160).max) return abi.encodePacked(uint160(x)); - if (x <= type(uint168).max) return abi.encodePacked(uint168(x)); - if (x <= type(uint176).max) return abi.encodePacked(uint176(x)); - if (x <= type(uint184).max) return abi.encodePacked(uint184(x)); - if (x <= type(uint192).max) return abi.encodePacked(uint192(x)); - if (x <= type(uint200).max) return abi.encodePacked(uint200(x)); - if (x <= type(uint208).max) return abi.encodePacked(uint208(x)); - if (x <= type(uint216).max) return abi.encodePacked(uint216(x)); - if (x <= type(uint224).max) return abi.encodePacked(uint224(x)); - if (x <= type(uint232).max) return abi.encodePacked(uint232(x)); - if (x <= type(uint240).max) return abi.encodePacked(uint240(x)); - if (x <= type(uint248).max) return abi.encodePacked(uint248(x)); - return abi.encodePacked(uint256(x)); - } - - function testRLPPUint256() public { - _testRLPPUint256(0); - _testRLPPUint256(1); - _testRLPPUint256(1 << 255); - } - - function _testRLPPUint256(uint256 x) internal { - LibRLP.List memory l; - unchecked { - for (uint256 i; i != 32; ++i) { - uint256 y = x ^ i; - l.p(y); - _checkMemory(l); - assertEq(_getUint256(l, i), y); - } - for (uint256 i; i != 32; ++i) { - uint256 y = x ^ i; - assertEq(_getUint256(l, i), y); - } - } - } - - function testRLPMemory(bytes32) public returns (LibRLP.List memory l) { - while (true) { - uint256 r = _random(); - if (r & 0x0003 == 0) { - _maybeBzztMemory(); - l.p(_randomBytes()); - _checkMemory(l); - } - if (r & 0x0030 == 0) { - if (_random() & 1 == 0) { - l.p(_randomNonZeroAddress()); - } else { - l.p(_random()); - } - _checkMemory(l); - _maybeBzztMemory(); - } - if (r & 0x0100 == 0) { - l.p(_testRLPP(0)); - _checkMemory(l); - } - if (r & 0x1000 == 0) break; - } - _checkMemory(l.encode()); - } - - function _testRLPP(uint256 depth) internal returns (LibRLP.List memory l) { - if (depth <= 2) { - while (true) { - uint256 r = _random(); - if (r & 0x0007 == 0) { - _maybeBzztMemory(); - l.p(_randomBytes()); - _checkMemory(l); - } - if (r & 0x0030 == 0) { - if (_random() & 1 == 0) { - l.p(_randomNonZeroAddress()); - } else { - l.p(_random()); - } - _checkMemory(l); - _maybeBzztMemory(); - } - if (r & 0x0300 == 0) { - _maybeBzztMemory(); - unchecked { - l.p(_testRLPP(depth + 1)); - } - _checkMemory(l); - } - if (r & 0x1000 == 0) break; - } - } - } - - function _getUint256(LibRLP.List memory l, uint256 i) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0) - let head := and(mload(l), 0xffffffffff) - if head { - for { let j := 0 } iszero(eq(j, i)) { j := add(j, 1) } { - head := and(mload(head), 0xffffffffff) - } - result := shr(48, mload(head)) - if eq(1, byte(26, mload(head))) { result := mload(result) } - } - } - } - - function testRLPEncodeBytes() public { - bytes memory s; - assertEq(LibRLP.encode(""), hex"80"); - s = "dog"; - assertEq(LibRLP.encode(s), abi.encodePacked(hex"83", s)); - assertEq(LibRLP.encode(hex"00"), hex"00"); - assertEq(LibRLP.encode(hex"0f"), hex"0f"); - assertEq(LibRLP.encode(hex"0400"), hex"820400"); - s = "Lorem ipsum dolor sit amet, consectetur adipisicing eli"; - assertEq(LibRLP.encode(s), abi.encodePacked(hex"b7", s)); - s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit"; - assertEq(LibRLP.encode(s), abi.encodePacked(hex"b838", s)); - s = new bytes(0x100); - assertEq(LibRLP.encode(s), abi.encodePacked(hex"b90100", s)); - s = new bytes(0xfffe); - assertEq(LibRLP.encode(s), abi.encodePacked(hex"b9fffe", s)); - } - - function testRLPEncodeBytes2() public { - assertEq(LibRLP.encode(""), hex"80"); - for (uint256 i = 0; i < 128; ++i) { - assertEq( - LibRLP.encode(bytes(abi.encodePacked(uint8(i)))), bytes(abi.encodePacked(uint8(i))) - ); - } - for (uint256 i = 128; i < 256; ++i) { - assertEq( - LibRLP.encode(bytes(abi.encodePacked(uint8(i)))), - bytes(abi.encodePacked(bytes1(0x81), uint8(i))) - ); - } - } - - function testRLPEncodeAddressViaList(address a0, address a1) public { - _maybeBzztMemory(); - bytes memory computed = LibRLP.p(_brutalized(a0)).p(_brutalized(a1)).encode(); - _checkMemory(computed); - _maybeBzztMemory(); - bytes memory expected = LibRLP.p(abi.encodePacked(a0)).p(abi.encodePacked(a1)).encode(); - assertEq(computed, expected); - } - - function testRLPEncodeListDifferential(bytes memory x0, uint256 x1) public { - _maybeBzztMemory(); - LibRLP.List memory list = LibRLP.p(x0).p(x1).p(x1).p(x0); - _checkMemory(list); - _maybeBzztMemory(); - bytes memory computed = LibRLP.encode(list); - _checkAndMaybeBzztMemory(computed); - bytes memory x0Encoded = LibRLP.encode(x0); - _checkAndMaybeBzztMemory(x0Encoded); - bytes memory x1Encoded = LibRLP.encode(x1); - _checkAndMaybeBzztMemory(x1Encoded); - bytes memory combined = abi.encodePacked(x0Encoded, x1Encoded, x1Encoded, x0Encoded); - assertEq(computed, _encodeSimple(combined, 0xc0)); - _checkAndMaybeBzztMemory(computed); - assertEq(computed, LibRLP.encode(list)); - } - - function testRLPEncodeBytesDifferential(bytes32) public { - bytes memory x = _randomBytesZeroRightPadded(); - _maybeBzztMemory(); - bytes memory computed = LibRLP.encode(x); - _checkAndMaybeBzztMemory(computed); - bytes memory computed2 = _encode(x); - _checkAndMaybeBzztMemory(computed2); - assertEq(computed, computed2); - assertEq(computed, _encodeSimple(x)); - } - - function testRLPEncodeUintDifferential(uint256 x) public { - _maybeBzztMemory(); - bytes memory computed = LibRLP.encode(x); - _checkAndMaybeBzztMemory(computed); - bytes memory computed2 = _encode(x); - _checkAndMaybeBzztMemory(computed2); - assertEq(computed, computed2); - assertEq(computed, _encodeSimple(x)); - } - - function testRLPEncodeAddressDifferential(address x) public { - _maybeBzztMemory(); - bytes memory computed = LibRLP.encode(_brutalized(x)); - _checkAndMaybeBzztMemory(computed); - bytes memory computed2 = _encode(x); - _checkAndMaybeBzztMemory(computed2); - assertEq(computed, computed2); - assertEq(computed, _encodeSimple(x)); - } - - function testRLPEncodeBool(bool x) public { - _maybeBzztMemory(); - bytes memory computed = LibRLP.encode(_brutalized(x)); - _checkMemory(computed); - bytes memory expected = bytes(x ? hex"01" : hex"80"); - assertEq(computed, expected); - uint256 y = x ? 1 : 0; - assertEq(LibRLP.p(y).p(y ^ 1).p(y).encode(), LibRLP.p(x).p(!x).p(x).encode()); - } - - function _maybeBzztMemory() internal { - uint256 r = _random(); - if (r & 0x000f == uint256(0)) _misalignFreeMemoryPointer(); - if (r & 0x0ff0 == uint256(0)) _brutalizeMemory(); - if (r & 0xf000 == uint256(0)) _misalignFreeMemoryPointer(); - } - - function _bzztMemory() internal view { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - - function _checkAndMaybeBzztMemory(bytes memory x) internal { - _checkMemory(x); - _maybeBzztMemory(); - } - - function _encode(uint256 x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function encodeUint(x_, o_) -> _o { - _o := add(o_, 1) - if iszero(gt(x_, 0x7f)) { - mstore8(o_, or(shl(7, iszero(x_)), x_)) // Copy `x_`. - leave - } - let r_ := shl(7, lt(0xffffffffffffffffffffffffffffffff, x_)) - r_ := or(r_, shl(6, lt(0xffffffffffffffff, shr(r_, x_)))) - r_ := or(r_, shl(5, lt(0xffffffff, shr(r_, x_)))) - r_ := or(r_, shl(4, lt(0xffff, shr(r_, x_)))) - r_ := or(shr(3, r_), lt(0xff, shr(r_, x_))) - mstore8(o_, add(r_, 0x81)) // Store the prefix. - mstore(0x00, x_) - mstore(_o, mload(xor(31, r_))) // Copy `x_`. - _o := add(add(1, r_), _o) - } - result := mload(0x40) - let o := encodeUint(x, add(result, 0x20)) - mstore(result, sub(o, add(result, 0x20))) - mstore(o, 0) - mstore(0x40, add(o, 0x20)) - } - } - - function _encode(bytes memory x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function encodeBytes(x_, o_, c_) -> _o { - _o := add(o_, 1) - let n_ := mload(x_) - if iszero(gt(n_, 55)) { - let f_ := mload(add(0x20, x_)) - if iszero(and(eq(1, n_), lt(byte(0, f_), 0x80))) { - mstore8(o_, add(n_, c_)) // Store the prefix. - mstore(add(0x21, o_), mload(add(0x40, x_))) - mstore(_o, f_) - _o := add(n_, _o) - leave - } - mstore(o_, f_) // Copy `x_`. - leave - } - returndatacopy(returndatasize(), returndatasize(), shr(32, n_)) - let r_ := add(1, add(lt(0xff, n_), add(lt(0xffff, n_), lt(0xffffff, n_)))) - mstore(o_, shl(248, add(r_, add(c_, 55)))) // Store the prefix. - // Copy `x`. - let i_ := add(r_, _o) - _o := add(i_, n_) - for { let d_ := sub(add(0x20, x_), i_) } 1 {} { - mstore(i_, mload(add(d_, i_))) - i_ := add(i_, 0x20) - if iszero(lt(i_, _o)) { break } - } - mstore(o_, or(mload(o_), shl(sub(248, shl(3, r_)), n_))) // Store the prefix. - } - result := mload(0x40) - let o := encodeBytes(x, add(result, 0x20), 0x80) - mstore(result, sub(o, add(result, 0x20))) - mstore(o, 0) - mstore(0x40, add(o, 0x20)) - } - } - - function _encode(address x) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function encodeAddress(x_, o_) -> _o { - _o := add(o_, 0x15) - mstore(o_, shl(88, x_)) - mstore8(o_, 0x94) - } - result := mload(0x40) - let o := encodeAddress(x, add(result, 0x20)) - mstore(result, sub(o, add(result, 0x20))) - mstore(o, 0) - mstore(0x40, add(o, 0x20)) - } - } - - function _encodeSimple(uint256 x) internal pure returns (bytes memory) { - if (x == 0) return hex"80"; - if (x < 0x80) return abi.encodePacked(uint8(x)); - bytes memory ep = _ep(x); - return abi.encodePacked(uint8(0x80 + ep.length), ep); - } - - function _encodeSimple(address x) internal pure returns (bytes memory) { - return abi.encodePacked(uint8(0x94), x); - } - - function _encodeSimple(bytes memory x, uint256 c) internal pure returns (bytes memory) { - uint256 n = x.length; - if (n == 0) return hex"80"; - if (n == 1 && uint8(bytes1(x[0])) < 0x80) return x; - if (n < 56) return abi.encodePacked(uint8(n + c), x); - bytes memory ep = _ep(n); - return abi.encodePacked(uint8(c + 55 + ep.length), ep, x); - } - - function _encodeSimple(bytes memory x) internal pure returns (bytes memory) { - return _encodeSimple(x, 0x80); - } - - function testRLPEncodeUint(uint256 x) public { - _maybeBzztMemory(); - if (x == 0) { - _testRLPEncodeUint(x, hex"80"); - return; - } - if (x < 0x80) { - _testRLPEncodeUint(x, abi.encodePacked(uint8(x))); - return; - } - bytes memory ep = _ep(x); - uint256 n = ep.length; - _testRLPEncodeUint(x, abi.encodePacked(uint8(0x80 + n), _ep(x))); - } - - function testRLPEncodeUint() public { - _testRLPEncodeUint(0, hex"80"); - _testRLPEncodeUint(0x1, hex"01"); - _testRLPEncodeUint(0x2, hex"02"); - _testRLPEncodeUint(0x7e, hex"7e"); - _testRLPEncodeUint(0x7f, hex"7f"); - _testRLPEncodeUint(0x80, hex"8180"); - _testRLPEncodeUint(0x81, hex"8181"); - _testRLPEncodeUint(0x82, hex"8182"); - _testRLPEncodeUint(0xfe, hex"81fe"); - _testRLPEncodeUint(0xff, hex"81ff"); - unchecked { - uint256 x = type(uint256).max; - while (x != 0) { - testRLPEncodeUint(x); - testRLPEncodeUint(x - 1); - x >>= 8; - } - } - } - - function testRLPEncodeListEdgeCases() public { - for (uint256 i; i < 0x80; ++i) { - bytes1 x = bytes1(uint8(i)); - assertEq(LibRLP.encode(LibRLP.p().p(abi.encodePacked(x))), abi.encodePacked(hex"c1", x)); - assertEq( - LibRLP.encode(LibRLP.p().p(LibRLP.p().p(abi.encodePacked(x)))), - abi.encodePacked(hex"c2c1", x) - ); - } - for (uint256 i = 0x80; i <= 0xff; ++i) { - bytes1 x = bytes1(uint8(i)); - assertEq( - LibRLP.encode(LibRLP.p().p(abi.encodePacked(x))), abi.encodePacked(hex"c281", x) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(LibRLP.p().p(abi.encodePacked(x)))), - abi.encodePacked(hex"c3c281", x) - ); - } - for (uint256 i = 0x100; i <= 0x1ff; ++i) { - bytes2 x = bytes2(uint16(i)); - assertEq( - LibRLP.encode(LibRLP.p().p(abi.encodePacked(x))), abi.encodePacked(hex"c382", x) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(LibRLP.p().p(abi.encodePacked(x)))), - abi.encodePacked(hex"c4c382", x) - ); - } - - assertEq( - LibRLP.encode(LibRLP.p().p(hex"112233445566778899aa")), hex"cb8a112233445566778899aa" - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(3))), abi.encodePacked(hex"c483", _repeatFF(3)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(7))), abi.encodePacked(hex"c887", _repeatFF(7)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(52))), abi.encodePacked(hex"f5b4", _repeatFF(52)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(53))), abi.encodePacked(hex"f6b5", _repeatFF(53)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(54))), abi.encodePacked(hex"f7b6", _repeatFF(54)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(55))), abi.encodePacked(hex"f838b7", _repeatFF(55)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(56))), - abi.encodePacked(hex"f83ab838", _repeatFF(56)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(57))), - abi.encodePacked(hex"f83bb839", _repeatFF(57)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(254))), - abi.encodePacked(hex"f90100b8fe", _repeatFF(254)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(255))), - abi.encodePacked(hex"f90101b8ff", _repeatFF(255)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(256))), - abi.encodePacked(hex"f90103b90100", _repeatFF(256)) - ); - assertEq( - LibRLP.encode(LibRLP.p().p(_repeatFF(257))), - abi.encodePacked(hex"f90104b90101", _repeatFF(257)) - ); - } - - function testRLPEncodeStringEdgeCases() public { - assertEq(LibRLP.encode(_repeatFF(3)), abi.encodePacked(hex"83", _repeatFF(3))); - assertEq(LibRLP.encode(_repeatFF(7)), abi.encodePacked(hex"87", _repeatFF(7))); - assertEq(LibRLP.encode(_repeatFF(52)), abi.encodePacked(hex"b4", _repeatFF(52))); - assertEq(LibRLP.encode(_repeatFF(53)), abi.encodePacked(hex"b5", _repeatFF(53))); - assertEq(LibRLP.encode(_repeatFF(54)), abi.encodePacked(hex"b6", _repeatFF(54))); - assertEq(LibRLP.encode(_repeatFF(55)), abi.encodePacked(hex"b7", _repeatFF(55))); - assertEq(LibRLP.encode(_repeatFF(56)), abi.encodePacked(hex"b838", _repeatFF(56))); - assertEq(LibRLP.encode(_repeatFF(57)), abi.encodePacked(hex"b839", _repeatFF(57))); - assertEq(LibRLP.encode(_repeatFF(254)), abi.encodePacked(hex"b8fe", _repeatFF(254))); - assertEq(LibRLP.encode(_repeatFF(255)), abi.encodePacked(hex"b8ff", _repeatFF(255))); - assertEq(LibRLP.encode(_repeatFF(256)), abi.encodePacked(hex"b90100", _repeatFF(256))); - assertEq(LibRLP.encode(_repeatFF(257)), abi.encodePacked(hex"b90101", _repeatFF(257))); - } - - function _repeatFF(uint256 n) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, n) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(result, 0x20), i), not(0)) - } - mstore(0x40, add(add(result, 0x20), n)) - } - } - - function _testRLPEncodeUint(uint256 x, bytes memory expected) internal { - bytes memory computed = LibRLP.encode(x); - _checkMemory(computed); - assertEq(computed, expected); - } - - function testRLPEncodeList() public { - LibRLP.List memory l; - _bzztMemory(); - assertEq(LibRLP.encode(l), hex"c0"); - l.p(LibRLP.p()); - _checkMemory(l); - l.p(LibRLP.p(LibRLP.p())); - _checkMemory(l); - l.p(LibRLP.p(LibRLP.p()).p(LibRLP.p(LibRLP.p()))); - _checkMemory(l); - _bzztMemory(); - bytes memory computed = LibRLP.encode(l); - _checkMemory(computed); - assertEq(computed, hex"c7c0c1c0c3c0c1c0"); - _bzztMemory(); - bytes memory computed2 = LibRLP.encode(l); - assertEq(computed, computed2); - _checkMemory(computed); - _checkMemory(computed2); - } - - function testRLPEncodeList2() public { - LibRLP.List memory l; - _checkMemory(l); - _bzztMemory(); - l.p("The").p("quick").p("brown").p("fox"); - l.p("jumps").p("over").p("the").p("lazy").p("dog"); - _checkMemory(l); - { - LibRLP.List memory lSub; - lSub.p(0).p(1).p(0x7f).p(0x80).p(0x81); - lSub.p(2 ** 256 - 1); - _checkMemory(lSub); - lSub.p("Jackdaws").p("loves").p("my").p(""); - lSub.p("great").p("sphinx").p("of").p("quartz"); - _checkMemory(lSub); - l.p(lSub); - _checkMemory(l); - } - _bzztMemory(); - l.p("0123456789abcdefghijklmnopqrstuvwxyz"); - _checkMemory(l); - _bzztMemory(); - bytes memory computed = LibRLP.encode(l); - _checkMemory(computed); - bytes memory expected = - hex"f8a58354686585717569636b8562726f776e83666f78856a756d7073846f76657283746865846c617a7983646f67f85280017f81808181a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff884a61636b64617773856c6f766573826d798085677265617486737068696e78826f668671756172747aa4303132333435363738396162636465666768696a6b6c6d6e6f707172737475767778797a"; - assertEq(computed, expected); - _bzztMemory(); - bytes memory computed2 = LibRLP.encode(l); - assertEq(computed, computed2); - _checkMemory(computed); - _checkMemory(computed2); - } - - function testSmallLog256Equivalence(uint256 n) public { - n = _bound(n, 0, 0xffffffff); - assertEq(_smallLog256(n), FixedPointMathLib.log256(n)); - assertEq(_smallLog256(n), _smallLog256Simple(n)); - n = _random() & 0xffffffff; - assertEq(_smallLog256(n), _smallLog256Simple(n)); - } - - function _smallLog256(uint256 n) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := add(lt(0xff, n), add(lt(0xffff, n), lt(0xffffff, n))) - } - } - - function _smallLog256Simple(uint256 n) internal pure returns (uint256 result) { - if (n <= 0x000000ff) return 0; - if (n <= 0x0000ffff) return 1; - if (n <= 0x00ffffff) return 2; - if (n <= 0xffffffff) return 3; - revert(); - } - - function _checkMemory(LibRLP.List memory l) internal pure { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let v := mload(l) - if gt(shr(40, v), m) { invalid() } - for { let head := and(v, 0xffffffffff) } head {} { - if gt(head, m) { invalid() } - head := and(mload(head), 0xffffffffff) - } - } - _checkMemory(); - } -} diff --git a/grouperBot/lib/solady/test/LibSort.t.sol b/grouperBot/lib/solady/test/LibSort.t.sol deleted file mode 100644 index 14ea5c3..0000000 --- a/grouperBot/lib/solady/test/LibSort.t.sol +++ /dev/null @@ -1,1461 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import "src/utils/LibSort.sol"; - -contract LibSortTest is SoladyTest { - function testInsertionSortAddressesDifferential(uint256) public { - unchecked { - uint256 n = _randomChance(32) ? _randomArrayLength() : _random() % 4; - address[] memory a = _randomAddresses(n); - // Make a copy of the `a` and perform insertion sort on it. - address[] memory aCopy = _copy(a); - for (uint256 i = 1; i < n; ++i) { - address key = aCopy[i]; - uint256 j = i; - while (j != 0 && aCopy[j - 1] > key) { - aCopy[j] = aCopy[j - 1]; - --j; - } - aCopy[j] = key; - } - LibSort.insertionSort(a); - assertEq(a, aCopy); - } - } - - function testInsertionSortPsuedorandom(uint256) public { - unchecked { - uint256[] memory a = _randomUints(32); - LibSort.insertionSort(a); - assertTrue(_isSorted(a)); - } - } - - function testInsertionSortPsuedorandom() public { - testInsertionSortPsuedorandom(123456789); - } - - function testSortChecksummed(uint256) public { - unchecked { - uint256 n = _randomArrayLength(); - uint256[] memory a = _randomUints(n); - uint256 checksum; - for (uint256 i = 0; i != n; ++i) { - checksum += a[i]; - } - LibSort.sort(a); - uint256 checksumAfterSort; - for (uint256 i = 0; i != n; ++i) { - checksumAfterSort += a[i]; - } - assertEq(checksum, checksumAfterSort); - assertTrue(_isSorted(a)); - } - } - - function testSortDifferential(uint256) public { - unchecked { - uint256[] memory a = _randomUints(_randomArrayLength()); - // Make a copy of the `a` and perform insertion sort on it. - uint256[] memory aCopy = _copy(a); - LibSort.insertionSort(aCopy); - LibSort.sort(a); - assertEq(a, aCopy); - } - } - - function testSort(uint256) public { - unchecked { - uint256[] memory a = _randomUints(_randomArrayLength()); - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortBasicCase() public { - unchecked { - uint256[] memory a = new uint256[](2); - a[0] = 3; - a[1] = 0; - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortPsuedorandom(uint256) public { - unchecked { - uint256[] memory a = _randomUints(100); - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortPsuedorandom() public { - testSortPsuedorandom(123456789); - } - - function testSortPsuedorandomNonuniform(uint256) public { - unchecked { - uint256[] memory a = new uint256[](100); - for (uint256 i; i < a.length; ++i) { - a[i] = _random() << (i & 8 == 0 ? 128 : 0); - } - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortPsuedorandomNonuniform() public { - testSortPsuedorandomNonuniform(123456789); - } - - function testSortSorted() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = i; - } - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortReversed() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = 999 - i; - } - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortMostlySame() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = i % 8 == 0 ? i : 0; - } - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortTestOverhead() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - uint256 mask = (1 << 128) - 1; - for (uint256 i; i != n; ++i) { - a[i] = (i << 128) | (_random() & mask); - } - assertTrue(_isSorted(a)); - } - } - - function testSortAddressesPsuedorandomBrutalizeUpperBits() public { - unchecked { - uint256 n = 100; - address[] memory a = new address[](n); - for (uint256 i; i != n; ++i) { - address addr = address(uint160(_random())); - uint256 randomness = _random(); - /// @solidity memory-safe-assembly - assembly { - addr := or(addr, shl(160, randomness)) - } - a[i] = addr; - } - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortAddressesDifferential(uint256) public { - unchecked { - uint256 n = _randomArrayLength(); - uint256[] memory aRaw = _randomUints(n); - address[] memory a = new address[](n); - for (uint256 i; i != n; ++i) { - address addr; - uint256 addrRaw = aRaw[i]; - /// @solidity memory-safe-assembly - assembly { - addr := addrRaw - } - a[i] = addr; - } - // Make a copy of the `a` and perform insertion sort on it. - address[] memory aCopy = _copy(a); - LibSort.insertionSort(aCopy); - LibSort.sort(a); - assertEq(a, aCopy); - } - } - - function testSortAddressesPsuedorandom(uint256) public { - unchecked { - address[] memory a = _randomAddresses(100); - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortAddressesPsuedorandom() public { - testSortAddressesPsuedorandom(123456789); - } - - function testSortAddressesSorted() public { - unchecked { - uint256 n = 100; - address[] memory a = new address[](n); - for (uint256 i; i != n; ++i) { - a[i] = address(uint160(i)); - } - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortAddressesReversed() public { - unchecked { - uint256 n = 100; - address[] memory a = new address[](n); - for (uint256 i; i != n; ++i) { - a[i] = address(uint160(999 - i)); - } - LibSort.sort(a); - assertTrue(_isSorted(a)); - } - } - - function testSortOriginalPsuedorandom(uint256) public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = _random(); - } - _sortOriginal(a); - assertTrue(_isSorted(a)); - } - } - - function testSortOriginalPsuedorandom() public { - testSortOriginalPsuedorandom(123456789); - } - - function testSortOriginalSorted() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = i; - } - _sortOriginal(a); - assertTrue(_isSorted(a)); - } - } - - function testSortOriginalReversed() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = 999 - i; - } - _sortOriginal(a); - assertTrue(_isSorted(a)); - } - } - - function testSortOriginalMostlySame() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = i % 8 == 0 ? i : 0; - } - _sortOriginal(a); - assertTrue(_isSorted(a)); - } - } - - function testUniquifySorted() public { - uint256[] memory a = new uint256[](5); - a[0] = 1; - a[1] = 1; - a[2] = 3; - a[3] = 3; - a[4] = 5; - LibSort.uniquifySorted(a); - assertTrue(_isSortedAndUniquified(a)); - assertEq(a.length, 3); - } - - function testUniquifySortedWithEmptyArray() public { - uint256[] memory a = new uint256[](0); - LibSort.uniquifySorted(a); - assertTrue(_isSortedAndUniquified(a)); - assertEq(a.length, 0); - } - - function testUniquifySortedAddress() public { - address[] memory a = new address[](10); - a[0] = address(0x1efF47bc3a10a45D4B230B5d10E37751FE6AA718); - a[1] = address(0x1efF47bc3a10a45D4B230B5d10E37751FE6AA718); - a[2] = address(0x1efF47bC3A10a45d4b630B5D10E37751FE6aA718); - a[3] = address(0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF); - a[4] = address(0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69); - a[5] = address(0x6813eb9362372Eef6200f3B1dbC3f819671cbA70); - a[6] = address(0xe1AB8145F7E55DC933d51a18c793F901A3A0b276); - a[7] = address(0xe1AB8145F7E55DC933d51a18c793F901A3A0b276); - a[8] = address(0xE1Ab8145F7e55Dc933D61a18c793f901A3a0B276); - a[9] = address(0xe1ab8145f7E55Dc933D61A18c793f901A3A0B288); - LibSort.uniquifySorted(a); - assertTrue(_isSortedAndUniquified(a)); - assertEq(a.length, 8); - } - - function testUniquifySorted(uint256) public { - uint256[] memory a = _randomUints(_randomArrayLength()); - LibSort.sort(a); - LibSort.uniquifySorted(a); - assertTrue(_isSortedAndUniquified(a)); - } - - function testUniquifySortedAddress(uint256) public { - address[] memory a = _randomAddresses(_randomArrayLength()); - LibSort.sort(a); - LibSort.uniquifySorted(a); - assertTrue(_isSortedAndUniquified(a)); - } - - function testUniquifySortedDifferential(uint256) public { - uint256 n = _randomArrayLength(); - uint256[] memory a = _randomUints(n); - LibSort.sort(a); - uint256[] memory aCopy = new uint256[](n); - for (uint256 i; i != n; ++i) { - aCopy[i] = a[i]; - } - LibSort.uniquifySorted(a); - _uniquifyOriginal(aCopy); - assertEq(a, aCopy); - } - - function testSearchSortedBasicCases() public { - uint256[] memory a = new uint256[](6); - a[0] = 0; - a[1] = 1; - a[2] = 2; - a[3] = 3; - a[4] = 4; - a[5] = 5; - (bool found, uint256 index) = LibSort.searchSorted(a, 2); - assertTrue(found); - assertEq(index, 2); - - a[0] = 0; - a[1] = 1; - a[2] = 2; - a[3] = 3; - a[4] = 4; - a[5] = 5; - (found, index) = LibSort.searchSorted(a, 5); - assertTrue(found); - assertEq(index, 5); - } - - function testSearchSortedEdgeCases() public { - uint256[] memory a = new uint256[](1); - a[0] = 2; - (bool found, uint256 index) = LibSort.searchSorted(a, 1); - assertFalse(found); - - a = new uint256[](2); - a[0] = 45; - a[1] = 46; - (found, index) = LibSort.searchSorted(a, 2); - assertFalse(found); - } - - function testSearchSortedWithEmptyArray() public { - uint256[] memory a = new uint256[](0); - (bool found, uint256 index) = LibSort.searchSorted(a, 1); - assertFalse(found); - assertEq(index, 0); - } - - function testSearchSortedElementNotInArray() public { - uint256[] memory a = new uint256[](5); - a[0] = 1; - a[1] = 2; - a[2] = 3; - a[3] = 4; - a[4] = 5; - (bool found, uint256 index) = LibSort.searchSorted(a, 0); - assertFalse(found); - assertEq(index, 0); - - a[0] = 15; - a[1] = 25; - a[2] = 35; - a[3] = 45; - a[4] = 55; - (found, index) = LibSort.searchSorted(a, 10); - assertFalse(found); - assertEq(index, 0); - (found, index) = LibSort.searchSorted(a, 20); - assertFalse(found); - assertEq(index, 0); - (found, index) = LibSort.searchSorted(a, 30); - assertFalse(found); - assertEq(index, 1); - (found, index) = LibSort.searchSorted(a, 40); - assertFalse(found); - assertEq(index, 2); - (found, index) = LibSort.searchSorted(a, 50); - assertFalse(found); - assertEq(index, 3); - (found, index) = LibSort.searchSorted(a, 60); - assertFalse(found); - assertEq(index, 4); - } - - function testSearchSortedElementInArray(uint256) public { - unchecked { - _misalignFreeMemoryPointer(); - uint256[] memory a = _randomUints(_randomNonZeroArrayLength()); - LibSort.sort(a); - if (_randomChance(2)) { - LibSort.uniquifySorted(a); - } - uint256 randomIndex = _random() % a.length; - uint256 value = a[randomIndex]; - (bool found, uint256 index) = LibSort.searchSorted(a, value); - if (_randomChance(16)) { - assertEq(LibSort.inSorted(a, value), found); - } - assertTrue(found); - assertEq(a[index], value); - } - } - - function testSearchSortedElementNotInArray(uint256) public { - unchecked { - _misalignFreeMemoryPointer(); - uint256[] memory a = _randomUints(_randomNonZeroArrayLength()); - LibSort.sort(a); - if (_randomChance(2)) { - LibSort.uniquifySorted(a); - } - uint256 randomIndex = _random() % a.length; - uint256 missingValue; - if (_randomChance(2)) { - if (_randomChance(2)) { - missingValue = a[randomIndex] + 1; - if (missingValue == 0) return; - } else { - missingValue = a[randomIndex] - 1; - if (missingValue == type(uint256).max) return; - } - if (_exists(a, missingValue)) return; - (bool found, uint256 index) = LibSort.searchSorted(a, missingValue); - assertFalse(found); - assertEq(a[index], a[_nearestIndexBefore(a, missingValue)]); - } else { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, missingValue) - missingValue := keccak256(0x00, 0x20) - } - (bool found,) = LibSort.searchSorted(a, missingValue); - assertFalse(found); - } - } - } - - function _exists(uint256[] memory a, uint256 x) internal pure returns (bool result) { - unchecked { - uint256 n = a.length; - for (uint256 i; i != n; ++i) { - if (a[i] == x) { - return true; - } - } - return false; - } - } - - function _nearestIndexBefore(uint256[] memory a, uint256 x) - internal - pure - returns (uint256 nearestIndex) - { - unchecked { - uint256 nearestDist = type(uint256).max; - uint256 n = a.length; - for (uint256 i; i != n; ++i) { - uint256 y = a[i]; - if (y > x) continue; - uint256 dist = x - y; - if (dist < nearestDist) { - nearestIndex = i; - nearestDist = dist; - } - } - } - } - - function testSearchSorted() public { - unchecked { - uint256 n = 100; - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; i++) { - a[i] = i; - } - for (uint256 i; i != n; i++) { - (bool found, uint256 index) = LibSort.searchSorted(a, i); - assertTrue(found); - assertEq(index, i); - } - } - } - - function testSearchSortedDifferential(uint256) public { - uint256[] memory a = _randomUints(_randomArrayLength()); - uint256 needle = _random(); - if (_randomChance(2) && a.length != 0) { - needle = a[_random() % a.length]; - } - (bool found, uint256 index) = LibSort.searchSorted(a, needle); - if (found) { - assertEq(a[index], needle); - } - LibSort.sort(a); - (found, index) = LibSort.searchSorted(a, needle); - assertEq(found, _exists(a, needle)); - if (found) { - assertEq(a[index], needle); - } - } - - function testSearchSortedInts() public { - unchecked { - uint256 n = 100; - int256[] memory a = new int256[](n); - for (uint256 i = 0; i != n; i++) { - a[i] = int256(i) - 50; - } - for (uint256 i; i != n; i++) { - (bool found, uint256 index) = LibSort.searchSorted(a, int256(i) - 50); - assertTrue(found); - assertEq(index, i); - } - } - } - - function testSearchSortedInts(int256[] memory a, int256 needle) public { - (bool found, uint256 index) = LibSort.searchSorted(a, needle); - if (found) { - assertEq(a[index], needle); - } - } - - function testSearchSortedAddresses() public { - unchecked { - uint256 n = 100; - address[] memory a = new address[](n); - for (uint256 i; i != n; i++) { - a[i] = address(uint160(i)); - } - for (uint256 i; i != n; i++) { - (bool found, uint256 index) = LibSort.searchSorted(a, address(uint160(i))); - assertTrue(found); - assertEq(index, i); - (found,) = LibSort.searchSorted(a, address(uint160(i + n))); - assertFalse(found); - } - } - } - - function testInsertionSortInts() public { - unchecked { - for (uint256 t; t != 16; ++t) { - int256[] memory a = _randomInts(_bound(_random(), 0, 8)); - LibSort.insertionSort(a); - assertTrue(_isSorted(a)); - } - } - } - - function testSortInts() public { - unchecked { - for (uint256 t; t != 16; ++t) { - int256[] memory a = _randomInts(_bound(_random(), 0, 64)); - LibSort.insertionSort(a); - assertTrue(_isSorted(a)); - } - } - } - - function testTwoComplementConversionSort(int256 a, int256 b) public { - uint256 w = 1 << 255; - /// @solidity memory-safe-assembly - assembly { - let aConverted := add(a, w) - let bConverted := add(b, w) - if iszero(lt(aConverted, bConverted)) { - let t := aConverted - aConverted := bConverted - bConverted := t - } - a := add(aConverted, w) - b := add(bConverted, w) - } - assertTrue(a <= b); - } - - function testReverse() public { - unchecked { - for (uint256 t; t != 16; ++t) { - uint256 n = _bound(_random(), 0, 8); - uint256[] memory a = new uint256[](n); - uint256[] memory reversed = new uint256[](n); - for (uint256 i; i != n; ++i) { - reversed[n - 1 - i] = (a[i] = _random()); - } - bytes32 originalHash = keccak256(abi.encode(a)); - LibSort.reverse(a); - assertEq(a, reversed); - LibSort.reverse(a); - assertEq(originalHash, keccak256(abi.encode(a))); - } - } - } - - function testCopy(uint256) public { - unchecked { - uint256[] memory a; - if (!_randomChance(32)) a = _randomUints(_random() % 4); - if (_randomChance(32)) _brutalizeMemory(); - uint256[] memory aCopy = LibSort.copy(a); - if (_randomChance(32)) _brutalizeMemory(); - assertEq(aCopy, a); - for (uint256 i; i != a.length; ++i) { - aCopy[i] *= 2; - } - for (uint256 i; i != a.length; ++i) { - assertEq(aCopy[i], a[i] * 2); - } - } - } - - function testSortedUnionDifferential(uint256) public { - (uint256[] memory a, uint256[] memory b) = _randomUintsPair(); - uint256[] memory c = LibSort.union(a, b); - assertTrue(_isSorted(c)); - assertEq(c, _unionOriginal(a, b)); - } - - function testSortedUnionDifferential() public { - unchecked { - for (uint256 t; t != 16; ++t) { - testSortedUnionDifferential(t); - } - } - } - - function testSortedUnionDifferentialInt(uint256) public { - (int256[] memory a, int256[] memory b) = _randomIntsPair(); - int256[] memory c = LibSort.union(a, b); - assertTrue(_isSorted(c)); - assertEq(c, _unionOriginal(a, b)); - } - - function testSortedIntersectionDifferential(uint256) public { - (uint256[] memory a, uint256[] memory b) = _randomUintsPair(); - uint256[] memory c = LibSort.intersection(a, b); - assertTrue(_isSorted(c)); - assertEq(c, _intersectionOriginal(a, b)); - } - - function testSortedIntersectionDifferential() public { - unchecked { - for (uint256 t; t != 16; ++t) { - testSortedIntersectionDifferential(t); - } - } - } - - function testSortedIntersectionDifferentialInt(uint256) public { - (int256[] memory a, int256[] memory b) = _randomIntsPair(); - int256[] memory c = LibSort.intersection(a, b); - assertTrue(_isSorted(c)); - assertEq(c, _intersectionOriginal(a, b)); - } - - function testSortedDifferenceDifferential(uint256) public { - (uint256[] memory a, uint256[] memory b) = _randomUintsPair(); - uint256[] memory c = LibSort.difference(a, b); - assertTrue(_isSorted(c)); - assertEq(c, _differenceOriginal(a, b)); - } - - function testSortedDifferenceDifferential() public { - unchecked { - for (uint256 t; t != 16; ++t) { - testSortedDifferenceDifferential(t); - } - } - } - - function testSortedDifferenceDifferentialInt(uint256) public { - (int256[] memory a, int256[] memory b) = _randomIntsPair(); - int256[] memory c = LibSort.difference(a, b); - assertTrue(_isSorted(c)); - assertEq(c, _differenceOriginal(a, b)); - } - - function testSortedDifferenceUnionIntersection(uint256) public { - unchecked { - bool found; - (uint256[] memory a, uint256[] memory b) = _randomUintsPair(); - - uint256[] memory aSubB = LibSort.difference(a, b); - assertTrue(_isSorted(aSubB)); - for (uint256 i; i != aSubB.length; ++i) { - (found,) = LibSort.searchSorted(a, aSubB[i]); - assertTrue(found); - (found,) = LibSort.searchSorted(b, aSubB[i]); - assertFalse(found); - } - for (uint256 i; i != b.length; ++i) { - (found,) = LibSort.searchSorted(aSubB, b[i]); - assertFalse(found); - } - - uint256[] memory bSubA = LibSort.difference(b, a); - assertTrue(_isSorted(bSubA)); - for (uint256 i; i != bSubA.length; ++i) { - (found,) = LibSort.searchSorted(b, bSubA[i]); - assertTrue(found); - (found,) = LibSort.searchSorted(a, bSubA[i]); - assertFalse(found); - } - for (uint256 i; i != a.length; ++i) { - (found,) = LibSort.searchSorted(bSubA, a[i]); - assertFalse(found); - } - - uint256[] memory aIntersectionB = LibSort.intersection(a, b); - for (uint256 i; i != aIntersectionB.length; ++i) { - (found,) = LibSort.searchSorted(b, aIntersectionB[i]); - assertTrue(found); - (found,) = LibSort.searchSorted(a, aIntersectionB[i]); - assertTrue(found); - } - - uint256[] memory aUnionB = LibSort.union(a, b); - uint256[] memory aSubBUnionBSubA = LibSort.union(aSubB, bSubA); - uint256[] memory emptySet; - assertEq(emptySet, LibSort.intersection(aSubB, bSubA)); - assertEq(emptySet, LibSort.intersection(aSubBUnionBSubA, aIntersectionB)); - assertEq(a, LibSort.union(aIntersectionB, aSubB)); - assertEq(b, LibSort.union(aIntersectionB, bSubA)); - assertEq(aIntersectionB, LibSort.intersection(b, a)); - assertEq(aUnionB, LibSort.union(b, a)); - assertEq(LibSort.union(aSubB, b), LibSort.union(b, aSubB)); - assertEq(LibSort.union(bSubA, a), LibSort.union(a, bSubA)); - assertEq(aUnionB, LibSort.union(aSubBUnionBSubA, aIntersectionB)); - } - } - - function testIsSortedDifferential(uint256) public { - unchecked { - uint256 n = _randomChance(2) ? _random() % 4 : _randomArrayLength(); - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = _random() % 4; - } - assertEq(LibSort.isSorted(a), _isSorted(a)); - LibSort.sort(a); - assertEq(LibSort.isSorted(a), _isSorted(a)); - if (n != 0) { - a[_random() % n] = 0; - if (_randomChance(2)) { - a[_random() % n] = a[_random() % n]; - } - } - assertEq(LibSort.isSorted(a), _isSorted(a)); - } - } - - function testIsSortedIntsDifferential(uint256) public { - unchecked { - uint256 n = _randomChance(2) ? _random() % 4 : _randomArrayLength(); - int256[] memory a = new int256[](n); - for (uint256 i; i != n; ++i) { - a[i] = int256(_random() % 4); - if (_randomChance(2)) { - a[i] = -a[i]; - } - } - assertEq(LibSort.isSorted(a), _isSorted(a)); - LibSort.sort(a); - assertEq(LibSort.isSorted(a), _isSorted(a)); - if (n != 0) { - a[_random() % n] = 0; - if (_randomChance(2)) { - a[_random() % n] = a[_random() % n]; - } - } - assertEq(LibSort.isSorted(a), _isSorted(a)); - } - } - - function testIsSortedAddressesDifferential(uint256) public { - unchecked { - uint256 n = _randomChance(2) ? _random() % 4 : _randomArrayLength(); - address[] memory a = new address[](n); - for (uint256 i; i != n; ++i) { - a[i] = address(uint160(_random() % 4)); - } - assertEq(LibSort.isSorted(a), _isSorted(a)); - LibSort.sort(a); - assertEq(LibSort.isSorted(a), _isSorted(a)); - if (n != 0) { - a[_random() % n] = address(0); - if (_randomChance(2)) { - a[_random() % n] = a[_random() % n]; - } - } - assertEq(LibSort.isSorted(a), _isSorted(a)); - } - } - - function testIsSortedAndUniquifiedDifferential(uint256) public { - unchecked { - uint256 n = _randomChance(2) ? _random() % 4 : _randomArrayLength(); - uint256[] memory a = new uint256[](n); - for (uint256 i; i != n; ++i) { - a[i] = _random() % 4; - } - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - LibSort.sort(a); - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - if (n != 0) { - a[_random() % n] = 0; - if (_randomChance(2)) { - a[_random() % n] = a[_random() % n]; - } - } - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - } - } - - function testIsSortedAndUniquifiedIntsDifferential(uint256) public { - unchecked { - uint256 n = _randomChance(2) ? _random() % 4 : _randomArrayLength(); - int256[] memory a = new int256[](n); - for (uint256 i; i != n; ++i) { - a[i] = int256(_random() % 4); - if (_randomChance(2)) { - a[i] = -a[i]; - } - } - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - LibSort.sort(a); - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - if (n != 0) { - a[_random() % n] = 0; - if (_randomChance(2)) { - a[_random() % n] = a[_random() % n]; - } - } - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - } - } - - function testIsSortedAndUniquifiedAddressesDifferential(uint256) public { - unchecked { - uint256 n = _randomChance(2) ? _random() % 4 : _randomArrayLength(); - address[] memory a = new address[](n); - for (uint256 i; i != n; ++i) { - a[i] = address(uint160(_random() % 4)); - } - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - LibSort.sort(a); - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - if (n != 0) { - a[_random() % n] = address(0); - if (_randomChance(2)) { - a[_random() % n] = a[_random() % n]; - } - } - assertEq(LibSort.isSortedAndUniquified(a), _isSortedAndUniquified(a)); - } - } - - function _unionOriginal(uint256[] memory a, uint256[] memory b) - private - pure - returns (uint256[] memory c) - { - unchecked { - c = new uint256[](a.length + b.length); - uint256 o; - for (uint256 i; i != a.length; ++i) { - c[o++] = a[i]; - } - for (uint256 i; i != b.length; ++i) { - c[o++] = b[i]; - } - LibSort.insertionSort(c); - LibSort.uniquifySorted(c); - } - } - - function _unionOriginal(int256[] memory a, int256[] memory b) - private - pure - returns (int256[] memory c) - { - unchecked { - c = new int256[](a.length + b.length); - uint256 o; - for (uint256 i; i != a.length; ++i) { - c[o++] = a[i]; - } - for (uint256 i; i != b.length; ++i) { - c[o++] = b[i]; - } - LibSort.insertionSort(c); - LibSort.uniquifySorted(c); - } - } - - function _intersectionOriginal(uint256[] memory a, uint256[] memory b) - private - pure - returns (uint256[] memory c) - { - unchecked { - c = new uint256[](a.length + b.length); - uint256 o; - bool found; - for (uint256 i; i != a.length; ++i) { - (found,) = LibSort.searchSorted(b, a[i]); - if (found) c[o++] = a[i]; - } - /// @solidity memory-safe-assembly - assembly { - mstore(c, o) - } - LibSort.insertionSort(c); - LibSort.uniquifySorted(c); - } - } - - function _intersectionOriginal(int256[] memory a, int256[] memory b) - private - pure - returns (int256[] memory c) - { - unchecked { - c = new int256[](a.length + b.length); - uint256 o; - bool found; - for (uint256 i; i != a.length; ++i) { - (found,) = LibSort.searchSorted(b, a[i]); - if (found) c[o++] = a[i]; - } - /// @solidity memory-safe-assembly - assembly { - mstore(c, o) - } - LibSort.insertionSort(c); - LibSort.uniquifySorted(c); - } - } - - function _differenceOriginal(uint256[] memory a, uint256[] memory b) - private - pure - returns (uint256[] memory c) - { - unchecked { - c = new uint256[](a.length + b.length); - uint256 o; - bool found; - for (uint256 i; i != a.length; ++i) { - (found,) = LibSort.searchSorted(b, a[i]); - if (!found) c[o++] = a[i]; - } - /// @solidity memory-safe-assembly - assembly { - mstore(c, o) - } - LibSort.insertionSort(c); - LibSort.uniquifySorted(c); - } - } - - function _differenceOriginal(int256[] memory a, int256[] memory b) - private - pure - returns (int256[] memory c) - { - unchecked { - c = new int256[](a.length + b.length); - uint256 o; - bool found; - for (uint256 i; i != a.length; ++i) { - (found,) = LibSort.searchSorted(b, a[i]); - if (!found) c[o++] = a[i]; - } - /// @solidity memory-safe-assembly - assembly { - mstore(c, o) - } - LibSort.insertionSort(c); - LibSort.uniquifySorted(c); - } - } - - function _isSorted(address[] memory a) private pure returns (bool) { - unchecked { - for (uint256 i = 1; i < a.length; ++i) { - if (a[i - 1] > a[i]) return false; - } - return true; - } - } - - function _isSorted(uint256[] memory a) private pure returns (bool) { - unchecked { - for (uint256 i = 1; i < a.length; ++i) { - if (a[i - 1] > a[i]) return false; - } - return true; - } - } - - function _isSorted(int256[] memory a) private pure returns (bool) { - unchecked { - for (uint256 i = 1; i < a.length; ++i) { - if (a[i - 1] > a[i]) return false; - } - return true; - } - } - - function _isSortedAndUniquified(uint256[] memory a) private pure returns (bool) { - if (a.length == 0) { - return true; - } - unchecked { - uint256 end = a.length - 1; - for (uint256 i = 0; i != end; ++i) { - if (a[i] >= a[i + 1]) { - return false; - } - } - return true; - } - } - - function _isSortedAndUniquified(int256[] memory a) private pure returns (bool) { - if (a.length == 0) { - return true; - } - unchecked { - uint256 end = a.length - 1; - for (uint256 i = 0; i != end; ++i) { - if (a[i] >= a[i + 1]) { - return false; - } - } - return true; - } - } - - function _isSortedAndUniquified(address[] memory a) private pure returns (bool) { - if (a.length == 0) { - return true; - } - unchecked { - uint256 end = a.length - 1; - for (uint256 i = 0; i != end; ++i) { - if (a[i] >= a[i + 1]) { - return false; - } - } - return true; - } - } - - function _sortOriginal(uint256[] memory a) internal pure { - _sortOriginal(a, 0, int256(a.length - 1)); - } - - function _sortOriginal(uint256[] memory arr, int256 left, int256 right) internal pure { - int256 i = left; - int256 j = right; - if (i == j) return; - uint256 pivot = arr[uint256(left + (right - left) / 2)]; - while (i <= j) { - while (arr[uint256(i)] < pivot) { - unchecked { - ++i; - } - } - while (pivot < arr[uint256(j)]) { - unchecked { - --j; - } - } - if (i <= j) { - (arr[uint256(i)], arr[uint256(j)]) = (arr[uint256(j)], arr[uint256(i)]); - unchecked { - ++i; - --j; - } - } - } - if (left < j) _sortOriginal(arr, left, j); - if (i < right) _sortOriginal(arr, i, right); - } - - function _copy(uint256[] memory a) private view returns (uint256[] memory b) { - /// @solidity memory-safe-assembly - assembly { - b := mload(0x40) - let n := add(shl(5, mload(a)), 0x20) - pop(staticcall(gas(), 4, a, n, b, n)) - mstore(0x40, add(b, n)) - } - } - - function _copy(int256[] memory a) private view returns (int256[] memory b) { - /// @solidity memory-safe-assembly - assembly { - b := mload(0x40) - let n := add(shl(5, mload(a)), 0x20) - pop(staticcall(gas(), 4, a, n, b, n)) - mstore(0x40, add(b, n)) - } - } - - function _copy(address[] memory a) private view returns (address[] memory b) { - /// @solidity memory-safe-assembly - assembly { - b := mload(0x40) - let n := add(shl(5, mload(a)), 0x20) - pop(staticcall(gas(), 4, a, n, b, n)) - mstore(0x40, add(b, n)) - } - } - - function _randomUints(uint256 n) private returns (uint256[] memory a) { - unchecked { - _misalignFreeMemoryPointer(); - /// @solidity memory-safe-assembly - assembly { - a := mload(0x40) - mstore(a, n) - mstore(0x40, add(add(0x20, a), shl(5, n))) - } - for (uint256 i; i != n; ++i) { - a[i] = _random(); - } - } - } - - function _randomAddresses(uint256 n) private returns (address[] memory a) { - unchecked { - _misalignFreeMemoryPointer(); - /// @solidity memory-safe-assembly - assembly { - a := mload(0x40) - mstore(a, n) - mstore(0x40, add(add(0x20, a), shl(5, n))) - } - for (uint256 i; i != n; ++i) { - a[i] = address(uint160(_random())); - } - } - } - - function _randomInts(uint256 n) private returns (int256[] memory a) { - unchecked { - uint256[] memory aRaw = _randomUints(n); - /// @solidity memory-safe-assembly - assembly { - a := aRaw - } - } - } - - function _uniquifyOriginal(uint256[] memory a) private pure { - if (a.length != 0) { - unchecked { - uint256 n = a.length; - uint256 i = 0; - for (uint256 j = 1; j < n; j++) { - if (a[i] != a[j]) { - i++; - a[i] = a[j]; - } - } - /// @solidity memory-safe-assembly - assembly { - mstore(a, add(i, 1)) - } - } - } - } - - function _randomUintsPair() private returns (uint256[] memory a, uint256[] memory b) { - uint256 r = _random(); - a = _randomUints(r & 7); - b = _randomUints((r >> 128) & 7); - LibSort.insertionSort(a); - LibSort.uniquifySorted(a); - LibSort.insertionSort(b); - LibSort.uniquifySorted(b); - } - - function _randomAddressesPair() private returns (address[] memory a, address[] memory b) { - uint256 r = _random(); - a = _randomAddresses(r & 7); - b = _randomAddresses((r >> 128) & 7); - LibSort.insertionSort(a); - LibSort.uniquifySorted(a); - LibSort.insertionSort(b); - LibSort.uniquifySorted(b); - } - - function _randomIntsPair() private returns (int256[] memory a, int256[] memory b) { - uint256 r = _random(); - a = _randomInts(r & 7); - b = _randomInts((r >> 128) & 7); - LibSort.insertionSort(a); - LibSort.uniquifySorted(a); - LibSort.insertionSort(b); - LibSort.uniquifySorted(b); - } - - function _randomArrayLength() internal returns (uint256 r) { - r = _random(); - /// @solidity memory-safe-assembly - assembly { - let m := 0x070707070707070707070707070707070f0f0f0f0f0f0f1f1f1f1f1f1f3f7fff - r := and(byte(1, r), byte(and(r, 31), m)) - } - } - - function _randomNonZeroArrayLength() internal returns (uint256 r) { - do { - r = _randomArrayLength(); - } while (r == 0); - } - - function testClean(uint256 n) public { - address[] memory a; - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, n) - n := and(n, 7) - a := mload(0x40) - mstore(a, n) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - mstore(0x20, i) - mstore(add(add(a, 0x20), shl(5, i)), keccak256(0x00, 0x40)) - } - mstore(0x40, add(add(a, 0x20), shl(5, n))) - } - address[] memory aCopy = LibSort.copy(a); - assertEq(a, aCopy); - LibSort.clean(a); - assertEq(a, aCopy); - assertEq(a.length, n); - uint256 orAll; - /// @solidity memory-safe-assembly - assembly { - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - mstore(0x20, i) - orAll := or(orAll, mload(add(add(a, 0x20), shl(5, i)))) - } - } - assertEq(orAll >> 160, 0); - } - - function testGroupSum() public { - uint256 n = 32; - uint256[] memory keys = new uint256[](n); - uint256[] memory values = new uint256[](n); - uint256 total; - unchecked { - for (uint256 i; i < n; ++i) { - keys[i] = (i + 1) % 7; - values[i] = i; - total += i; - } - } - LibSort.groupSum(keys, values); - assertEq(keys.length, 7); - assertEq(values.length, 7); - assertEq(_sum(values), total); - } - - function testGroupSum(bytes32) public { - if (_randomChance(2)) { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - uint256 n = _random() & 0x1f; - uint256[] memory keys = new uint256[](n); - uint256[] memory values = new uint256[](n); - unchecked { - for (uint256 i; i < n; ++i) { - uint256 k = _randomUniform() & 0xf; - uint256 v = _randomUniform() & 0xff; - keys[i] = k; - values[i] = v; - } - } - uint256 oriSum = _sum(values); - uint256[] memory uniqueKeys = LibSort.copy(keys); - LibSort.insertionSort(uniqueKeys); - LibSort.uniquifySorted(uniqueKeys); - uint256[] memory sums = new uint256[](uniqueKeys.length); - unchecked { - for (uint256 i; i < n; ++i) { - (, uint256 j) = LibSort.searchSorted(uniqueKeys, keys[i]); - sums[j] += values[i]; - } - } - LibSort.groupSum(keys, values); - _checkMemory(sums); - assertEq(keys, uniqueKeys); - assertEq(values, sums); - assertEq(_sum(sums), oriSum); - } - - function _sum(uint256[] memory a) internal pure returns (uint256 result) { - unchecked { - for (uint256 i; i < a.length; ++i) { - result += a[i]; - } - } - } - - function testHasDuplicateGas() public { - for (uint256 i = 1; i < 1024; i = i * 2) { - this._testHasDuplicateGas(i - 1); - this._testHasDuplicateGas(i); - } - } - - function testHasDuplicateOriginalGas() public { - for (uint256 i = 1; i < 1024; i = i * 2) { - this._testHasDuplicateOriginalGas(i - 1); - this._testHasDuplicateOriginalGas(i); - } - } - - function _testHasDuplicateGas(uint256 n) public { - assertEq(LibSort.hasDuplicate(_getTestHasDuplicateGasArray(n)), false); - } - - function _testHasDuplicateOriginalGas(uint256 n) public { - assertEq(_hasDuplicateOriginal(_getTestHasDuplicateGasArray(n)), false); - } - - function _getTestHasDuplicateGasArray(uint256 n) internal returns (uint256[] memory a) { - vm.pauseGasMetering(); - a = new uint256[](n); - for (uint256 i; i < n; ++i) { - a[i] = i; - } - vm.resumeGasMetering(); - } - - function testHasDuplicate(uint256[] memory a, uint256 r) public { - bytes32 aHash = keccak256(abi.encode(a)); - if (r & 1 != 0) _brutalizeMemory(); - if (r & 2 != 0) _misalignFreeMemoryPointer(); - bool computed = LibSort.hasDuplicate(a); - _checkMemory(a); - bool expected = _hasDuplicateOriginal(a); - _checkMemory(a); - assertEq(computed, expected); - _checkMemory(a); - assertEq(keccak256(abi.encode(a)), aHash); - if (r & 4 != 0) { - if (a.length >= 2) { - a[_randomUniform() % a.length] = a[_randomUniform() % a.length]; - aHash = keccak256(abi.encode(a)); - } - computed = LibSort.hasDuplicate(a); - expected = _hasDuplicateOriginal(a); - assertEq(computed, expected); - assertEq(keccak256(abi.encode(a)), aHash); - } - } - - function testHasDuplicate(uint256 r) public { - uint256[] memory a; - if (r & 1 != 0) _brutalizeMemory(); - if (r & 2 != 0) _misalignFreeMemoryPointer(); - if (r & 0xff00 != 0) a = _randomUints(_randomArrayLength()); - testHasDuplicate(a, _randomUniform()); - } - - function _hasDuplicateOriginal(uint256[] memory a) internal pure returns (bool) { - uint256[] memory b = LibSort.copy(a); - LibSort.sort(b); - LibSort.uniquifySorted(b); - return b.length != a.length; - } - - function testHasDuplicateHashmapCapacityTrick(uint256 n) public pure { - n = n & 0x7fffffff; - uint256 c; - /// @solidity memory-safe-assembly - assembly { - let w := not(0x1f) // `-0x20`. - let t := mul(0x30, n) - c := or(shr(1, t), t) - c := or(shr(2, c), c) - c := or(shr(4, c), c) - c := or(shr(8, c), c) - c := and(w, or(shr(16, c), c)) - c := add(0x20, c) - } - uint256 t = n + (n >> 1); - t |= t >> 1; - t |= t >> 2; - t |= t >> 4; - t |= t >> 8; - t |= t >> 16; - t |= t >> 32; - t |= t >> 64; - t |= t >> 128; - t += 1; - t = t << 5; - assert(c == t && n >> 31 == 0); - } - - function check_HasDuplicateHashmapCapacityTrickEquivalence(uint256 n) public pure { - testHasDuplicateHashmapCapacityTrick(n); - } -} diff --git a/grouperBot/lib/solady/test/LibStorage.t.sol b/grouperBot/lib/solady/test/LibStorage.t.sol deleted file mode 100644 index 1ef1c87..0000000 --- a/grouperBot/lib/solady/test/LibStorage.t.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibStorage} from "../src/utils/LibStorage.sol"; - -contract LibStorageTest is SoladyTest { - using LibStorage for *; - - uint256 private constant _BUMPED_STORAGE_REF_SLOT_SEED = 0xd4203f8b; - - function testBumpSlot(bytes32 s, uint256 c) public { - c = c & 0xffffffffffffffffff; - LibStorage.Bump storage bump = LibStorage.bump(s); - bump._current = c; - assertEq( - bump.slot(), - keccak256(abi.encodePacked(s, uint32(_BUMPED_STORAGE_REF_SLOT_SEED), uint216(c))) - ); - bump.invalidate(); - assertEq( - bump.slot(), - keccak256(abi.encodePacked(s, uint32(_BUMPED_STORAGE_REF_SLOT_SEED), uint216(c + 1))) - ); - } -} diff --git a/grouperBot/lib/solady/test/LibString.t.sol b/grouperBot/lib/solady/test/LibString.t.sol deleted file mode 100644 index 9afbdf0..0000000 --- a/grouperBot/lib/solady/test/LibString.t.sol +++ /dev/null @@ -1,1865 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract SimpleStringSetAndGet { - string public x; - - function setX(string calldata x_) public { - x = x_; - } -} - -contract SimpleStringSetAndGetWithStringStorage { - LibString.StringStorage internal _x; - - function setX(string calldata x_) public { - LibString.setCalldata(_x, x_); - } - - function x() public view returns (string memory) { - return LibString.get(_x); - } -} - -contract LibStringTest is SoladyTest { - function testSimpleStringSetAndGetGas() public { - _testSimpleStringSetAndGet(new SimpleStringSetAndGet()); - _testSimpleStringSetAndGet( - SimpleStringSetAndGet(address(new SimpleStringSetAndGetWithStringStorage())) - ); - } - - function _testSimpleStringSetAndGet(SimpleStringSetAndGet ss) internal { - _testSimpleStringSetAndGet(ss, string(new bytes(512))); - _testSimpleStringSetAndGet(ss, "123456789012345678901234567890"); - _testSimpleStringSetAndGet(ss, "1234567890123456789012345678901"); - _testSimpleStringSetAndGet(ss, "12345678901234567890123456789012"); - _testSimpleStringSetAndGet(ss, "123456789012345678901234567890123"); - _testSimpleStringSetAndGet( - ss, "123456789012345678901234567890123456789012345678901234567890" - ); - } - - function _testSimpleStringSetAndGet(SimpleStringSetAndGet ss, string memory s) internal { - ss.setX(s); - assertEq(ss.x(), s); - } - - function testToStringZero() public { - assertEq(LibString.toString(uint256(0)), "0"); - } - - function testToStringPositiveNumber() public { - assertEq(LibString.toString(uint256(4132)), "4132"); - } - - function testToStringUint256Max() public { - assertEq( - LibString.toString(type(uint256).max), - "115792089237316195423570985008687907853269984665640564039457584007913129639935" - ); - } - - function testToStringZeroBrutalized() public brutalizeMemory { - string memory s0 = LibString.toString(uint256(0)); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(0x40), not(0)) - mstore(0x40, add(mload(0x40), 0x20)) - } - string memory s1 = LibString.toString(uint256(0)); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(0x40), not(0)) - mstore(0x40, add(mload(0x40), 0x20)) - } - assertEq(s0, "0"); - assertEq(s1, "0"); - } - - function testToStringPositiveNumberBrutalized() public brutalizeMemory { - string memory s0 = LibString.toString(uint256(4132)); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(0x40), not(0)) - mstore(0x40, add(mload(0x40), 0x20)) - } - string memory s1 = LibString.toString(uint256(4132)); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(0x40), not(0)) - mstore(0x40, add(mload(0x40), 0x20)) - } - assertEq(s0, "4132"); - assertEq(s1, "4132"); - } - - function testToStringUint256MaxBrutalized() public brutalizeMemory { - string memory s0 = LibString.toString(type(uint256).max); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(0x40), not(0)) - mstore(0x40, add(mload(0x40), 0x20)) - } - string memory s1 = LibString.toString(type(uint256).max); - /// @solidity memory-safe-assembly - assembly { - mstore(mload(0x40), not(0)) - mstore(0x40, add(mload(0x40), 0x20)) - } - assertEq( - s0, "115792089237316195423570985008687907853269984665640564039457584007913129639935" - ); - assertEq( - s1, "115792089237316195423570985008687907853269984665640564039457584007913129639935" - ); - } - - function testToStringZeroRightPadded(uint256 x) public view brutalizeMemory { - _checkMemory(LibString.toString(x)); - } - - function testToStringSignedDifferential(int256 x) public brutalizeMemory { - assertEq(LibString.toString(x), _toStringSignedOriginal(x)); - } - - function testToStringSignedMemory(int256 x) public view brutalizeMemory { - _misalignFreeMemoryPointer(); - uint256 freeMemoryPointer; - /// @solidity memory-safe-assembly - assembly { - freeMemoryPointer := mload(0x40) - } - string memory str = LibString.toString(x); - /// @solidity memory-safe-assembly - assembly { - if lt(str, freeMemoryPointer) { revert(0, 0) } - } - _checkMemory(str); - } - - function testToStringSignedGas() public pure { - for (int256 x = -10; x < 10; ++x) { - LibString.toString(x); - } - } - - function testToStringSignedOriginalGas() public pure { - for (int256 x = -10; x < 10; ++x) { - _toStringSignedOriginal(x); - } - } - - function _toStringSignedOriginal(int256 x) internal pure returns (string memory) { - unchecked { - return x >= 0 - ? LibString.toString(uint256(x)) - : string(abi.encodePacked("-", LibString.toString(uint256(-x)))); - } - } - - function testToHexStringZero() public { - assertEq(LibString.toHexString(0), "0x00"); - } - - function testToHexStringPositiveNumber() public { - assertEq(LibString.toHexString(0x4132), "0x4132"); - } - - function testToHexStringUint256Max() public { - assertEq( - LibString.toHexString(type(uint256).max), - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - } - - function testToHexStringFixedLengthPositiveNumberLong() public { - assertEq( - LibString.toHexString(0x4132, 32), - "0x0000000000000000000000000000000000000000000000000000000000004132" - ); - } - - function testToHexStringFixedLengthPositiveNumberShort() public { - assertEq(LibString.toHexString(0x4132, 2), "0x4132"); - } - - function testToHexStringZeroRightPadded(uint256 x) public pure { - _checkMemory(LibString.toHexString(x)); - } - - function testToHexStringFixedLengthInsufficientLength() public { - vm.expectRevert(LibString.HexLengthInsufficient.selector); - this.toHexString(0x4132, 1); - } - - function toHexString(uint256 x, uint256 l) public pure returns (string memory) { - return LibString.toHexString(x, l); - } - - function testToHexStringFixedLengthUint256Max() public { - assertEq( - LibString.toHexString(type(uint256).max, 32), - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - } - - function testToHexStringFixedLengthZeroRightPadded(uint256 x, uint256 randomness) public pure { - uint256 minLength = (bytes(LibString.toHexString(x)).length - 2) * 2; - uint256 length = (randomness % 32) + minLength; - _checkMemory(LibString.toHexString(x, length)); - } - - function testFromAddressToHexString() public { - assertEq( - LibString.toHexString(0xA9036907dCcae6a1E0033479B12E837e5cF5a02f), - "0xa9036907dccae6a1e0033479b12e837e5cf5a02f" - ); - } - - function testAddressToHexStringZeroRightPadded(address x) public pure { - _checkMemory(LibString.toHexString(x)); - } - - function testFromAddressToHexStringWithLeadingZeros() public { - assertEq( - LibString.toHexString(0x0000E0Ca771e21bD00057F54A68C30D400000000), - "0x0000e0ca771e21bd00057f54a68c30d400000000" - ); - } - - function testToMinimalHexStringZero() public { - assertEq(LibString.toMinimalHexString(0), "0x0"); - } - - function testToMinimalHexStringPositiveNumber() public { - assertEq(LibString.toMinimalHexString(0x54132), "0x54132"); - assertEq(LibString.toMinimalHexString(0x4132), "0x4132"); - assertEq(LibString.toMinimalHexString(0x0123), "0x123"); - assertEq(LibString.toMinimalHexString(0x12), "0x12"); - assertEq(LibString.toMinimalHexString(0x1), "0x1"); - } - - function testToMinimalHexStringUint256Max() public { - assertEq( - LibString.toMinimalHexString(type(uint256).max), - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - } - - function testToMinimalHexStringZeroRightPadded(uint256 x) public pure { - _checkMemory(LibString.toMinimalHexString(x)); - } - - function testToMinimalHexStringNoPrefixZero() public { - assertEq(LibString.toMinimalHexStringNoPrefix(0), "0"); - } - - function testToMinimalHexStringNoPrefixPositiveNumber() public { - assertEq(LibString.toMinimalHexStringNoPrefix(0x54132), "54132"); - assertEq(LibString.toMinimalHexStringNoPrefix(0x4132), "4132"); - assertEq(LibString.toMinimalHexStringNoPrefix(0x0123), "123"); - assertEq(LibString.toMinimalHexStringNoPrefix(0x12), "12"); - assertEq(LibString.toMinimalHexStringNoPrefix(0x1), "1"); - } - - function testToMinimalHexStringNoPrefixUint256Max() public { - assertEq( - LibString.toMinimalHexStringNoPrefix(type(uint256).max), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - } - - function testToMinimalHexStringNoPrefixZeroRightPadded(uint256 x) public pure { - _checkMemory(LibString.toMinimalHexStringNoPrefix(x)); - } - - function testFromAddressToHexStringChecksummed() public { - // All caps. - assertEq( - LibString.toHexStringChecksummed(0x52908400098527886E0F7030069857D2E4169EE7), - "0x52908400098527886E0F7030069857D2E4169EE7" - ); - assertEq( - LibString.toHexStringChecksummed(0x8617E340B3D01FA5F11F306F4090FD50E238070D), - "0x8617E340B3D01FA5F11F306F4090FD50E238070D" - ); - // All lower. - assertEq( - LibString.toHexStringChecksummed(0xde709f2102306220921060314715629080e2fb77), - "0xde709f2102306220921060314715629080e2fb77" - ); - assertEq( - LibString.toHexStringChecksummed(0x27b1fdb04752bbc536007a920d24acb045561c26), - "0x27b1fdb04752bbc536007a920d24acb045561c26" - ); - // Normal. - assertEq( - LibString.toHexStringChecksummed(0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed), - "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed" - ); - assertEq( - LibString.toHexStringChecksummed(0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359), - "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359" - ); - assertEq( - LibString.toHexStringChecksummed(0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB), - "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB" - ); - assertEq( - LibString.toHexStringChecksummed(0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb), - "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb" - ); - } - - function testFromAddressToHexStringChecksummedDifferential(uint256 randomness) - public - brutalizeMemory - { - address r; - /// @solidity memory-safe-assembly - assembly { - r := randomness - } - string memory expectedResult = LibString.toHexString(r); - /// @solidity memory-safe-assembly - assembly { - let o := add(expectedResult, 0x22) - let hashed := keccak256(o, 40) - // forgefmt: disable-next-item - for { let i := 0 } iszero(eq(i, 20)) { i := add(i, 1) } { - let temp := byte(i, hashed) - let p := add(o, add(i, i)) - let c0 := byte(0, mload(p)) - let c1 := byte(1, mload(p)) - if and(gt(c1, 58), gt(and(temp, 15), 7)) { - mstore8(add(p, 1), sub(c1, 32)) - } - if and(gt(c0, 58), gt(shr(4, temp), 7)) { - mstore8(p, sub(c0, 32)) - } - } - } - string memory checksummed = LibString.toHexStringChecksummed(r); - _checkMemory(checksummed); - assertEq(checksummed, expectedResult); - } - - function testHexStringNoPrefixVariants(uint256 x, uint256 randomness) public brutalizeMemory { - string memory noPrefix = LibString.toHexStringNoPrefix(x); - _checkMemory(noPrefix); - string memory expectedResult = LibString.concat("0x", noPrefix); - string memory withPrefix = LibString.toHexString(x); - _checkMemory(withPrefix); - assertEq(withPrefix, expectedResult); - - uint256 length; - /// @solidity memory-safe-assembly - assembly { - length := add(shr(1, mload(noPrefix)), and(randomness, 63)) - } - _misalignFreeMemoryPointer(); - noPrefix = LibString.toHexStringNoPrefix(x, length); - _checkMemory(noPrefix); - expectedResult = LibString.concat("0x", noPrefix); - _misalignFreeMemoryPointer(); - withPrefix = LibString.toHexString(x, length); - _checkMemory(withPrefix); - assertEq(withPrefix, expectedResult); - - address xAddress; - /// @solidity memory-safe-assembly - assembly { - xAddress := x - } - _misalignFreeMemoryPointer(); - noPrefix = LibString.toHexStringNoPrefix(xAddress); - _checkMemory(noPrefix); - expectedResult = LibString.concat("0x", noPrefix); - _misalignFreeMemoryPointer(); - withPrefix = LibString.toHexString(xAddress); - _checkMemory(withPrefix); - assertEq(withPrefix, expectedResult); - } - - function testBytesToHexStringNoPrefix() public { - assertEq(LibString.toHexStringNoPrefix(""), ""); - assertEq(LibString.toHexStringNoPrefix("A"), "41"); - assertEq( - LibString.toHexStringNoPrefix("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), - "4142434445464748494a4b4c4d4e4f505152535455565758595a" - ); - } - - function testBytesToHexStringNoPrefix(bytes memory raw) public brutalizeMemory { - string memory converted = LibString.toHexStringNoPrefix(raw); - _checkMemory(converted); - unchecked { - bytes memory hexChars = "0123456789abcdef"; - for (uint256 i; i != raw.length; ++i) { - uint256 t = uint8(bytes1(raw[i])); - assertTrue(hexChars[t & 15] == bytes(converted)[i * 2 + 1]); - assertTrue(hexChars[(t >> 4) & 15] == bytes(converted)[i * 2]); - } - } - } - - function testBytesToHexString() public { - assertEq(LibString.toHexString(""), "0x"); - assertEq(LibString.toHexString("A"), "0x41"); - assertEq( - LibString.toHexString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), - "0x4142434445464748494a4b4c4d4e4f505152535455565758595a" - ); - } - - function testBytesToHexString(bytes memory raw) public brutalizeMemory { - string memory converted = LibString.toHexString(raw); - _checkMemory(converted); - unchecked { - bytes memory hexChars = "0123456789abcdef"; - for (uint256 i; i != raw.length; ++i) { - uint256 t = uint8(bytes1(raw[i])); - assertTrue(hexChars[t & 15] == bytes(converted)[i * 2 + 1 + 2]); - assertTrue(hexChars[(t >> 4) & 15] == bytes(converted)[i * 2 + 2]); - } - } - } - - function testStringIs7BitASCIIWithAllowedLookup() public { - uint128 allowed = LibString.to7BitASCIIAllowedLookup("0123456789"); - assertEq(LibString.is7BitASCII("", allowed), true); - assertEq(LibString.is7BitASCII("0", allowed), true); - assertEq(LibString.is7BitASCII("9", allowed), true); - assertEq(LibString.is7BitASCII("a", allowed), false); - assertEq(LibString.is7BitASCII("0123456789", allowed), true); - assertEq(LibString.is7BitASCII("0123456789a", allowed), false); - assertEq(LibString.is7BitASCII("a0123456789", allowed), false); - assertEq(LibString.is7BitASCII("", 0), true); - assertEq(LibString.is7BitASCII("1", 0), false); - } - - function testTo7BitASCIIAllowedLookup() public { - assertEq(LibString.to7BitASCIIAllowedLookup("0123456789"), LibString.DIGITS_7_BIT_ASCII); - assertEq( - LibString.to7BitASCIIAllowedLookup("abcdefghijklmnopqrstuvwxyz"), - LibString.LOWERCASE_7_BIT_ASCII - ); - } - - function testStringIs7BitASCIIWithAllowedLookupDifferential(bytes memory raw, uint128 allowed) - public - brutalizeMemory - { - string memory s = string(raw); - bytes32 hashBefore = keccak256(raw); - assertEq(LibString.is7BitASCII(s, allowed), _is7BitASCIIOriginal(s, allowed)); - assertEq(keccak256(raw), hashBefore); - /// @solidity memory-safe-assembly - assembly { - mstore(add(raw, add(0x20, mload(raw))), hashBefore) - } - assertEq(LibString.is7BitASCII(s, allowed), _is7BitASCIIOriginal(s, allowed)); - assertEq(keccak256(raw), hashBefore); - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(mload(add(raw, add(0x20, mload(raw)))), hashBefore)) { revert(0, 0) } - } - } - - function testStringIs7BitASCII() public { - assertEq(LibString.is7BitASCII(""), true); - bytes memory raw = new bytes(1); - for (uint256 i; i < 256; ++i) { - raw[0] = bytes1(uint8(i)); - assertEq(LibString.is7BitASCII(string(raw)), i < 128); - assertEq(LibString.is7BitASCII(string(raw)), _is7BitASCIIOriginal(string(raw))); - } - } - - function testStringIs7BitASCIIDifferential(bytes memory raw) public brutalizeMemory { - string memory s = string(raw); - bytes32 hashBefore = keccak256(raw); - assertEq(LibString.is7BitASCII(s), _is7BitASCIIOriginal(s)); - assertEq(keccak256(raw), hashBefore); - /// @solidity memory-safe-assembly - assembly { - mstore(add(raw, add(0x20, mload(raw))), hashBefore) - } - assertEq(LibString.is7BitASCII(s), _is7BitASCIIOriginal(s)); - assertEq(keccak256(raw), hashBefore); - /// @solidity memory-safe-assembly - assembly { - if iszero(eq(mload(add(raw, add(0x20, mload(raw)))), hashBefore)) { revert(0, 0) } - } - } - - function testStringRuneCountDifferential(string memory s) public { - assertEq(LibString.runeCount(s), _runeCountOriginal(s)); - } - - function testStringRuneCount() public { - unchecked { - string memory runes = new string(256); - for (uint256 i; i < 256; ++i) { - /// @solidity memory-safe-assembly - assembly { - mstore8(add(add(runes, 0x20), i), i) - } - } - for (uint256 i; i < 256; ++i) { - string memory s = _generateString(runes); - testStringRuneCountDifferential(s); - } - } - } - - function testStringReplaceShort() public { - assertEq(LibString.replace("abc", "", "_@"), "_@a_@b_@c_@"); - assertEq(LibString.replace("abc", "a", "_"), "_bc"); - assertEq(LibString.replace("abc", "b", "_"), "a_c"); - assertEq(LibString.replace("abc", "c", "_"), "ab_"); - assertEq(LibString.replace("abc", "ab", "_"), "_c"); - assertEq(LibString.replace("abc", "bc", "_"), "a_"); - assertEq(LibString.replace("abc", "ac", "_"), "abc"); - assertEq(LibString.replace("abc", "a", ""), "bc"); - assertEq(LibString.replace("abc", "", ""), "abc"); - assertEq(LibString.replace("abc", "d", "x"), "abc"); - } - - function testStringReplaceMedium() public { - // forgefmt: disable-next-item - string memory subject = "70708741044725766535585242414884609539555049888764130733849700923779599488691391677696419266840"; - string memory search = "46095395550498887641307338497009"; - string memory replacement = "320807383223517906783031356692334377159141"; - // forgefmt: disable-next-item - string memory expectedResult = "707087410447257665355852424148832080738322351790678303135669233437715914123779599488691391677696419266840"; - assertEq(LibString.replace(subject, search, replacement), expectedResult); - } - - function testStringReplaceLong() public { - // forgefmt: disable-next-item - string memory subject = "01234567890123456789012345678901_search_search_search_search_search_search_23456789012345678901234567890123456789_search_search_search_search_search_search"; - string memory search = "search_search_search_search_search_search"; - string memory replacement = "REPLACEMENT_REPLACEMENT_REPLACEMENT_REPLACEMENT_REPLACEMENT"; - // forgefmt: disable-next-item - string memory expectedResult = "01234567890123456789012345678901_REPLACEMENT_REPLACEMENT_REPLACEMENT_REPLACEMENT_REPLACEMENT_23456789012345678901234567890123456789_REPLACEMENT_REPLACEMENT_REPLACEMENT_REPLACEMENT_REPLACEMENT"; - assertEq(LibString.replace(subject, search, replacement), expectedResult); - } - - function testStringReplace(uint256) public brutalizeMemory { - string memory filler = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory search = _generateString("abcdefghijklmnopqrstuvwxyz"); - string memory replacement = _generateString("0123456790_-+/=|{}<>!"); - if (bytes(search).length != 0) { - string memory subject; - subject = LibString.concat(subject, filler); - subject = LibString.concat(subject, search); - subject = LibString.concat(subject, filler); - subject = LibString.concat(subject, search); - subject = LibString.concat(subject, filler); - _misalignFreeMemoryPointer(); - string memory expectedResult; - expectedResult = LibString.concat(expectedResult, filler); - expectedResult = LibString.concat(expectedResult, replacement); - expectedResult = LibString.concat(expectedResult, filler); - expectedResult = LibString.concat(expectedResult, replacement); - expectedResult = LibString.concat(expectedResult, filler); - _misalignFreeMemoryPointer(); - string memory replaced = LibString.replace(subject, search, replacement); - _checkMemory(replaced); - assertEq(replaced, expectedResult); - } else { - string memory expectedResult; - expectedResult = LibString.concat(expectedResult, replacement); - expectedResult = LibString.concat(expectedResult, " "); - expectedResult = LibString.concat(expectedResult, replacement); - expectedResult = LibString.concat(expectedResult, " "); - expectedResult = LibString.concat(expectedResult, replacement); - expectedResult = LibString.concat(expectedResult, " "); - expectedResult = LibString.concat(expectedResult, replacement); - string memory replaced = LibString.replace(" ", search, replacement); - assertEq(replaced, expectedResult); - } - } - - function testStringIndexOf(uint256) public brutalizeMemory { - string memory filler0 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory filler1 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory search = _generateString("abcdefghijklmnopqrstuvwxyz"); - - string memory subject = string(bytes.concat(bytes(filler0), bytes(search), bytes(filler1))); - - uint256 from = _generateFrom(subject); - - if (bytes(search).length == 0) { - if (from > bytes(subject).length) { - assertEq(LibString.indexOf(subject, search, from), bytes(subject).length); - } else { - assertEq(LibString.indexOf(subject, search, from), from); - } - } else { - if (from > bytes(filler0).length) { - assertEq(LibString.indexOf(subject, search, from), LibString.NOT_FOUND); - } else { - assertEq(LibString.indexOf(subject, search, from), bytes(filler0).length); - } - } - } - - function testStringIndexOf() public { - string memory subject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - assertEq(LibString.indexOf(subject, ""), 0); - assertEq(LibString.indexOf(subject, "", 16), 16); - assertEq(LibString.indexOf(subject, "", 17), 17); - assertEq(LibString.indexOf(subject, "", 52), 52); - assertEq(LibString.indexOf(subject, "", 53), 52); - assertEq(LibString.indexOf(subject, "", 555), 52); - assertEq(LibString.indexOf(subject, "abc", 0), 0); - assertEq(LibString.indexOf(subject, "abc", 1), LibString.NOT_FOUND); - assertEq(LibString.indexOf(subject, "bcd"), 1); - assertEq(LibString.indexOf(subject, "XYZ"), 49); - assertEq(LibString.indexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW"), 16); - assertEq(LibString.indexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 16); - assertEq(LibString.indexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 16), 16); - assertEq( - LibString.indexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 17), - LibString.NOT_FOUND - ); - assertEq(LibString.indexOf("abcabcabc", "abc"), 0); - assertEq(LibString.indexOf("abcabcabc", "abc", 1), 3); - - assertEq(LibString.indexOf("a", "bcd"), LibString.NOT_FOUND); - assertEq(LibString.indexOf("a", "bcd", 0), LibString.NOT_FOUND); - assertEq(LibString.indexOf("accd", "bcd"), LibString.NOT_FOUND); - assertEq(LibString.indexOf("", "bcd"), LibString.NOT_FOUND); - } - - function testStringLastIndexOf(uint256) public brutalizeMemory { - string memory filler0 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory filler1 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory search = _generateString("abcdefghijklmnopqrstuvwxyz"); - - string memory subject = string(bytes.concat(bytes(filler0), bytes(search), bytes(filler1))); - - uint256 from = _generateFrom(subject); - - if (bytes(search).length == 0) { - if (from > bytes(subject).length) { - assertEq(LibString.lastIndexOf(subject, search, from), bytes(subject).length); - } else { - assertEq(LibString.lastIndexOf(subject, search, from), from); - } - } else { - if (from < bytes(filler0).length) { - assertEq(LibString.lastIndexOf(subject, search, from), LibString.NOT_FOUND); - } else { - assertEq(LibString.lastIndexOf(subject, search, from), bytes(filler0).length); - } - } - } - - function testStringLastIndexOf() public { - string memory subject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - assertEq(LibString.lastIndexOf(subject, "", 0), 0); - assertEq(LibString.lastIndexOf(subject, "", 16), 16); - assertEq(LibString.lastIndexOf(subject, "", 17), 17); - assertEq(LibString.lastIndexOf(subject, "", 52), 52); - assertEq(LibString.lastIndexOf(subject, "", 53), 52); - assertEq(LibString.lastIndexOf(subject, "", 555), 52); - assertEq(LibString.lastIndexOf(subject, "abc"), 0); - assertEq(LibString.lastIndexOf(subject, "abc", 0), 0); - assertEq(LibString.lastIndexOf(subject, "abc", 1), 0); - assertEq(LibString.lastIndexOf(subject, "abc", 3), 0); - assertEq(LibString.lastIndexOf(subject, "bcd"), 1); - assertEq(LibString.lastIndexOf(subject, "bcd", 1), 1); - assertEq(LibString.lastIndexOf(subject, "bcd", 0), LibString.NOT_FOUND); - assertEq(LibString.lastIndexOf(subject, "XYZ"), 49); - assertEq(LibString.lastIndexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW"), 16); - assertEq(LibString.lastIndexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 16); - assertEq(LibString.lastIndexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 52), 16); - assertEq(LibString.lastIndexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 51), 16); - assertEq(LibString.lastIndexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 16), 16); - assertEq( - LibString.lastIndexOf(subject, "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 15), - LibString.NOT_FOUND - ); - - assertEq(LibString.lastIndexOf("abcabcabc", "abc"), 6); - assertEq(LibString.lastIndexOf("abcabcabc", "abc", 5), 3); - - assertEq(LibString.lastIndexOf("a", "bcd"), LibString.NOT_FOUND); - assertEq(LibString.lastIndexOf("a", "bcd", 0), LibString.NOT_FOUND); - assertEq(LibString.lastIndexOf("accd", "bcd"), LibString.NOT_FOUND); - assertEq(LibString.lastIndexOf("", "bcd"), LibString.NOT_FOUND); - } - - function testContains() public { - string memory subject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - assertEq(LibString.contains(subject, "a"), true); - assertEq(LibString.contains(subject, "abc"), true); - assertEq(LibString.contains(subject, "z"), true); - assertEq(LibString.contains(subject, "Z"), true); - assertEq(LibString.contains(subject, "az"), false); - assertEq(LibString.contains(subject, "aZ"), false); - assertEq(LibString.contains(subject, "Aa"), false); - assertEq(LibString.contains(subject, "Zz"), false); - assertEq(LibString.contains(subject, "abcZ"), false); - assertEq(LibString.contains(subject, "abcz"), false); - assertEq(LibString.contains(subject, "abcA"), false); - assertEq(LibString.contains(subject, "abcB"), false); - assertEq(LibString.contains(subject, "abcC"), false); - assertEq(LibString.contains(subject, ""), true); - assertEq(LibString.contains("", "abc"), false); - assertEq(LibString.contains("", ""), true); - } - - function testStringStartsWith(uint256) public brutalizeMemory { - string memory filler = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory search = _generateString("abcdefghijklmnopqrstuvwxyz"); - - if (bytes(search).length == 0) { - string memory subject = string(bytes.concat(bytes(filler), bytes(search))); - assertEq(LibString.startsWith(subject, search), true); - } - - if (_random() & 1 == 1) { - string memory subject = string(bytes.concat(bytes(search), bytes(filler))); - assertEq(LibString.startsWith(subject, search), true); - } - - if (bytes(filler).length != 0 && bytes(search).length != 0) { - string memory subject = string(bytes.concat(bytes(filler), bytes(search))); - assertEq(LibString.startsWith(subject, search), false); - } - } - - function testStringStartsWith() public { - string memory subject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - assertEq(LibString.startsWith(subject, "abc"), true); - assertEq(LibString.startsWith(subject, "abcdefghijklmnopqrstuvwxyzABCDEFG"), true); - assertEq(LibString.startsWith(subject, "bcd"), false); - assertEq(LibString.startsWith(subject, "bcdefghijklmnopqrstuvwxyzABCDEFGH"), false); - - assertEq(LibString.startsWith("", ""), true); - assertEq(LibString.startsWith("bc", ""), true); - assertEq(LibString.startsWith("bc", "bc"), true); - assertEq(LibString.startsWith("bc", "abc"), false); - assertEq(LibString.startsWith("", "abc"), false); - } - - function testStringEndsWith(uint256) public brutalizeMemory { - string memory filler = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory search = _generateString("abcdefghijklmnopqrstuvwxyz"); - - if (bytes(search).length == 0) { - string memory subject = string(bytes.concat(bytes(search), bytes(filler))); - assertEq(LibString.endsWith(subject, search), true); - } - - if (_random() & 1 == 1) { - string memory subject = string(bytes.concat(bytes(filler), bytes(search))); - assertEq(LibString.endsWith(subject, search), true); - } - - if (bytes(filler).length != 0 && bytes(search).length != 0) { - string memory subject = string(bytes.concat(bytes(search), bytes(filler))); - assertEq(LibString.endsWith(subject, search), false); - } - } - - function testStringEndsWith() public { - string memory subject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - assertEq(LibString.endsWith(subject, "XYZ"), true); - assertEq(LibString.endsWith(subject, "pqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), true); - assertEq(LibString.endsWith(subject, "WXY"), false); - assertEq(LibString.endsWith(subject, "opqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"), false); - - assertEq(LibString.endsWith("", ""), true); - assertEq(LibString.endsWith("bc", ""), true); - assertEq(LibString.endsWith("bc", "bc"), true); - assertEq(LibString.endsWith("bc", "abc"), false); - assertEq(LibString.endsWith("", "abc"), false); - } - - function testStringRepeat(string memory subject, uint256 times) public brutalizeMemory { - times = times % 8; - _misalignFreeMemoryPointer(); - string memory repeated = LibString.repeat(subject, times); - _checkMemory(repeated); - string memory expectedResult = _repeatOriginal(subject, times); - _checkMemory(repeated); - assertEq(repeated, expectedResult); - } - - function testStringRepeat() public { - assertEq(LibString.repeat("", 0), ""); - assertEq(LibString.repeat("", 100), ""); - assertEq(LibString.repeat("a", 0), ""); - assertEq(LibString.repeat("a", 1), "a"); - assertEq(LibString.repeat("a", 3), "aaa"); - assertEq(LibString.repeat("abc", 0), ""); - assertEq(LibString.repeat("abc", 1), "abc"); - assertEq(LibString.repeat("abc", 3), "abcabcabc"); - assertEq(LibString.repeat("efghi", 3), "efghiefghiefghi"); - } - - function testStringRepeatOriginal() public { - assertEq(_repeatOriginal("", 0), ""); - assertEq(_repeatOriginal("", 100), ""); - assertEq(_repeatOriginal("a", 0), ""); - assertEq(_repeatOriginal("a", 1), "a"); - assertEq(_repeatOriginal("a", 3), "aaa"); - assertEq(_repeatOriginal("abc", 0), ""); - assertEq(_repeatOriginal("abc", 1), "abc"); - assertEq(_repeatOriginal("abc", 3), "abcabcabc"); - assertEq(_repeatOriginal("efghi", 3), "efghiefghiefghi"); - } - - function testStringSlice(uint256) public brutalizeMemory { - string memory filler0 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory expectedResult = _generateString("abcdefghijklmnopqrstuvwxyz"); - string memory filler1 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - - string memory subject = - string(bytes.concat(bytes(filler0), bytes(expectedResult), bytes(filler1))); - - uint256 start = bytes(filler0).length; - uint256 end = start + bytes(expectedResult).length; - - _misalignFreeMemoryPointer(); - string memory slice = LibString.slice(subject, start, end); - _checkMemory(slice); - assertEq(slice, expectedResult); - } - - function testStringSlice(bytes calldata subject, uint256 start, uint256 end) - public - brutalizeMemory - { - _misalignFreeMemoryPointer(); - do { - start = _bound(_random(), 0, subject.length); - end = _bound(_random(), 0, subject.length); - } while (end < start); - _misalignFreeMemoryPointer(); - bytes memory slice = bytes(LibString.slice(string(subject), start, end)); - assertEq(slice, subject[start:end]); - } - - function testStringSlice() public { - assertEq(LibString.slice("", 0, 1), ""); - assertEq(LibString.slice("", 1, 0), ""); - assertEq(LibString.slice("", 0, 0), ""); - assertEq(LibString.slice("", 0), ""); - assertEq(LibString.slice("", 1), ""); - - assertEq(LibString.slice("a", 0), "a"); - assertEq(LibString.slice("a", 1), ""); - assertEq(LibString.slice("a", 3), ""); - - assertEq(LibString.slice("abc", 0), "abc"); - assertEq(LibString.slice("abc", 1), "bc"); - assertEq(LibString.slice("abc", 1, 2), "b"); - assertEq(LibString.slice("abc", 3), ""); - - string memory subject = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - assertEq(LibString.slice(subject, 0), subject); - assertEq(LibString.slice(subject, 1), "bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - assertEq( - LibString.slice(subject, 1, 51), "bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY" - ); - assertEq(LibString.slice(subject, 11, 41), "lmnopqrstuvwxyzABCDEFGHIJKLMNO"); - assertEq(LibString.slice(subject, 21, 31), "vwxyzABCDE"); - assertEq(LibString.slice(subject, 31, 21), ""); - } - - function testStringIndicesOf(uint256) public brutalizeMemory { - string memory filler0 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory filler1 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory search = _generateString("abcdefghijklmnopqrstuvwxyz"); - - string memory subject; - - unchecked { - uint256[] memory indices; - if (_random() & 1 == 0) { - subject = string(bytes.concat(bytes(filler0), bytes(search), bytes(filler1))); - indices = new uint256[](1); - indices[0] = bytes(filler0).length; - } else { - subject = string(bytes.concat(bytes(filler0), bytes(filler1))); - indices = new uint256[](0); - } - - if (bytes(search).length == 0) { - indices = new uint256[](bytes(subject).length + 1); - for (uint256 i; i < indices.length; ++i) { - indices[i] = i; - } - } - assertEq(LibString.indicesOf(subject, search), indices); - } - } - - function testStringIndicesOf() public { - uint256[] memory indices; - - indices = new uint256[](3); - indices[0] = 0; - indices[1] = 2; - indices[2] = 4; - assertEq(LibString.indicesOf("ababa", "a"), indices); - - indices = new uint256[](6); - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - indices[3] = 3; - indices[4] = 4; - indices[5] = 5; - assertEq(LibString.indicesOf("ababa", ""), indices); - - indices = new uint256[](2); - indices[0] = 1; - indices[1] = 3; - assertEq(LibString.indicesOf("ababa", "b"), indices); - - indices = new uint256[](2); - indices[0] = 0; - indices[1] = 2; - assertEq(LibString.indicesOf("ababa", "ab"), indices); - - indices = new uint256[](2); - indices[0] = 1; - indices[1] = 3; - assertEq(LibString.indicesOf("ababa", "ba"), indices); - - indices = new uint256[](1); - indices[0] = 1; - assertEq(LibString.indicesOf("ababa", "bab"), indices); - - indices = new uint256[](1); - indices[0] = 0; - assertEq(LibString.indicesOf("ababa", "ababa"), indices); - - indices = new uint256[](1); - indices[0] = 0; - assertEq(LibString.indicesOf("", ""), indices); - - indices = new uint256[](0); - assertEq(LibString.indicesOf("ababa", "c"), indices); - - indices = new uint256[](0); - assertEq(LibString.indicesOf("ababab", "abababa"), indices); - } - - function testStringSplit(uint256) public brutalizeMemory { - string memory filler0 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory filler1 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory delimiter = _generateString("abcdefghijklmnopqrstuvwxyz"); - - string memory subject = - string(bytes.concat(bytes(filler0), bytes(delimiter), bytes(filler1))); - - unchecked { - string[] memory elements; - if (bytes(delimiter).length == 0) { - elements = new string[](bytes(subject).length); - for (uint256 i; i < elements.length; ++i) { - elements[i] = LibString.slice(subject, i, i + 1); - } - } else { - elements = new string[](2); - elements[0] = filler0; - elements[1] = filler1; - } - _misalignFreeMemoryPointer(); - string[] memory split = LibString.split(subject, delimiter); - for (uint256 i; i < split.length; ++i) { - _checkMemory(split[i]); - } - assertTrue(_stringArraysAreSame(split, elements)); - } - } - - function testStringSplit() public { - string[] memory elements; - - elements = new string[](4); - elements[0] = ""; - elements[1] = "b"; - elements[2] = "b"; - elements[3] = ""; - assertTrue(_stringArraysAreSame(LibString.split("ababa", "a"), elements)); - - elements = new string[](3); - elements[0] = "a"; - elements[1] = "a"; - elements[2] = "a"; - assertTrue(_stringArraysAreSame(LibString.split("ababa", "b"), elements)); - - elements = new string[](5); - elements[0] = "a"; - elements[1] = "b"; - elements[2] = "a"; - elements[3] = "b"; - elements[4] = "a"; - assertTrue(_stringArraysAreSame(LibString.split("ababa", ""), elements)); - - elements = new string[](2); - elements[0] = "a"; - elements[1] = "b"; - assertTrue(_stringArraysAreSame(LibString.split("ab", ""), elements)); - - elements = new string[](1); - elements[0] = "ab"; - assertTrue(_stringArraysAreSame(LibString.split("ab", " "), elements)); - - elements = new string[](1); - elements[0] = "a"; - assertTrue(_stringArraysAreSame(LibString.split("a", ""), elements)); - - elements = new string[](0); - assertTrue(_stringArraysAreSame(LibString.split("", ""), elements)); - } - - function testStringConcat(string memory a, string memory b) public brutalizeMemory { - string memory concatenated = LibString.concat(a, b); - _checkMemory(concatenated); - string memory expectedResult = string(bytes.concat(bytes(a), bytes(b))); - assertEq(concatenated, expectedResult); - } - - function testStringConcat() public { - assertEq( - LibString.concat( - "bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY", - "12345678901234567890123456789012345678901234567890" - ), - "bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY12345678901234567890123456789012345678901234567890" - ); - assertEq(LibString.concat("", "b"), "b"); - assertEq(LibString.concat("", "b"), "b"); - assertEq(LibString.concat("a", "b"), "ab"); - assertEq(LibString.concat("a", ""), "a"); - assertEq(LibString.concat("", ""), ""); - } - - function testStringConcatOriginal() public { - assertEq( - string( - bytes.concat( - bytes("bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"), - bytes("12345678901234567890123456789012345678901234567890") - ) - ), - "bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY12345678901234567890123456789012345678901234567890" - ); - assertEq(string(bytes.concat(bytes(""), bytes("b"))), "b"); - assertEq(string(bytes.concat(bytes(""), bytes("b"))), "b"); - assertEq(string(bytes.concat(bytes("a"), bytes("b"))), "ab"); - assertEq(string(bytes.concat(bytes("a"), bytes(""))), "a"); - assertEq(string(bytes.concat(bytes(""), bytes(""))), ""); - } - - function testStringEscapeHTML() public { - assertEq(LibString.escapeHTML(""), ""); - assertEq(LibString.escapeHTML("abc"), "abc"); - assertEq(LibString.escapeHTML('abc"_123'), "abc"_123"); - assertEq(LibString.escapeHTML("abc&_123"), "abc&_123"); - assertEq(LibString.escapeHTML("abc'_123"), "abc'_123"); - assertEq(LibString.escapeHTML("abc<_123"), "abc<_123"); - assertEq(LibString.escapeHTML("abc>_123"), "abc>_123"); - } - - function testStringEscapeHTML(uint256) public brutalizeMemory { - string[] memory originalChars = new string[](5); - originalChars[0] = '"'; - originalChars[1] = "&"; - originalChars[2] = "'"; - originalChars[3] = "<"; - originalChars[4] = ">"; - - string[] memory escapedChars = new string[](5); - escapedChars[0] = """; - escapedChars[1] = "&"; - escapedChars[2] = "'"; - escapedChars[3] = "<"; - escapedChars[4] = ">"; - - string memory filler0 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - string memory filler1 = _generateString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - - uint256 r = _random() % 5; - - string memory expectedResult = - string(bytes.concat(bytes(filler0), bytes(escapedChars[r]), bytes(filler1))); - - string memory input = - string(bytes.concat(bytes(filler0), bytes(originalChars[r]), bytes(filler1))); - - _misalignFreeMemoryPointer(); - string memory escaped = LibString.escapeHTML(input); - _checkMemory(escaped); - - assertEq(expectedResult, escaped); - } - - function testStringEscapeJSON() public { - _checkStringEscapeJSON("", ""); - _checkStringEscapeJSON("abc", "abc"); - _checkStringEscapeJSON('abc"_123', 'abc\\"_123'); - _checkStringEscapeJSON("abc\\_123", "abc\\\\_123"); - _checkStringEscapeJSON("abc\x08_123", "abc\\b_123"); - _checkStringEscapeJSON("abc\x0c_123", "abc\\f_123"); - _checkStringEscapeJSON("abc\n_123", "abc\\n_123"); - _checkStringEscapeJSON("abc\r_123", "abc\\r_123"); - _checkStringEscapeJSON("abc\t_123", "abc\\t_123"); - } - - function _checkStringEscapeJSON(string memory s, string memory expected) internal { - assertEq(LibString.escapeJSON(s), expected); - assertEq(LibString.escapeJSON(s, false), expected); - assertEq(LibString.escapeJSON(s, true), string(bytes.concat('"', bytes(expected), '"'))); - } - - function testStringEscapeJSONHexEncode() public brutalizeMemory { - unchecked { - for (uint256 i; i <= 0x1f; ++i) { - if (i != 0x8 && i != 0x9 && i != 0x0a && i != 0x0c && i != 0x0d) { - string memory input = - string(bytes.concat(bytes("abc"), bytes1(uint8(i)), bytes("_123"))); - string memory hexCode = LibString.replace(LibString.toHexString(i), "0x", "00"); - string memory expectedOutput = - string(bytes.concat(bytes("abc\\u"), bytes(hexCode), bytes("_123"))); - string memory escaped = LibString.escapeJSON(input); - _checkMemory(escaped); - assertEq(escaped, expectedOutput); - } - } - } - } - - function testStringEncodeURIComponent() public { - string memory emptyString; - _testEncodeURIComponent(emptyString, ""); - _testEncodeURIComponent("", ""); - _testEncodeURIComponent("a", "a"); - _testEncodeURIComponent("ab", "ab"); - string memory encodeURIComponentSkippedCharacters = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'()"; - _testEncodeURIComponent( - encodeURIComponentSkippedCharacters, encodeURIComponentSkippedCharacters - ); - // All of these characters are encoded, they are reserved by URI standard - _testEncodeURIComponent(";/?:@&=+$,# ", "%3B%2F%3F%3A%40%26%3D%2B%24%2C%23%20"); - // Test unicode. - _testEncodeURIComponent(unicode"шеллы", "%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"); - _testEncodeURIComponent(unicode"😃", "%F0%9F%98%83"); - // Test space. - _testEncodeURIComponent("Hello World", "Hello%20World"); - _testEncodeURIComponent("Hello World!", "Hello%20World!"); - } - - function _testEncodeURIComponent(string memory input, string memory expectedOutput) internal { - assertEq(LibString.encodeURIComponent(input), expectedOutput); - } - - function testEncodeURIComponentDifferential(string memory s) public { - if (_randomChance(8)) _misalignFreeMemoryPointer(); - if (_randomChance(16)) _brutalizeMemory(); - bytes32 hashBefore = keccak256(bytes(s)); - string memory encoded = LibString.encodeURIComponent(s); - _checkMemory(encoded); - assertEq(encoded, _encodeURIComponentOriginal(s)); - if (_randomChance(8)) { - assertEq(_decodeURIComponentOriginal(encoded), s); - } - _checkMemory(encoded); - assertEq(keccak256(bytes(s)), hashBefore); - } - - // Original implementation of `_encodeURIComponentOriginal` - // credit to John Shankman aka White Lights - johnny@white-lights.net (whitelights.eth). - function _encodeURIComponentOriginal(string memory str) internal pure returns (string memory) { - bytes memory input = bytes(str); - uint256 inputLength = input.length; - uint256 outputLength = 0; - bytes memory TABLE = "0123456789ABCDEF"; - unchecked { - for (uint256 i = 0; i < inputLength; i++) { - bytes1 b = input[i]; - if ( - (b >= 0x30 && b <= 0x39) // 0-9 - || (b >= 0x41 && b <= 0x5a) // A-Z - || (b >= 0x61 && b <= 0x7a) // a-z - || b == 0x2D // - - || b == 0x5F // '_' - || b == 0x2E // . - || b == 0x21 // ! - || b == 0x7E // ~ - || b == 0x2A // * - || b == 0x27 // ' - || b == 0x28 // ( - || b == 0x29 // ) - ) { - outputLength++; - } else { - outputLength += 3; - } - } - - bytes memory output = new bytes(outputLength); - uint256 j = 0; - - for (uint256 i = 0; i < inputLength; i++) { - bytes1 b = input[i]; - - if ( - (b >= 0x30 && b <= 0x39) // 0-9 - || (b >= 0x41 && b <= 0x5a) // A-Z - || (b >= 0x61 && b <= 0x7a) // a-z - || b == 0x2D // - - || b == 0x5F // '_' - || b == 0x2E // . - || b == 0x21 // ! - || b == 0x7E // ~ - || b == 0x2A // * - || b == 0x27 // ' - || b == 0x28 // ( - || b == 0x29 // ) - ) { - output[j++] = b; - } else { - bytes1 b1 = TABLE[uint8(b) / 16]; - bytes1 b2 = TABLE[uint8(b) % 16]; - output[j++] = 0x25; // '%' - output[j++] = b1; - output[j++] = b2; - } - } - - return string(output); - } - } - - // Original implementation of `_decodeURIComponentOriginal` - // credit to John Shankman aka White Lights - johnny@white-lights.net (whitelights.eth). - // - // Since we don't currently have a clear onchain use case for decoding, - // we'll include this function in the test suite for completeness. - function _decodeURIComponentOriginal(string memory str) internal pure returns (string memory) { - string memory result = ""; - uint256 bytelength = bytes(str).length; - unchecked { - for (uint256 i = 0; i < bytelength; i++) { - bytes1 b = bytes(str)[i]; - // check if that character (as a byte1) is the "%" sign delimiter - if (b == bytes1("%")) { - // parse the two characters following the % delimiter - uint8 byteU8_1 = uint8(bytes(str)[++i]); - uint8 byteU8_2 = uint8(bytes(str)[++i]); - - // ensure they are characters 0-9 or A-F or a-f and therefore hexadecimal - require( - ( - (byteU8_1 >= 48 && byteU8_1 <= 57) || (byteU8_1 >= 65 && byteU8_1 <= 70) - || (byteU8_1 >= 97 && byteU8_1 <= 102) - ), - "invalid encoded string" - ); - require( - ( - (byteU8_2 >= 48 && byteU8_2 <= 57) || (byteU8_2 >= 65 && byteU8_2 <= 70) - || (byteU8_2 >= 97 && byteU8_2 <= 102) - ), - "invalid encoded string" - ); - - // convert the 1st char representing a hexadecimal to decimal - uint8 hexCharAsDecimal; - if (byteU8_1 >= 48 && byteU8_1 <= 57) { - // 0-9 - hexCharAsDecimal = byteU8_1 - 48; - } else if (byteU8_1 >= 65 && byteU8_1 <= 70) { - // A-F - hexCharAsDecimal = byteU8_1 - 55; - } else { - // a-f - hexCharAsDecimal = byteU8_1 - 87; - } - - // convert the 2nd char representing a hexadecimal to decimal - uint8 hexCharAsDecimal2; - if (byteU8_2 >= 48 && byteU8_2 <= 57) { - // 0-9 - hexCharAsDecimal2 = byteU8_2 - 48; - } else if (byteU8_2 >= 65 && byteU8_2 <= 70) { - // A-F - hexCharAsDecimal2 = byteU8_2 - 55; - } else { - // a-f - hexCharAsDecimal2 = byteU8_2 - 87; - } - - // 1st hex-char is a number words to move over - // 2nd hex-char is byte offset from there - // ex: %3E or %3e we move (3 * 16) + 14 bytes over - result = string( - abi.encodePacked( - result, bytes1((hexCharAsDecimal * 16) + hexCharAsDecimal2) - ) - ); - } else { - result = string(abi.encodePacked(result, string(abi.encodePacked(b)))); - } - } - return result; - } - } - - function testStringEq(string memory a, string memory b) public { - assertEq(LibString.eq(a, b), keccak256(bytes(a)) == keccak256(bytes(b))); - } - - function checkIsSN(string memory s) public pure returns (bool) { - // You can try replacing it with - // `return keccak256(bytes(s)) == keccak256("sn");` - // and see the bytecode size increase. - // This demonstrates that `eqs` does the compile time magic. - // Note that `s` must be in memory, not calldata. - return LibString.eqs(s, "sn"); - } - - function testStringEqs() public { - assertTrue(LibString.eqs("", "")); - assertTrue(LibString.eqs("1", "1")); - assertTrue(LibString.eqs("12", "12")); - assertTrue(LibString.eqs("123", "123")); - assertTrue(LibString.eqs("Hello", "Hello")); - assertTrue( - LibString.eqs("12345678901234567890123456789012", "12345678901234567890123456789012") - ); - - assertTrue(LibString.eqs("", hex"0061")); - assertTrue(LibString.eqs("a", hex"610061")); - assertTrue(LibString.eqs("aa", hex"61610061")); - - assertFalse(LibString.eqs("", "x")); - assertFalse(LibString.eqs("1", "2")); - assertFalse(LibString.eqs("Hello", "Hehe")); - assertFalse(LibString.eqs("12345678901234567890123456789012", "")); - - assertTrue(checkIsSN("sn")); - assertFalse(checkIsSN("x")); - } - - function testStringPackAndUnpackOneDifferential(string memory a) public brutalizeMemory { - a = LibString.slice(a, 0); - bytes32 packed = LibString.packOne(a); - unchecked { - if (bytes(a).length < 32) { - bytes memory expectedResultBytes = abi.encodePacked(uint8(bytes(a).length), a); - bytes32 expectedResult; - /// @solidity memory-safe-assembly - assembly { - expectedResult := mload(add(expectedResultBytes, 0x20)) - } - assertEq(packed, expectedResult); - } else { - assertEq(packed, bytes32(0)); - } - } - } - - function testStringPackAndUnpackOne(string memory a) public brutalizeMemory { - _misalignFreeMemoryPointer(); - bytes32 packed = LibString.packOne(a); - string memory unpacked = LibString.unpackOne(packed); - _checkMemory(unpacked); - - if (bytes(a).length < 32) { - assertEq(unpacked, a); - } else { - assertEq(packed, bytes32(0)); - assertEq(unpacked, ""); - } - } - - function testStringPackAndUnpackOne() public { - unchecked { - testStringPackAndUnpackOne(""); - testStringPackAndUnpackOne("Hehe"); - testStringPackAndUnpackOne("abcdefghijklmnopqrstuvwxyzABCD"); - testStringPackAndUnpackOne("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - } - } - - function testStringPackAndUnpackTwoDifferential(string memory a, string memory b) - public - brutalizeMemory - { - a = LibString.slice(a, 0); - b = LibString.slice(b, 0); - bytes32 packed = LibString.packTwo(a, b); - unchecked { - if (bytes(a).length + bytes(b).length < 31) { - bytes memory expectedResultBytes = - abi.encodePacked(uint8(bytes(a).length), a, uint8(bytes(b).length), b); - bytes32 expectedResult; - /// @solidity memory-safe-assembly - assembly { - expectedResult := mload(add(expectedResultBytes, 0x20)) - } - assertEq(packed, expectedResult); - } else { - assertEq(packed, bytes32(0)); - } - } - } - - function testStringPackAndUnpackTwo(string memory a, string memory b) public brutalizeMemory { - bytes32 packed = LibString.packTwo(a, b); - _misalignFreeMemoryPointer(); - (string memory unpackedA, string memory unpackedB) = LibString.unpackTwo(packed); - _checkMemory(unpackedA); - _checkMemory(unpackedB); - - unchecked { - if (bytes(a).length + bytes(b).length < 31) { - assertEq(unpackedA, a); - assertEq(unpackedB, b); - } else { - assertEq(packed, bytes32(0)); - assertEq(unpackedA, ""); - assertEq(unpackedB, ""); - } - } - } - - function testStringPackAndUnpackTwo() public { - unchecked { - testStringPackAndUnpackTwo("", ""); - testStringPackAndUnpackTwo("", ""); - testStringPackAndUnpackTwo("a", ""); - testStringPackAndUnpackTwo("", "b"); - testStringPackAndUnpackTwo("abcdefghijklmnopqrstuvwxyzABCD", ""); - testStringPackAndUnpackTwo("The strongest community I've ever seen", "NGL"); - testStringPackAndUnpackTwo("", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - } - } - - function testStringDirectReturn(string memory a) public { - assertEq(this.returnString(a), a); - } - - function testStringDirectReturn() public { - testStringDirectReturn(""); - testStringDirectReturn("aaa"); - testStringDirectReturn("98729"); - } - - function returnString(string memory a) external pure returns (string memory) { - LibString.directReturn(a); - } - - function testStringLowerDifferential(string memory s) public { - string memory expectedResult = _lowerOriginal(s); - _misalignFreeMemoryPointer(); - string memory result = LibString.lower(s); - _checkMemory(result); - assertEq(result, expectedResult); - } - - function testStringLowerDifferential() public { - unchecked { - string memory ascii = new string(128); - for (uint256 i; i < 128; ++i) { - /// @solidity memory-safe-assembly - assembly { - mstore8(add(add(ascii, 0x20), i), i) - } - } - for (uint256 i; i < 256; ++i) { - string memory s = _generateString(ascii); - testStringLowerDifferential(s); - } - } - } - - function testStringLowerOriginal() public { - assertEq(_lowerOriginal("@AZ["), "@az["); - } - - function testStringUpperDifferential(string memory s) public { - string memory expectedResult = _upperOriginal(s); - _misalignFreeMemoryPointer(); - string memory result = LibString.upper(s); - _checkMemory(result); - assertEq(result, expectedResult); - } - - function testStringUpperDifferential() public { - unchecked { - string memory ascii = new string(128); - for (uint256 i; i < 128; ++i) { - /// @solidity memory-safe-assembly - assembly { - mstore8(add(add(ascii, 0x20), i), i) - } - } - for (uint256 i; i < 256; ++i) { - string memory s = _generateString(ascii); - testStringUpperDifferential(s); - } - } - } - - function testStringUpperOriginal() public { - assertEq(_upperOriginal("`az}"), "`AZ}"); - } - - function fromSmallString() public { - assertEq(LibString.fromSmallString(bytes32("")), ""); - assertEq(LibString.fromSmallString(bytes32("a")), "a"); - assertEq(LibString.fromSmallString(bytes32("abc")), "abc"); - assertEq(LibString.fromSmallString(bytes32("Hello world!")), "Hello world!"); - } - - function testNormalizeSmallString() public { - bytes32 x; - bytes32 y; - assertEq(LibString.normalizeSmallString(x), y); - x = 0x1100000000000000000000000000000000000000000000000000000000000000; - y = 0x1100000000000000000000000000000000000000000000000000000000000000; - assertEq(LibString.normalizeSmallString(x), y); - x = 0x1100ff0000000000000000000000000000000000000000000000000000000000; - y = 0x1100000000000000000000000000000000000000000000000000000000000000; - assertEq(LibString.normalizeSmallString(x), y); - x = 0x1122ff0000000000000000000000000000000000000000000000000000000000; - y = 0x1122ff0000000000000000000000000000000000000000000000000000000000; - assertEq(LibString.normalizeSmallString(x), y); - x = 0x00000000000000000000000000000000000000000000000000000000000000ff; - y = 0x0000000000000000000000000000000000000000000000000000000000000000; - assertEq(LibString.normalizeSmallString(x), y); - x = 0x00ff0000000000000000000000000000000000000000000000000000000000ff; - y = 0x0000000000000000000000000000000000000000000000000000000000000000; - assertEq(LibString.normalizeSmallString(x), y); - } - - function testNormalizeSmallString(bytes32 x) public { - string memory y = LibString.fromSmallString(x); - bytes32 normalized = LibString.normalizeSmallString(x); - assertEq(LibString.toSmallString(y), normalized); - assertTrue(LibString.eqs(y, normalized)); - assertTrue(LibString.eqs(y, x)); - } - - function testToSmallString() public { - assertEq(LibString.toSmallString(""), ""); - assertEq(LibString.toSmallString("a"), "a"); - assertEq(LibString.toSmallString("ab"), "ab"); - assertEq(LibString.toSmallString("abc"), "abc"); - assertEq( - LibString.toSmallString("1234567890123456789012345678901"), - "1234567890123456789012345678901" - ); - assertEq( - LibString.toSmallString("12345678901234567890123456789012"), - "12345678901234567890123456789012" - ); - vm.expectRevert(LibString.TooBigForSmallString.selector); - this.toSmallString("123456789012345678901234567890123"); - } - - function toSmallString(string memory s) public pure returns (bytes32) { - return LibString.toSmallString(s); - } - - function testSetAndGetStringStorage() public { - string memory emptyString; - _testSetAndGetStringStorage(emptyString); - _testSetAndGetStringStorage(""); - _testSetAndGetStringStorage("a"); - _testSetAndGetStringStorage("ab"); - unchecked { - for (uint256 i = 0; i != 300; ++i) { - _testSetAndGetStringStorage(_randomUniformString(i), false); - } - } - } - - function testSetAndGetStringStorage(bytes32) public { - vm.pauseGasMetering(); - if (_randomChance(32)) { - assertTrue(LibString.isEmpty(_getStringStorage())); - assertEq(LibString.length(_getStringStorage()), 0); - assertEq(_get(_getStringStorage()), ""); - } - if (_randomChance(2)) _testSetAndGetStringStorage(string(_randomBytes())); - if (_randomChance(16)) _testSetAndGetStringStorage(string(_randomBytes())); - if (_randomChance(32)) { - _testSetAndGetStringStorage(_randomUniformString(_randomUniform() & 0xfff)); - } - vm.resumeGasMetering(); - } - - function testSetAndGetStringStorage2(string memory s) public { - _testSetAndGetStringStorage(s); - } - - function testSetAndGetStringStorageCalldata(string calldata s) public { - LibString.setCalldata(_getStringStorage(), s); - assertEq(LibString.get(_getStringStorage()), s); - } - - function _testSetAndGetStringStorage(string memory s) internal { - _testSetAndGetStringStorage(s, _randomChance(8)); - } - - function _testSetAndGetStringStorage(string memory s0, bool writeTo1) internal { - _set(_getStringStorage(0), s0); - string memory s1; - if (writeTo1) { - s1 = string(_randomBytes()); - _set(_getStringStorage(1), s1); - if (_randomChance(16)) { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - } - assertEq(_get(_getStringStorage(0)), s0); - if (writeTo1) { - assertEq(_get(_getStringStorage(1)), s1); - if (_randomChance(16)) _testClear(_getStringStorage(0)); - if (_randomChance(16)) _testClear(_getStringStorage(1)); - } - } - - function _testClear(LibString.StringStorage storage $) internal { - if (_randomChance(2)) { - LibString.clear($); - } else { - delete $._spacer; - } - assertEq(LibString.get($), ""); - assertTrue(LibString.isEmpty($)); - } - - function _set(LibString.StringStorage storage $, string memory s) internal { - LibString.set($, s); - assertEq(LibString.length($), bytes(s).length); - assertEq(LibString.isEmpty($), bytes(s).length == 0); - } - - function _get(LibString.StringStorage storage $) internal returns (string memory result) { - result = LibString.get($); - _checkMemory(result); - assertEq(LibString.isEmpty($), bytes(result).length == 0); - assertEq(LibString.length($), bytes(result).length); - } - - function _getStringStorage() internal pure returns (LibString.StringStorage storage) { - return _getStringStorage(0); - } - - function _getStringStorage(uint256 o) - internal - pure - returns (LibString.StringStorage storage $) - { - /// @solidity memory-safe-assembly - assembly { - $.slot := add(0x39be4c398aefe47a0e, o) - } - } - - function testUint8AtStringStorage(bytes calldata s, uint256 i) public { - LibString.setCalldata(_getStringStorage(0), string(s)); - uint8 retrieved = LibString.uint8At(_getStringStorage(0), i); - assertEq(retrieved, i < s.length ? uint8(s[i]) : 0); - } - - function testUint8AtStringStorage(bytes32) public { - uint256 i = _bound(_random(), 0, 1000); - this.testUint8AtStringStorage(_randomBytes(), i); - } - - function testUint8AtStringStorage() public { - this.testUint8AtStringStorage(hex"1122334455", 2); - this.testUint8AtStringStorage(new bytes(200), 2); - this.testUint8AtStringStorage(new bytes(500), 2); - } - - function _lowerOriginal(string memory subject) internal pure returns (string memory result) { - unchecked { - uint256 n = bytes(subject).length; - result = new string(n); - for (uint256 i; i != n; ++i) { - /// @solidity memory-safe-assembly - assembly { - let b := byte(0, mload(add(add(subject, 0x20), i))) - mstore8( - add(add(result, 0x20), i), add(b, mul(0x20, and(lt(0x40, b), lt(b, 0x5b)))) - ) - } - } - } - } - - function _upperOriginal(string memory subject) internal pure returns (string memory result) { - unchecked { - uint256 n = bytes(subject).length; - result = new string(n); - for (uint256 i; i != n; ++i) { - /// @solidity memory-safe-assembly - assembly { - let b := byte(0, mload(add(add(subject, 0x20), i))) - mstore8( - add(add(result, 0x20), i), sub(b, mul(0x20, and(lt(0x60, b), lt(b, 0x7b)))) - ) - } - } - } - } - - function _is7BitASCIIOriginal(string memory s) internal pure returns (bool) { - unchecked { - bytes memory sBytes = bytes(s); - for (uint256 i; i < sBytes.length; ++i) { - if (uint8(bytes1(sBytes[i])) > 127) return false; - } - return true; - } - } - - function _is7BitASCIIOriginal(string memory s, uint256 allowed) internal pure returns (bool) { - unchecked { - bytes memory sBytes = bytes(s); - for (uint256 i; i < sBytes.length; ++i) { - uint256 ord = uint8(bytes1(sBytes[i])); - if (ord > 127 || ((allowed >> ord) & 1) == 0) return false; - } - return true; - } - } - - function _runeCountOriginal(string memory s) internal pure returns (uint256) { - unchecked { - uint256 len; - uint256 i = 0; - uint256 bytelength = bytes(s).length; - for (len = 0; i < bytelength; len++) { - bytes1 b = bytes(s)[i]; - if (b < 0x80) { - i += 1; - } else if (b < 0xE0) { - i += 2; - } else if (b < 0xF0) { - i += 3; - } else if (b < 0xF8) { - i += 4; - } else if (b < 0xFC) { - i += 5; - } else { - i += 6; - } - } - return len; - } - } - - function _repeatOriginal(string memory subject, uint256 times) - internal - pure - returns (string memory) - { - unchecked { - string memory result; - if (!(times == 0 || bytes(subject).length == 0)) { - for (uint256 i; i < times; ++i) { - result = string(bytes.concat(bytes(result), bytes(subject))); - } - } - _misalignFreeMemoryPointer(); - return result; - } - } - - function _generateFrom(string memory subject) internal returns (uint256) { - unchecked { - if (_randomChance(8)) { - return _random(); - } - return _random() % (bytes(subject).length + 10); - } - } - - function _generateString(string memory byteChoices) internal returns (string memory result) { - uint256 randomness = _random(); - uint256 resultLength = _randomStringLength(); - /// @solidity memory-safe-assembly - assembly { - if mload(byteChoices) { - result := mload(0x40) - mstore(0x00, randomness) - mstore(0x40, and(add(add(result, 0x40), resultLength), not(31))) - mstore(result, resultLength) - - // forgefmt: disable-next-item - for { let i := 0 } lt(i, resultLength) { i := add(i, 1) } { - mstore(0x20, gas()) - mstore8( - add(add(result, 0x20), i), - mload(add(add(byteChoices, 1), mod(keccak256(0x00, 0x40), mload(byteChoices)))) - ) - } - } - } - } - - function _randomUniformString(uint256 n) internal returns (string memory result) { - uint256 randomness = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x20, randomness) - let o := add(result, 0x20) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(0x00, i) - mstore(add(o, i), keccak256(0x00, 0x40)) - } - mstore(result, n) - mstore(0x40, add(o, n)) - } - } - - function _randomStringLength() internal returns (uint256 r) { - r = _random() % 256; - if (r < 64) return _random() % 128; - if (r < 128) return _random() % 64; - return _random() % 16; - } - - function _stringArraysAreSame(string[] memory a, string[] memory b) - internal - pure - returns (bool) - { - unchecked { - if (a.length != b.length) { - return false; - } - for (uint256 i; i < a.length; ++i) { - if (keccak256(bytes(a[i])) != keccak256(bytes(b[i]))) { - return false; - } - } - return true; - } - } -} diff --git a/grouperBot/lib/solady/test/LibTransient.t.sol b/grouperBot/lib/solady/test/LibTransient.t.sol deleted file mode 100644 index 1a279d2..0000000 --- a/grouperBot/lib/solady/test/LibTransient.t.sol +++ /dev/null @@ -1,532 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "./utils/SoladyTest.sol"; -import {LibTransient} from "../src/utils/LibTransient.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; - -contract A { - address public immutable b; - - constructor() { - b = abi.decode(LibTransient.registryGet("b"), (address)); - } -} - -contract B { - address public immutable a; - - constructor() { - a = abi.decode(LibTransient.registryGet("a"), (address)); - } -} - -contract LibTransientTest is SoladyTest { - using LibTransient for *; - - function testSetAndGetBytesTransient() public { - vm.chainId(2); - _testSetAndGetBytesTransient("123"); - _testSetAndGetBytesTransient("12345678901234567890123456789012345678901234567890"); - _testSetAndGetBytesTransient("123"); - } - - function _testSetAndGetBytesTransient(bytes memory data) internal { - LibTransient.TBytes storage p = LibTransient.tBytes(uint256(0)); - p.setCompat(data); - assertEq(p.lengthCompat(), data.length); - assertEq(p.getCompat(), data); - } - - function testSetAndGetBytesTransientCalldata( - uint256 tSlot, - bytes calldata data0, - bytes calldata data1 - ) public { - vm.chainId(_randomUniform() & 3); - unchecked { - LibTransient.TBytes storage p0 = LibTransient.tBytes(tSlot); - LibTransient.TBytes storage p1 = LibTransient.tBytes(tSlot + 1); - if (_randomChance(2)) { - p0.setCalldataCompat(data0); - p1.setCalldataCompat(data1); - } else { - p0.setCompat(data0); - p1.setCompat(data1); - } - assertEq(p0.getCompat(), data0); - assertEq(p1.getCompat(), data1); - if (_randomChance(2)) { - p0.setCalldataCompat(data1); - p1.setCalldataCompat(data0); - } else { - p0.setCompat(data1); - p1.setCompat(data0); - } - assertEq(p0.getCompat(), data1); - assertEq(p1.getCompat(), data0); - p0.clearCompat(); - assertEq(p0.lengthCompat(), 0); - assertEq(p0.getCompat(), ""); - assertEq(p1.getCompat(), data0); - p1.clearCompat(); - assertEq(p1.lengthCompat(), 0); - assertEq(p1.getCompat(), ""); - assertEq(p0.lengthCompat(), 0); - assertEq(p0.getCompat(), ""); - } - } - - function testSetAndGetBytesTransient(uint256 tSlot, bytes memory data) public { - vm.chainId(_randomUniform() & 3); - LibTransient.TBytes storage p = LibTransient.tBytes(tSlot); - if (_randomChance(8)) data = _randomBytes(); - p.setCompat(data); - assertEq(p.lengthCompat(), data.length); - if (_randomChance(8)) { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - bytes memory retrieved = p.getCompat(); - _checkMemory(retrieved); - assertEq(retrieved, data); - p.clearCompat(); - assertEq(p.lengthCompat(), 0); - assertEq(p.getCompat(), ""); - } - - function testSetAndGetBytesTransientCalldata(uint256 tSlot, bytes calldata data) public { - vm.chainId(_randomUniform() & 3); - LibTransient.TBytes storage p = LibTransient.tBytes(tSlot); - p.setCompat(data); - assertEq(p.lengthCompat(), data.length); - assertEq(p.getCompat(), data); - p.clearCompat(); - assertEq(p.lengthCompat(), 0); - assertEq(p.getCompat(), ""); - } - - function testSetAndGetUint256Transient(uint256 tSlot, uint256 value) public { - vm.chainId(_randomUniform() & 3); - LibTransient.TUint256 storage p = LibTransient.tUint256(tSlot); - p.setCompat(value); - assertEq(p.getCompat(), value); - p.clearCompat(); - assertEq(p.getCompat(), 0); - } - - function testSetAndGetInt256Transient(uint256 tSlot, int256 value) public { - vm.chainId(_randomUniform() & 3); - LibTransient.TInt256 storage p = LibTransient.tInt256(tSlot); - p.setCompat(value); - assertEq(p.getCompat(), value); - p.clearCompat(); - assertEq(p.getCompat(), 0); - } - - function testSetAndGetAddressTransient(uint256 tSlot, address value) public { - vm.chainId(_randomUniform() & 3); - LibTransient.TAddress storage p = LibTransient.tAddress(tSlot); - p.setCompat(_brutalized(value)); - assertEq(p.getCompat(), value); - p.clearCompat(); - assertEq(p.getCompat(), address(0)); - } - - function testSetAndGetBytes32Transient(uint256 tSlot, bytes32 value) public { - vm.chainId(_randomUniform() & 3); - LibTransient.TBytes32 storage p = LibTransient.tBytes32(tSlot); - p.setCompat(value); - assertEq(p.getCompat(), value); - p.clearCompat(); - assertEq(p.getCompat(), bytes32(0)); - } - - function testSetAndGetBoolTransient(uint256 tSlot, bool value) public { - vm.chainId(_randomUniform() & 3); - LibTransient.TBool storage p = LibTransient.tBool(tSlot); - p.setCompat(_brutalized(value)); - assertEq(p.getCompat(), value); - p.clearCompat(); - assertEq(p.getCompat(), false); - } - - function testUint256IncDecTransient() public { - for (uint256 c; c < 3; ++c) { - vm.chainId(c); - uint256 tSlot; - LibTransient.TUint256 storage p = LibTransient.tUint256(tSlot); - p.setCompat(10); - assertEq(this.tUintIncCompat(tSlot), 11); - assertEq(p.getCompat(), 11); - assertEq(this.tUintIncCompat(tSlot, 20), 31); - assertEq(p.getCompat(), 31); - p.setCompat(2 ** 256 - 2); - assertEq(this.tUintIncCompat(tSlot), 2 ** 256 - 1); - assertEq(p.getCompat(), 2 ** 256 - 1); - vm.expectRevert(); - this.tUintIncCompat(tSlot); - vm.expectRevert(); - this.tUintIncCompat(tSlot, 10); - assertEq(this.tUintDecCompat(tSlot), 2 ** 256 - 2); - assertEq(p.getCompat(), 2 ** 256 - 2); - p.setCompat(10); - assertEq(this.tUintDecCompat(tSlot, 5), 5); - assertEq(p.getCompat(), 5); - assertEq(this.tUintDecCompat(tSlot, 5), 0); - assertEq(p.getCompat(), 0); - vm.expectRevert(); - this.tUintDecCompat(tSlot); - vm.expectRevert(); - this.tUintDecCompat(tSlot, 5); - p.setCompat(10); - assertEq(this.tUintIncSignedCompat(tSlot, 1), 11); - assertEq(p.getCompat(), 11); - assertEq(this.tUintIncSignedCompat(tSlot, -1), 10); - assertEq(p.getCompat(), 10); - assertEq(this.tUintDecSignedCompat(tSlot, 1), 9); - assertEq(p.getCompat(), 9); - assertEq(this.tUintDecSignedCompat(tSlot, -1), 10); - assertEq(p.getCompat(), 10); - } - } - - function tUintIncSignedCompat(uint256 tSlot, int256 delta) public returns (uint256) { - return LibTransient.tUint256(tSlot).incSignedCompat(delta); - } - - function tUintDecSignedCompat(uint256 tSlot, int256 delta) public returns (uint256) { - return LibTransient.tUint256(tSlot).decSignedCompat(delta); - } - - function tUintIncCompat(uint256 tSlot, uint256 delta) public returns (uint256) { - return LibTransient.tUint256(tSlot).incCompat(delta); - } - - function tUintDecCompat(uint256 tSlot, uint256 delta) public returns (uint256) { - return LibTransient.tUint256(tSlot).decCompat(delta); - } - - function tUintIncCompat(uint256 tSlot) public returns (uint256) { - return LibTransient.tUint256(tSlot).incCompat(); - } - - function tUintDecCompat(uint256 tSlot) public returns (uint256) { - return LibTransient.tUint256(tSlot).decCompat(); - } - - function tIntIncCompat(uint256 tSlot, int256 delta) public returns (int256) { - return LibTransient.tInt256(tSlot).incCompat(delta); - } - - function tIntDecCompat(uint256 tSlot, int256 delta) public returns (int256) { - return LibTransient.tInt256(tSlot).decCompat(delta); - } - - function tIntIncCompat(uint256 tSlot) public returns (int256) { - return LibTransient.tInt256(tSlot).incCompat(); - } - - function tIntDecCompat(uint256 tSlot) public returns (int256) { - return LibTransient.tInt256(tSlot).decCompat(); - } - - function testSetBytesTransientRevertsIfLengthTooBig(uint256 n) public { - n = _bound(n, 0x100000000, type(uint256).max); - vm.chainId(_randomUniform() & 3); - vm.expectRevert(); - this.setBytesTransientWithLengthTooBig(n); - } - - function testSetBytesTransientRevertsIfLengthTooBigCalldata(uint256 n) public { - n = _bound(n, 0x100000000, type(uint256).max); - vm.chainId(_randomUniform() & 3); - vm.expectRevert(); - this.setBytesTransientWithLengthTooBigCalldata(n); - } - - function setBytesTransientWithLengthTooBig(uint256 n) public { - bytes memory data; - /// @solidity memory-safe-assembly - assembly { - data := mload(0x40) - mstore(data, n) - mstore(0x40, add(data, 0x20)) - } - LibTransient.tBytes(uint256(0)).setCompat(data); - } - - function setBytesTransientWithLengthTooBigCalldata(uint256 n) public { - bytes calldata data; - /// @solidity memory-safe-assembly - assembly { - data.offset := 0 - data.length := n - } - LibTransient.tBytes(uint256(0)).setCalldataCompat(data); - } - - function testStackPlacePopBytes() public { - testStackPlacePopBytes(type(uint256).max, 0, 1); - } - - function testStackPlacePopBytes(uint256 r, uint256 aStackSlot, uint256 bStackSlot) public { - bytes[] memory aValues = new bytes[]((r >> 8) & 0x7); - bytes[] memory bValues = new bytes[]((r >> 16) & 0x7); - if (aStackSlot == bStackSlot) { - bStackSlot = aStackSlot ^ 1; - } - for (uint256 i; i < aValues.length; ++i) { - aValues[i] = abi.encodePacked(keccak256(abi.encode(i, aStackSlot)), "hehe"); - LibTransient.tStack(aStackSlot).place().tBytes().set(aValues[i]); - } - for (uint256 i; i < bValues.length; ++i) { - bValues[i] = abi.encodePacked(keccak256(abi.encode(i, bStackSlot))); - LibTransient.tStack(bStackSlot).place().tBytes().set(bValues[i]); - } - if (aValues.length > 0) { - bytes memory expected = aValues[aValues.length - 1]; - assertEq(LibTransient.tStack(aStackSlot).top().tBytes().get(), expected); - assertEq(LibTransient.tStack(aStackSlot).peek().tBytes().get(), expected); - assertGt(uint256(LibTransient.tStack(aStackSlot).peek()), 0); - } else { - assertEq(uint256(LibTransient.tStack(aStackSlot).peek()), 0); - assertEq(LibTransient.tStack(aStackSlot).peek().tBytes().get(), ""); - } - if (bValues.length > 0) { - bytes memory expected = bValues[bValues.length - 1]; - assertEq(LibTransient.tStack(bStackSlot).top().tBytes().get(), expected); - assertEq(LibTransient.tStack(bStackSlot).peek().tBytes().get(), expected); - assertGt(uint256(LibTransient.tStack(bStackSlot).peek()), 0); - } else { - assertEq(uint256(LibTransient.tStack(bStackSlot).peek()), 0); - assertEq(LibTransient.tStack(bStackSlot).peek().tBytes().get(), ""); - } - for (uint256 i; i < aValues.length; ++i) { - bytes memory expected = aValues[aValues.length - 1 - i]; - assertEq(LibTransient.tStack(aStackSlot).pop().tBytes().get(), expected); - } - for (uint256 i; i < bValues.length; ++i) { - bytes memory expected = bValues[bValues.length - 1 - i]; - assertEq(LibTransient.tStack(bStackSlot).pop().tBytes().get(), expected); - } - } - - function testStackPlacePopClear(bytes32 stackSlot) public { - uint256 n = _randomUniform() & 7; - for (uint256 i; i < n; ++i) { - assertEq(LibTransient.tStack(stackSlot).length(), i); - bytes32 x = keccak256(abi.encode(i)); - LibTransient.tStack(stackSlot).place().tBytes32().set(x); - assertEq(LibTransient.tStack(stackSlot).top().tBytes32().get(), x); - assertEq(LibTransient.tStack(stackSlot).peek().tBytes32().get(), x); - } - assertEq(LibTransient.tStack(stackSlot).length(), n); - - LibTransient.tStack(stackSlot).clear(); - assertEq(LibTransient.tStack(stackSlot).peek(), 0); - if (stackSlot != 0) { - assertEq(LibTransient.tStack(stackSlot).peek().tBytes32().get(), 0); - } - - assertEq(LibTransient.tStack(stackSlot).length(), 0); - for (uint256 i; i < n; ++i) { - assertEq(LibTransient.tStack(stackSlot).length(), i); - assertEq(LibTransient.tStack(stackSlot).place().tBytes32().get(), 0); - } - } - - function testStackPeekTrick(uint256 base, uint256 n, uint256 r) public pure { - check_StackPeekTrick(base, n, r); - } - - function check_StackPeekTrick(uint256 base, uint256 n, uint256 r) public pure { - n = (n & 0xffffffffffffffff) | 1; - unchecked { - uint256 s = base * 0x9e076501211e1371b + ((n * 0x100000000) | (r << 128)); - assert(s != 0); - } - } - - function testEmptyStackTopReverts() public { - vm.expectRevert(LibTransient.StackIsEmpty.selector); - this.stackTop(0); - } - - function testEmptyStackPopReverts() public { - vm.expectRevert(LibTransient.StackIsEmpty.selector); - this.stackPop(0); - } - - function stackTop(uint256 stackSlot) public view returns (bytes32) { - return LibTransient.tStack(stackSlot).top(); - } - - function stackPop(uint256 stackSlot) public returns (bytes32) { - return LibTransient.tStack(stackSlot).pop(); - } - - function testRegistry(bytes32 key, bytes memory value) public { - _etchTransientRegistry(); - if (_randomChance(2)) { - vm.expectRevert(bytes4(keccak256("TransientRegistryUnauthorized()"))); - this.registryClear(key); - } - - this.registrySet(key, value); - assertEq(this.registryGet(key), value); - assertEq(this.registryAdminOf(key), address(this)); - - if (_randomChance(2)) { - address newAdmin = _randomUniqueHashedAddress(); - vm.expectRevert(bytes4(keccak256("TransientRegistryUnauthorized()"))); - this.registrySet(newAdmin, key, value); - } - - if (_randomChance(2)) { - vm.expectRevert(bytes4(keccak256("TransientRegistryNewAdminIsZeroAddress()"))); - this.registryChangeAdmin(key, address(0)); - } - - if (_randomChance(2)) { - address newAdmin = _randomUniqueHashedAddress(); - uint256 newAdminRaw = uint256(uint160(newAdmin)); - if (_randomChance(2)) newAdminRaw |= _random() << 160; - - bool success; - if (newAdminRaw >> 160 == 0) { - if (_randomChance(2)) { - (success,) = LibTransient.REGISTRY.call( - abi.encodeWithSignature("changeAdmin(bytes32,address)", key, newAdminRaw) - ); - assertTrue(success); - } else { - this.registryChangeAdmin(key, newAdmin); - } - } else { - (success,) = LibTransient.REGISTRY.call( - abi.encodeWithSignature("changeAdmin(bytes32,address)", key, newAdminRaw) - ); - assertFalse(success); - newAdminRaw = (newAdminRaw << 96) >> 96; - (success,) = LibTransient.REGISTRY.call( - abi.encodeWithSignature("changeAdmin(bytes32,address)", key, newAdminRaw) - ); - assertTrue(success); - } - - assertEq(this.registryAdminOf(key), newAdmin); - if (_randomChance(2)) return; - - bytes memory anotherValue = _randomBytes(); - this.registrySet(newAdmin, key, anotherValue); - assertEq(this.registryGet(key), anotherValue); - assertEq(this.registryAdminOf(key), newAdmin); - - this.registryChangeAdmin(newAdmin, key, address(this)); - } - - if (_randomChance(2)) { - if (_randomChance(2)) this.registryClear(key); - bytes memory anotherValue = _randomBytes(); - this.registrySet(key, anotherValue); - assertEq(this.registryGet(key), anotherValue); - assertEq(this.registryAdminOf(key), address(this)); - } - - if (_randomChance(2)) { - this.registryClear(key); - vm.expectRevert(bytes4(keccak256("TransientRegistryKeyDoesNotExist()"))); - this.registryGet(key); - assertEq(this.registryAdminOf(key), address(0)); - - if (_randomChance(2)) return; - - address newAdmin = _randomUniqueHashedAddress(); - this.registrySet(newAdmin, key, value); - assertEq(this.registryGet(key), value); - assertEq(this.registryAdminOf(key), newAdmin); - } - } - - function testRegistryAB() public { - _etchTransientRegistry(); - bytes32 aInitCodeHash = keccak256(type(A).creationCode); - bytes32 bInitCodeHash = keccak256(type(B).creationCode); - address aAddress = LibClone.predictDeterministicAddress(aInitCodeHash, 0, _NICKS_FACTORY); - address bAddress = LibClone.predictDeterministicAddress(bInitCodeHash, 0, _NICKS_FACTORY); - this.registrySet("a", abi.encode(aAddress)); - this.registrySet("b", abi.encode(bAddress)); - A a = new A(); - B b = new B(); - assertEq(a.b(), bAddress); - assertEq(b.a(), aAddress); - } - - function testRegistryNotDeployed() public { - bytes memory value = _randomBytes(); - bytes memory empty; - - vm.expectRevert(empty); - this.registrySet(bytes32(_randomUniform()), value); - - vm.expectRevert(empty); - this.registryGet(bytes32(_randomUniform())); - - vm.expectRevert(empty); - this.registryClear(bytes32(_randomUniform())); - - vm.expectRevert(empty); - this.registryChangeAdmin(bytes32(_randomUniform()), _randomUniqueHashedAddress()); - - vm.expectRevert(empty); - this.registryAdminOf(bytes32(_randomUniform())); - } - - function registrySet(bytes32 hash, bytes memory value) public { - LibTransient.registrySet(hash, value); - _checkMemory(); - } - - function registrySet(address pranker, bytes32 hash, bytes memory value) public { - vm.prank(pranker); - registrySet(hash, value); - } - - function registryGet(bytes32 hash) public view returns (bytes memory result) { - result = LibTransient.registryGet(hash); - _checkMemory(result); - } - - function registryClear(address pranker, bytes32 hash) public { - vm.prank(pranker); - registryClear(hash); - } - - function registryClear(bytes32 hash) public { - LibTransient.registryClear(hash); - _checkMemory(); - } - - function registryChangeAdmin(address pranker, bytes32 hash, address newAdmin) public { - vm.prank(pranker); - registryChangeAdmin(hash, newAdmin); - } - - function registryChangeAdmin(bytes32 hash, address newAdmin) public { - LibTransient.registryChangeAdmin(hash, newAdmin); - _checkMemory(); - } - - function registryAdminOf(bytes32 hash) public view returns (address) { - return LibTransient.registryAdminOf(hash); - } - - function _etchTransientRegistry() internal { - bytes32 salt = 0x00000000000000000000000000000000000000001ef0fa4e834693009a3bcdbc; - bytes memory initializationCode = - hex"6080604052348015600e575f5ffd5b506104d48061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610064575f3560e01c806397040a451161004d57806397040a45146100b0578063aac438c0146100c3578063c5344411146100d6575f5ffd5b8063053b1ca3146100685780638eaa6ac014610090575b5f5ffd5b61007b610076366004610395565b61010e565b60405190151581526020015b60405180910390f35b6100a361009e3660046103db565b61016e565b60405161008791906103f2565b61007b6100be3660046103db565b610227565b61007b6100d1366004610427565b61029f565b6100e96100e43660046103db565b610361565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610087565b5f8161012157634396ac1b5f526004601cfd5b825f527f2c96949beeb8aca2ef85b169c5bca920576b836c1cb3edaa443380aff09df99b60205260405f20805c33146101615763860170335f526004601cfd5b82815d5060015f5260205ff35b6060815f527f2c96949beeb8aca2ef85b169c5bca920576b836c1cb3edaa443380aff09df99b60205260405f205c6101ad57639bdc798f5f526004601cfd5b7fc8f6675aac5818d398110f4d0e7276685c19f1a74e66eed262c8a6aa9aabaedf60205260405f20604051602081015f8152825c601c8201528051806020830101601d821061021757845f528260205f2003603c84015b8082015c81526020018281106102045750505b5f81526020845283810360200184f35b5f815f527f2c96949beeb8aca2ef85b169c5bca920576b836c1cb3edaa443380aff09df99b60205260405f2033815c146102685763860170335f526004601cfd5b5f815d507fc8f6675aac5818d398110f4d0e7276685c19f1a74e66eed262c8a6aa9aabaedf6020525f60405f205d60015f5260205ff35b5f835f527f2c96949beeb8aca2ef85b169c5bca920576b836c1cb3edaa443380aff09df99b60205260405f20805c80156102e7573381146102e75763860170335f526004601cfd5b5033815d507fc8f6675aac5818d398110f4d0e7276685c19f1a74e66eed262c8a6aa9aabaedf60205260405f20833560201c8360e01b17815d601d831061035757805f528284016020858560201c5f036020175f200301601c86015b80358282015d602001828110610343575050505b5060015f5260205ff35b5f815f527f2c96949beeb8aca2ef85b169c5bca920576b836c1cb3edaa443380aff09df99b60205260405f205c5f5260205ff35b5f5f604083850312156103a6575f5ffd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff811681146103d0575f5ffd5b809150509250929050565b5f602082840312156103eb575f5ffd5b5035919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f5f60408486031215610439575f5ffd5b83359250602084013567ffffffffffffffff811115610456575f5ffd5b8401601f81018613610466575f5ffd5b803567ffffffffffffffff81111561047c575f5ffd5b86602082840101111561048d575f5ffd5b93966020919091019550929350505056fea2646970667358221220af8785b9665e5c7f00368ff4d9720b2d4f4b6d2d9eb7be97936fba46cc7e6dcd64736f6c634300081c0033"; - address deployment = _nicksCreate2(0, salt, initializationCode); - assertEq(deployment, LibTransient.REGISTRY); - } -} diff --git a/grouperBot/lib/solady/test/LibZip.t.sol b/grouperBot/lib/solady/test/LibZip.t.sol deleted file mode 100644 index 34ff31d..0000000 --- a/grouperBot/lib/solady/test/LibZip.t.sol +++ /dev/null @@ -1,540 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MockCd, MockCdFallbackDecompressor} from "./utils/mocks/MockCd.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {ERC1967Factory} from "../src/utils/ERC1967Factory.sol"; -import {LibString} from "../src/utils/LibString.sol"; -import {DynamicBufferLib} from "../src/utils/DynamicBufferLib.sol"; -import {LibBytes} from "../src/utils/LibBytes.sol"; -import {LibZip} from "../src/utils/LibZip.sol"; - -contract LibZipTest is SoladyTest { - using LibBytes for LibBytes.BytesStorage; - using DynamicBufferLib for DynamicBufferLib.DynamicBuffer; - - LibBytes.BytesStorage internal _bytesStorage; - - struct ABC { - uint256 a; - uint256 b; - uint256 c; - } - - struct ABCPacked { - uint32 a; - uint64 b; - uint32 c; - } - - uint256 internal constant _A = 0x112233; - uint256 internal constant _B = 0x0102030405060708; - uint256 internal constant _C = 0xf1f2f3; - - ABC internal _abc; - ABCPacked internal _abcPacked; - - bytes internal constant _CD_COMPRESS_INPUT = - hex"00000000000000000000000000000000000000000000000000000000000ae11c0000000000000000000000000000000000000000000000000000002b9cdca0ab0000000000000000000000000000000000003961790f8baa365051889e4c367d00000000000000000000000000000000000026d85539440bc844167ac0cc42320000000000000000000000000000000000000000000000007b55939986433925"; - - bytes internal constant _CD_COMPRESS_OUTPUT = - hex"ffe3f51e1c001a2b9cdca0ab00113961790f8baa365051889e4c367d001126d85539440bc844167ac0cc423200177b55939986433925"; - - function testABCCdCompressAndDecompressGas() public { - bytes memory data = abi.encode(_A, _B, _C); - assertEq(LibZip.cdDecompress(LibZip.cdCompress(data)).length, data.length); - } - - function testABCCdCompressAndDecompressOriginalGas() public { - bytes memory data = abi.encode(_A, _B, _C); - assertEq(_cdDecompressOriginal(_cdCompressOriginal(data)).length, data.length); - } - - function testCdDecompressGas() public { - bytes memory data = _CD_COMPRESS_OUTPUT; - assertGt(LibZip.cdDecompress(data).length, data.length); - } - - function testCdDecompressOriginalGas() public { - bytes memory data = _CD_COMPRESS_OUTPUT; - assertGt(_cdDecompressOriginal(data).length, data.length); - } - - function testCdCompressGas() public { - bytes memory data = _CD_COMPRESS_INPUT; - assertLt(LibZip.cdCompress(data).length, data.length); - } - - function testCdCompressOriginalGas() public { - bytes memory data = _CD_COMPRESS_INPUT; - assertLt(_cdCompressOriginal(data).length, data.length); - } - - function testABCStoreWithCdCompressGas() public { - _bytesStorage.set(LibZip.cdCompress(abi.encode(_A, _B, _C))); - } - - function testABCStoreWithCdCompressOriginalGas() public { - _bytesStorage.set(_cdCompressOriginal(abi.encode(_A, _B, _C))); - } - - function testABCStoreWithFlzCompressGas() public { - _bytesStorage.set(LibZip.flzCompress(abi.encode(_A, _B, _C))); - } - - function testABCStoreGas() public { - _abc.a = _A; - _abc.b = _B; - _abc.c = _C; - } - - function testABCStorePackedGas() public { - _abcPacked.a = uint32(_A); - _abcPacked.b = uint64(_B); - _abcPacked.c = uint32(_C); - } - - function testCdCompressDifferential(bytes32) public { - bytes memory data; - if (_randomChance(8)) data = _randomCd(); - uint256 t = _randomUniform() % 4; - for (uint256 i; i < t; ++i) { - if (_randomChance(2)) data = abi.encodePacked(data, _random()); - if (_randomChance(2)) data = abi.encodePacked(data, new bytes(_random() & 0x3ff)); - if (_randomChance(2)) data = abi.encodePacked(data, _random()); - if (_randomChance(32)) data = abi.encodePacked(data, _randomCd()); - } - testCdCompressDifferential(data); - } - - function testCdCompressDifferential(bytes memory data) public { - if (_randomChance(32)) _misalignFreeMemoryPointer(); - if (_randomChance(32)) _brutalizeMemory(); - bytes memory computed = LibZip.cdCompress(data); - assertEq(computed, _cdCompressOriginal(data)); - } - - function testCdDecompressDifferential(bytes32) public { - bytes memory data = _randomCd(); - if (_randomChance(2)) { - testCdDecompressDifferential(LibZip.cdCompress(data)); - } else { - testCdDecompressDifferential(data); - } - } - - function testCdDecompressDifferential(bytes memory data) public { - assertEq(LibZip.cdDecompress(data), _cdDecompressOriginal(data)); - } - - function _cdCompressOriginal(bytes memory data) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - function rle(v_, o_, d_) -> _o, _d { - mstore(o_, shl(240, or(and(0xff, add(d_, 0xff)), and(0x80, v_)))) - _o := add(o_, 2) - } - result := mload(0x40) - let o := add(result, 0x20) - let z := 0 // Number of consecutive 0x00. - let y := 0 // Number of consecutive 0xff. - for { let end := add(data, mload(data)) } iszero(eq(data, end)) {} { - data := add(data, 1) - let c := byte(31, mload(data)) - if iszero(c) { - if y { o, y := rle(0xff, o, y) } - z := add(z, 1) - if eq(z, 0x80) { o, z := rle(0x00, o, 0x80) } - continue - } - if eq(c, 0xff) { - if z { o, z := rle(0x00, o, z) } - y := add(y, 1) - if eq(y, 0x20) { o, y := rle(0xff, o, 0x20) } - continue - } - if y { o, y := rle(0xff, o, y) } - if z { o, z := rle(0x00, o, z) } - mstore8(o, c) - o := add(o, 1) - } - if y { o, y := rle(0xff, o, y) } - if z { o, z := rle(0x00, o, z) } - // Bitwise negate the first 4 bytes. - mstore(add(result, 4), not(mload(add(result, 4)))) - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate the memory. - } - } - - function _cdDecompressOriginal(bytes memory data) internal pure returns (bytes memory result) { - /// @solidity memory-safe-assembly - assembly { - if mload(data) { - result := mload(0x40) - let o := add(result, 0x20) - let s := add(data, 4) - let v := mload(s) - let end := add(data, mload(data)) - mstore(s, not(v)) // Bitwise negate the first 4 bytes. - for {} lt(data, end) {} { - data := add(data, 1) - let c := byte(31, mload(data)) - if iszero(c) { - data := add(data, 1) - let d := byte(31, mload(data)) - // Fill with either 0xff or 0x00. - mstore(o, not(0)) - if iszero(gt(d, 0x7f)) { calldatacopy(o, calldatasize(), add(d, 1)) } - o := add(o, add(and(d, 0x7f), 1)) - continue - } - mstore8(o, c) - o := add(o, 1) - } - mstore(s, v) // Restore the first 4 bytes. - mstore(result, sub(o, add(result, 0x20))) // Store the length. - mstore(o, 0) // Zeroize the slot after the string. - mstore(0x40, add(o, 0x20)) // Allocate the memory. - } - } - } - - function testFlzCompressDecompress() public brutalizeMemory { - assertEq(LibZip.flzCompress(""), ""); - assertEq(LibZip.flzDecompress(""), ""); - bytes memory compressed = - hex"1f4e65772077617665206469676974616c206172742073686f756c64206e6f74201f6265206a756467656420736f6c656c79206f6e20616573746865746963206d65017269202301757420240e737420617320696d706f7274616e74202a1b666f7220697473206162696c69747920746f20646576656c6f702061200c406d03766973692051026f662020510320576972206801616e200301626f209315616c6c20637265617465206e6574776f726b20737069207201756140500e2e20416e6369656e7420477265656b60ba04697320686520bb01696e6051036869676820ad062072656761726420cd0463617573652095c089406f0220776820db03206d79742007016f6720a801686141040061401d0272656c2119066f6e2c206d6f72607660a0017761210a0866206c6966652e2054212f016768607c20ff026c6963205fa080414e40b80073402de003ae016365613741630373756666203320c8213406646973656e676141710366726f6d208b016520201102736f722097006f208e03666c6563205e21570b6f776e2070726f647563747340840065400d03626c656d406b056d6f6465726e417621120074201ba17a006d2066401f0272617420d521f00273656c200d805620118048036265617520e920e140c00561707065617220dc21fb41d5006d21310a69636820636f6e74726173208a02616273200920972142410a40450275732ce0081720852028016f798092056e616976652f40dd02756f752044057070726563696098c07a2072076578657274696e6760f3046e617475722172015265818b20dc02736c612025016279208e006d20400068212c60c701507221de2281026e7465409a201304207769746820a200652008426906696e766f6c7665808c20bf006e21940373657061811b4082227c2312e006dc620004616363656c20580074203e0165782062214b01697380bb2072026f207020a74009017569407a072c20656d626f647940c74080c2cf42ec01756e4183214c0273636921074204027261774029006f235905747275746873e2010c02636f6c42012139223c046f73706865410f025468724178205b2111016265603c830280ea0077228a02636869237e21c20172652144201d006f214e2047002ce0078140b620da2064c20f06696e64697669642377032065676f6175036163726922b6234060ee40d4e00b9a405c210121be205701756e2294208063fc23fa201583d040c0427523aa427021cf404f80ba20d04325016f6e21186297036966756c633c82fc21800061e1004f804e20a722f9052e2049206c6f20634488024e657443870d2053706972697475616c69747921"; - bytes memory decompressed = LibZip.flzDecompress(compressed); - bytes memory expectedDecompressed = - "New wave digital art should not be judged solely on aesthetic merit but just as importantly for its ability to develop a total vision of the Wired and above all create network spirituality. Ancient Greek art is held in the highest regard because it developed a whole mythology that shaped religion, morality and way of life. Thought is implicit in the art works of Ancient Greece but not sufficiently disengaged from the sensory to reflect its own products. The problem of modernity is the development of rational self reflection. The beauty of art appears in a form which contrasts abstract thought. Thus, abstract thought destroys the naive/sensuous appreciation of art in exerting its nature. Reality is slain by comprehension. Proper interaction with the wired involves the trance separation of real abstract thought and accelerates externalisation into pure intuition, embodying the network and unselfconsciously drawing out truths from the collective noosphere. Through this being on the wired we achieve a return to naive, unselfconscious interaction. The individual ego is sacrificed into the collective noosphere, uniting us under a totalising spirit. The best art in the wired is not only beautiful but produces a network spirituality. I long for Network Spirituality!"; - assertEq(decompressed, expectedDecompressed); - assertEq(LibZip.flzCompress(decompressed), compressed); - // Check backwards compatibility with older FastLZ releases. - compressed = - hex"1f4e65772077617665206469676974616c206172742073686f756c64206e6f74201f6265206a756467656420736f6c656c79206f6e20616573746865746963206d65017269202301757420240e737420617320696d706f7274616e74202a1b666f7220697473206162696c69747920746f20646576656c6f702061200c406d03766973692051026f662020510320576972206801616e200301626f209315616c6c20637265617465206e6574776f726b20737069207201756140500e2e20416e6369656e7420477265656b60ba04697320686520bb01696e6051036869676820ad062072656761726420cd0463617573652095c089406f0220776820db03206d79742007016f6720a801686141040061401d0272656c2119066f6e2c206d6f72607660a0017761210a0866206c6966652e2054212f016768607c20ff026c6963205fa080414e40b80073402de003ae016365613741630373756666203320c8213406646973656e676141710366726f6d208b016520201102736f722097006f208e03666c6563205e21570b6f776e2070726f647563747340840065400d03626c656d406b056d6f6465726e417621124044a17a006d2066401f0272617420d521f00273656c200d805620118048036265617520e920e140c00561707065617220dc21fb41d5006d21310a69636820636f6e74726173208a02616273200920972142410a40450275732ce0081720852028016f798092056e616976652f40dd02756f752044057070726563696098c07a2072076578657274696e6760f3046e617475722172015265818b20dc02736c612025016279208e006d20400068212c60c701507221de2281026e7465409a201304207769746820a200652008426906696e766f6c7665808c20bf006e21940373657061811b4082227c2312e006dc620004616363656c20580074203e0165782062214b01697380bb2072026f207020a74009017569407a072c20656d626f647940c74080c2cf42ec01756e4183214c0273636921074204027261774029006f235905747275746873e2010c02636f6c42012139223c046f73706865410f025468724178205b2111016265603c830280ea0077228a02636869237e21c20172652144201d006f214e2047002ce0078140b620da2064c20f06696e64697669642377032065676f6175036163726922b6234060ee40d4e00b9a405c210121be205701756e2294208063fc23fa201583d040c0427523aa427021cf404f80ba20d04325016f6e21186297036966756c633c82fc21800061e1004f804e20a722f9052e2049206c6f20634488004ea4400c53706972697475616c69747921"; - assertEq(LibZip.flzDecompress(compressed), decompressed); - } - - function _expandedData(bytes memory data) internal returns (bytes memory) { - unchecked { - DynamicBufferLib.DynamicBuffer memory buffer; - bytes memory r = abi.encode(_random()); - if (_randomChance(8)) { - r = abi.encodePacked(r, r, r, r); - r = bytes(LibString.slice(string(r), 0, _random() % r.length)); - } - uint256 n = _random() % 16 + 1; - uint256 c = _random(); - for (uint256 i; i < n; ++i) { - buffer.p((c >> i) & 1 == 0 ? r : data); - } - return buffer.data; - } - } - - function testFlzCompressDecompress(bytes memory data) public brutalizeMemory { - if (_randomChance(2)) { - data = _expandedData(data); - } - bytes32 dataHash = keccak256(data); - _misalignFreeMemoryPointer(); - bytes memory compressed = LibZip.flzCompress(data); - bytes32 compressedHash = keccak256(compressed); - _checkMemory(compressed); - _misalignFreeMemoryPointer(); - bytes memory decompressed = LibZip.flzDecompress(compressed); - _checkMemory(compressed); - _checkMemory(decompressed); - assertEq(decompressed, data); - assertEq(keccak256(data), dataHash); - assertEq(keccak256(compressed), compressedHash); - } - - function testFlzCompressDecompress2() public brutalizeMemory { - bytes memory data = - "______________________________________________________________e_______8______________________________________________________________________________________________________________________12_______8______________________________________________________________________________________________________________________16_______8______________________________________________________________________________________________________________________1a_______________________________________________________________2_____________________________________________732e2_5_726f2_49__73______________________________________________________________2_____________________________________________732e2_5_726f2_49__73______________________________________________________________2_____________________________________________732e2_5_726f2_49__73______________________________________________________________2_____________________________________________732e2_5_726f2_49__73"; - bytes32 dataHash = keccak256(data); - bytes memory expectedCompressed = - hex"015f5fe033010065a03c0038a007e06600013132a070e06f7f0036e0767f0061a07fe02f00c13fe01d000f37333265325f355f37323666325f34394011e01d39e00f00e0fd7fe02e7f04395f5f3733"; - bytes memory compressed = LibZip.flzCompress(data); - assertEq(compressed, expectedCompressed); - bytes32 compressedHash = keccak256(compressed); - _checkMemory(compressed); - bytes memory decompressed = LibZip.flzDecompress(compressed); - _checkMemory(compressed); - _checkMemory(decompressed); - assertEq(decompressed, data); - assertEq(keccak256(data), dataHash); - assertEq(keccak256(compressed), compressedHash); - } - - function testCdCompressDecompress(bytes memory data) public brutalizeMemory { - if (_randomChance(8)) { - data = _expandedData(data); - } - bytes32 dataHash = keccak256(data); - _misalignFreeMemoryPointer(); - bytes memory compressed = LibZip.cdCompress(data); - bytes32 compressedHash = keccak256(compressed); - _checkMemory(compressed); - _misalignFreeMemoryPointer(); - bytes memory decompressed = LibZip.cdDecompress(compressed); - _checkMemory(compressed); - _checkMemory(decompressed); - assertEq(decompressed, data); - assertEq(keccak256(data), dataHash); - assertEq(keccak256(compressed), compressedHash); - } - - function _randomCd() internal returns (bytes memory data) { - uint256 n = _randomChance(8) ? _random() % 2048 : _random() % 256; - data = new bytes(n); - if (_randomChance(32)) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(0x20, xor("randomUniform", i)) - mstore(add(add(data, 0x20), i), keccak256(0x00, 0x40)) - } - } - } - if (_randomChance(4)) { - /// @solidity memory-safe-assembly - assembly { - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(data, 0x20), i), not(0)) - } - } - } - if (_randomChance(16)) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) - mstore(0x20, xor("mode", not(0))) - let mode := and(1, keccak256(0x00, 0x40)) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(0x20, xor("mode", i)) - mode := xor(mode, iszero(and(keccak256(0x00, 0x40), 7))) - mstore(add(add(data, 0x20), i), mul(iszero(mode), not(0))) - } - } - } - if (_randomChance(16)) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(0x20, xor("0", i)) - let p := keccak256(0x00, 0x40) - if and(0x01, p) { mstore(add(add(data, 0x20), i), 0) } - } - } - } - if (_randomChance(16)) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(0x20, xor("not(0)", i)) - let p := keccak256(0x00, 0x40) - if and(0x10, p) { mstore(add(add(data, 0x20), i), not(0)) } - } - } - } - if (_randomChance(2)) { - if (n != 0) { - uint256 m = _random() % 8; - for (uint256 j; j < m; ++j) { - data[_random() % n] = bytes1(uint8(_random())); - } - } - } - } - - function testCdCompressDecompress(uint256) public brutalizeMemory { - unchecked { - bytes memory data = _randomCd(); - bytes memory compressed = LibZip.cdCompress(data); - bytes memory decompressed = LibZip.cdDecompress(compressed); - assertEq(decompressed, data); - } - } - - function testCdFallbackDecompressor(bytes memory data) public { - bytes memory compressed = LibZip.cdCompress(data); - MockCdFallbackDecompressor decompressor = new MockCdFallbackDecompressor(); - (, bytes memory result) = address(decompressor).call(compressed); - assertEq(abi.decode(result, (bytes32)), keccak256(data)); - } - - function testCdFallbackDecompressor(uint256) public { - bytes memory data = _randomCd(); - bytes memory compressed = LibZip.cdCompress(data); - MockCdFallbackDecompressor decompressor = new MockCdFallbackDecompressor(); - (, bytes memory result) = address(decompressor).call(compressed); - assertEq(abi.decode(result, (bytes32)), keccak256(data)); - } - - function testCdCompress() public { - assertEq(LibZip.cdCompress(""), ""); - assertEq(LibZip.cdDecompress(""), ""); - bytes memory data = - hex"ac9650d80000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000a40c49ccbe000000000000000000000000000000000000000000000000000000000005b70e00000000000000000000000000000000000000000000000000000dfc79825feb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000645c48a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084fc6f7865000000000000000000000000000000000000000000000000000000000005b70e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f1cdf1a632eaaab40d1c263edf49faf749010a1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064df2ab5bb0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f1cdf1a632eaaab40d1c263edf49faf749010a100000000000000000000000000000000000000000000000000000000"; - bytes memory expected = - hex"5369af27001e20001e04001e80001d0160001d0220001d02a0001ea40c49ccbe001c05b70e00190dfc79825feb005b645c48a7003a84fc6f7865001c05b70e002f008f000f008f003a4449404b7c002b1f1cdf1a632eaaab40d1c263edf49faf749010a1003a64df2ab5bb000b7f5c764cbc14f9669b88837ca1490cca17c31607002b1f1cdf1a632eaaab40d1c263edf49faf749010a1001b"; - assertEq(LibZip.cdCompress(data), expected); - } - - function testCdDecompressOnInvalidInput() public { - bytes memory data = hex"ffffffff00ff"; - bytes memory expected = - hex"0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - bytes memory decompressed = LibZip.cdDecompress(data); - assertEq(decompressed, expected); - } - - function testDecompressWontRevert(bytes memory data) public brutalizeMemory { - data = LibZip.cdDecompress(data); - bytes memory compressed = LibZip.cdCompress(data); - bytes memory decompressed = LibZip.cdDecompress(compressed); - assertEq(decompressed, data); - } - - function testCdFallback() public { - MockCd mockCd = new MockCd(); - _testCdFallback(mockCd); - // Check if it also works for clones. - mockCd = MockCd(payable(LibClone.clone(address(mockCd)))); - _testCdFallback(mockCd); - // Check if it also works for CWIA. - mockCd = MockCd(payable(LibClone.clone(address(mockCd), ""))); - _testCdFallback(mockCd); - // Check if it also works for ERC1967 proxies. - ERC1967Factory factory = new ERC1967Factory(); - mockCd = MockCd(payable(factory.deploy(address(mockCd), address(this)))); - _testCdFallback(mockCd); - } - - function _testCdFallback(MockCd mockCd) internal { - uint256[] memory numbers = new uint256[](100); - unchecked { - for (uint256 i; i < numbers.length; ++i) { - numbers[i] = i % 2 == 0 ? i : ~i; - } - } - assertEq(mockCd.numbersHash(), 0); - assertEq(mockCd.lastCallvalue(), 0); - assertEq(mockCd.lastCaller(), address(0)); - - uint256 callValue = 123 ether; - vm.deal(address(this), callValue * 2); - - (bool success, bytes memory result) = payable(mockCd).call{value: callValue}( - LibZip.cdCompress( - abi.encodeWithSignature("storeNumbersHash(uint256[],bool)", numbers, true) - ) - ); - - assertTrue(success); - bytes32 decodedNumbersHash = abi.decode(result, (bytes32)); - bytes32 expectedNumbersHash = keccak256(abi.encode(numbers)); - assertEq(decodedNumbersHash, expectedNumbersHash); - assertEq(mockCd.numbersHash(), expectedNumbersHash); - assertEq(mockCd.lastCallvalue(), callValue); - assertEq(mockCd.lastCaller(), address(this)); - assertEq(address(mockCd).balance, callValue); - - (success, result) = payable(mockCd).call{value: callValue}( - LibZip.cdCompress( - abi.encodeWithSignature("storeNumbersHash(uint256[],bool)", numbers, false) - ) - ); - - assertFalse(success); - assertEq(address(mockCd).balance, callValue); - assertEq(abi.encodeWithSelector(MockCd.Hash.selector, expectedNumbersHash), result); - assertEq(address(mockCd).balance, callValue); - - (success, result) = payable(mockCd).call{value: callValue}(""); - assertEq(address(mockCd).balance, callValue * 2); - assertTrue(success); - } - - function testCdFallback(bytes memory data, uint256 callValue) public brutalizeMemory { - MockCd mockCd = new MockCd(); - callValue = _bound(callValue, 0, 123 ether); - vm.deal(address(this), callValue * 2); - if (_randomChance(8)) { - data = _expandedData(data); - } - - (bool success, bytes memory result) = payable(mockCd).call{value: callValue}( - LibZip.cdCompress(abi.encodeWithSignature("storeDataHash(bytes,bool)", data, true)) - ); - - assertTrue(success); - bytes32 decodedDataHash = abi.decode(result, (bytes32)); - bytes32 expectedDataHash = keccak256(data); - assertEq(decodedDataHash, expectedDataHash); - assertEq(mockCd.dataHash(), expectedDataHash); - assertEq(mockCd.lastCallvalue(), callValue); - assertEq(mockCd.lastCaller(), address(this)); - assertEq(address(mockCd).balance, callValue); - - (success, result) = payable(mockCd).call{value: callValue}( - LibZip.cdCompress(abi.encodeWithSignature("storeDataHash(bytes,bool)", data, false)) - ); - - assertFalse(success); - assertEq(address(mockCd).balance, callValue); - assertEq(abi.encodeWithSelector(MockCd.Hash.selector, expectedDataHash), result); - assertEq(address(mockCd).balance, callValue); - - (success, result) = payable(mockCd).call{value: callValue}(""); - assertEq(address(mockCd).balance, callValue * 2); - assertTrue(success); - } - - function testCdFallbackMaskTrick(uint256 i, uint256 j) public { - i = _bound(i, 0, 2 ** 248 - 1); - uint256 a; - uint256 b; - /// @solidity memory-safe-assembly - assembly { - a := byte(0, xor(add(i, not(3)), j)) - b := xor(byte(i, shl(224, 0xffffffff)), byte(0, j)) - } - assertEq(a, b); - } - - function testCountLeadingNonZeroBytes(bytes32 s) public { - uint256 expected; - uint256 computed; - /// @solidity memory-safe-assembly - assembly { - let n := 0 - for {} byte(n, s) { n := add(n, 1) } {} // Scan for '\0'. - expected := n - let m := 0x7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F - let x := not(or(or(add(and(s, m), m), s), m)) - computed := 0x20 - if x { - let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := xor(31, or(shr(3, r), lt(0xff, shr(r, x)))) - computed := r - } - } - assertEq(computed, expected); - } -} diff --git a/grouperBot/lib/solady/test/Lifebuoy.t.sol b/grouperBot/lib/solady/test/Lifebuoy.t.sol deleted file mode 100644 index 2141368..0000000 --- a/grouperBot/lib/solady/test/Lifebuoy.t.sol +++ /dev/null @@ -1,318 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {Lifebuoy, MockLifebuoy, MockLifebuoyOwned} from "./utils/mocks/MockLifebuoy.sol"; -import {MockETHRecipient} from "./utils/mocks/MockETHRecipient.sol"; -import {MockERC20} from "./utils/mocks/MockERC20.sol"; -import {MockERC721} from "./utils/mocks/MockERC721.sol"; -import {MockERC1155} from "./utils/mocks/MockERC1155.sol"; -import {MockERC6909} from "./utils/mocks/MockERC6909.sol"; -import {LibRLP} from "../src/utils/LibRLP.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {SafeTransferLib} from "../src/utils/SafeTransferLib.sol"; - -contract LifebuoyTest is SoladyTest { - /// @dev Flag to denote that the deployer's access is locked. - uint256 internal constant _LIFEBUOY_DEPLOYER_ACCESS_LOCK = 1 << 0; - - /// @dev Flag to denote that the `owner()`'s access is locked. - uint256 internal constant _LIFEBUOY_OWNER_ACCESS_LOCK = 1 << 1; - - /// @dev Flag to denote that the `lockRescue` function is locked. - uint256 internal constant _LIFEBUOY_LOCK_RESCUE_LOCK = 1 << 2; - - /// @dev Flag to denote that the `rescueETH` function is locked. - uint256 internal constant _LIFEBUOY_RESCUE_ETH_LOCK = 1 << 3; - - /// @dev Flag to denote that the `rescueERC20` function is locked. - uint256 internal constant _LIFEBUOY_RESCUE_ERC20_LOCK = 1 << 4; - - /// @dev Flag to denote that the `rescueERC721` function is locked. - uint256 internal constant _LIFEBUOY_RESCUE_ERC721_LOCK = 1 << 5; - - MockERC20 erc20; - MockERC721 erc721; - MockERC1155 erc1155; - MockERC6909 erc6909; - - function setUp() public { - erc20 = new MockERC20("Name", "SYMBOL", 18); - erc721 = new MockERC721(); - erc1155 = new MockERC1155(); - erc6909 = new MockERC6909(); - } - - function _deployViaCreate(address deployer, bytes memory initcode) internal returns (address) { - (bool success, bytes memory result) = deployer.call(initcode); - assertTrue(success); - return abi.decode(result, (address)); - } - - function _testLifebuoyCreateDeployment(address deployer, bytes memory initcode) internal { - address expected = LibRLP.computeAddress(deployer, vm.getNonce(deployer)); - assertEq(_deployViaCreate(deployer, initcode), expected); - } - - function testLifebuoyCreateDeployment(address deployer, address owner, uint256 r) public { - while (deployer.code.length != 0 || uint160(deployer) < 0xffffffffff) { - deployer = _randomNonZeroAddress(); - } - vm.etch(deployer, hex"3d3d363d3d37363d34f09052602081f3"); - for (uint256 i; i != 3; ++i) { - r = r >> 32; - if (r & 31 == 0) { - _testLifebuoyCreateDeployment(deployer, type(MockERC721).creationCode); - continue; - } - r = r >> 8; - if (r & 1 == 0) { - bytes memory initcode = type(MockLifebuoyOwned).creationCode; - initcode = abi.encodePacked(initcode, abi.encode(owner)); - _testLifebuoyCreateDeployment(deployer, initcode); - continue; - } - _testLifebuoyCreateDeployment(deployer, type(MockLifebuoy).creationCode); - } - } - - struct _TestTemps { - address deployer; - address owner; - address recipient; - MockLifebuoy lifebuoy; - MockLifebuoyOwned lifebuoyOwned; - MockLifebuoyOwned lifebuoyOwnedClone; - uint256 tokenId; - uint256 amount; - } - - function _erc20BalanceOf(address holder) internal view returns (uint256) { - return SafeTransferLib.balanceOf(address(erc20), holder); - } - - function _erc1155BalanceOf(address holder, uint256 tokenId) internal view returns (uint256) { - return erc1155.balanceOf(holder, tokenId); - } - - function _erc6909BalanceOf(address holder, uint256 tokenId) internal view returns (uint256) { - return erc6909.balanceOf(holder, tokenId); - } - - function _testTempsBase() internal returns (_TestTemps memory t) { - t.deployer = _randomHashedAddress(); - t.owner = _randomHashedAddress(); - do { - t.recipient = _randomHashedAddress(); - } while (t.recipient == t.deployer || t.recipient == t.owner); - - if (_randomChance(32)) t.owner = t.deployer; - if (_randomChance(2)) vm.etch(t.deployer, " "); - - vm.prank(t.deployer, t.deployer); - t.lifebuoyOwned = new MockLifebuoyOwned(t.owner); - vm.deal(address(t.lifebuoyOwned), 1 ether); - } - - function _testTempsForRescue() internal returns (_TestTemps memory t) { - t = _testTempsBase(); - t.amount = _random(); - t.tokenId = _random(); - - erc20.mint(address(t.lifebuoyOwned), t.amount); - erc721.mint(address(t.lifebuoyOwned), t.tokenId); - erc1155.mint(address(t.lifebuoyOwned), t.tokenId, t.amount, ""); - erc6909.mint(address(t.lifebuoyOwned), t.tokenId, t.amount); - } - - function _testTempsForRescuePermissions() internal returns (_TestTemps memory t) { - t = _testTempsBase(); - - vm.prank(t.deployer, t.deployer); - t.lifebuoy = new MockLifebuoy(); - vm.deal(address(t.lifebuoy), 1 ether); - - vm.prank(t.deployer, t.deployer); - t.lifebuoyOwnedClone = MockLifebuoyOwned(LibClone.clone(address(t.lifebuoyOwned))); - t.lifebuoyOwnedClone.initializeOwner(t.owner); - vm.deal(address(t.lifebuoyOwnedClone), 1 ether); - } - - function testLifebuoyRescuePermissions(bytes32) public { - _TestTemps memory t = _testTempsForRescuePermissions(); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoy.rescueETH(t.recipient, 1); - - vm.prank(t.deployer); - t.lifebuoy.rescueETH(t.recipient, 1); - - vm.prank(t.owner); - if (t.deployer != t.owner) { - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - } - t.lifebuoy.rescueETH(t.recipient, 1); - } - - function testLifebuoyOwnedRescuePermissions(bytes32) public { - _TestTemps memory t = _testTempsForRescuePermissions(); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoy.rescueETH(t.recipient, 1); - - vm.prank(t.deployer); - t.lifebuoyOwned.rescueETH(t.recipient, 1); - - vm.prank(t.owner); - t.lifebuoyOwned.rescueETH(t.recipient, 1); - } - - function testLifebuoyOwnedCloneRescuePermissions(bytes32) public { - _TestTemps memory t = _testTempsForRescuePermissions(); - vm.prank(t.deployer); - if (t.deployer != t.owner) { - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - } - t.lifebuoyOwnedClone.rescueETH(t.recipient, 1); - - vm.prank(t.owner); - t.lifebuoyOwnedClone.rescueETH(t.recipient, 1); - - vm.prank(t.owner); - t.lifebuoyOwnedClone.transferOwnership(t.recipient); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - vm.prank(t.owner); - t.lifebuoyOwnedClone.rescueETH(t.recipient, 1); - } - - function testRescueAll(bytes32) public { - _TestTemps memory t = _testTempsForRescue(); - if (_randomChance(2)) _testRescueETH(t); - if (_randomChance(2)) _testRescueERC20(t); - if (_randomChance(2)) _testRescueERC721(t); - if (_randomChance(2)) _testRescueERC1155(t); - if (_randomChance(2)) _testRescueERC6909(t); - } - - function _testRescueETH(_TestTemps memory t) internal { - uint256 amount = _random(); - if (_randomChance(2)) { - amount = _bound(amount, 0, address(t.lifebuoyOwned).balance); - uint256 expectedRemaining = address(t.lifebuoyOwned).balance - amount; - vm.prank(t.owner); - t.lifebuoyOwned.rescueETH(t.recipient, amount); - assertEq(address(t.lifebuoyOwned).balance, expectedRemaining); - assertEq(t.recipient.balance, amount); - } else if (amount > address(t.lifebuoyOwned).balance) { - vm.prank(t.owner); - vm.expectRevert(Lifebuoy.RescueTransferFailed.selector); - t.lifebuoyOwned.rescueETH(t.recipient, amount); - } else { - vm.prank(t.owner); - t.lifebuoyOwned.rescueETH(t.recipient, amount); - } - } - - function _testRescueERC20(_TestTemps memory t) internal { - uint256 amount = _random(); - if (_randomChance(2)) { - amount = _bound(amount, 0, t.amount); - vm.prank(t.owner); - t.lifebuoyOwned.rescueERC20(address(erc20), t.recipient, amount); - assertEq(_erc20BalanceOf(address(t.lifebuoyOwned)), t.amount - amount); - assertEq(_erc20BalanceOf(t.recipient), amount); - } else if (amount > _erc20BalanceOf(address(t.lifebuoyOwned))) { - vm.prank(t.owner); - vm.expectRevert(Lifebuoy.RescueTransferFailed.selector); - t.lifebuoyOwned.rescueERC20(address(erc20), t.recipient, amount); - } else { - vm.prank(t.owner); - t.lifebuoyOwned.rescueERC20(address(erc20), t.recipient, amount); - } - } - - function _testRescueERC721(_TestTemps memory t) internal { - vm.prank(t.owner); - t.lifebuoyOwned.rescueERC721(address(erc721), t.recipient, t.tokenId); - assertEq(erc721.balanceOf(address(t.lifebuoyOwned)), 0); - assertEq(erc721.balanceOf(t.recipient), 1); - vm.prank(t.owner); - vm.expectRevert(Lifebuoy.RescueTransferFailed.selector); - t.lifebuoyOwned.rescueERC721(address(erc721), t.recipient, t.tokenId); - } - - function _testRescueERC1155(_TestTemps memory t) public { - uint256 amount = _random(); - if (_randomChance(2)) { - amount = _bound(amount, 0, t.amount); - vm.prank(t.owner); - t.lifebuoyOwned.rescueERC1155(address(erc1155), t.recipient, t.tokenId, amount, ""); - assertEq(_erc1155BalanceOf(address(t.lifebuoyOwned), t.tokenId), t.amount - amount); - assertEq(_erc1155BalanceOf(t.recipient, t.tokenId), amount); - } else if (amount > _erc1155BalanceOf(address(t.lifebuoyOwned), t.tokenId)) { - vm.prank(t.owner); - vm.expectRevert(Lifebuoy.RescueTransferFailed.selector); - t.lifebuoyOwned.rescueERC1155(address(erc1155), t.recipient, t.tokenId, amount, ""); - } else { - bytes memory data = _randomBytes(); - vm.prank(t.owner); - t.lifebuoyOwned.rescueERC1155(address(erc1155), t.recipient, t.tokenId, amount, data); - assertEq(erc1155.lastDataHash(), keccak256(data)); - } - } - - function _testRescueERC6909(_TestTemps memory t) public { - uint256 amount = _random(); - if (_randomChance(2)) { - amount = _bound(amount, 0, t.amount); - vm.prank(t.owner); - t.lifebuoyOwned.rescueERC6909(address(erc6909), t.recipient, t.tokenId, amount); - assertEq(_erc6909BalanceOf(address(t.lifebuoyOwned), t.tokenId), t.amount - amount); - assertEq(_erc6909BalanceOf(t.recipient, t.tokenId), amount); - } else if (amount > _erc6909BalanceOf(address(t.lifebuoyOwned), t.tokenId)) { - vm.prank(t.owner); - vm.expectRevert(Lifebuoy.RescueTransferFailed.selector); - t.lifebuoyOwned.rescueERC6909(address(erc6909), t.recipient, t.tokenId, amount); - } else { - vm.prank(t.owner); - t.lifebuoyOwned.rescueERC6909(address(erc6909), t.recipient, t.tokenId, amount); - } - } - - function testLockRescueETH() public { - _TestTemps memory t = _testTempsForRescue(); - vm.startPrank(t.owner); - t.lifebuoyOwned.rescueETH(t.recipient, 1); - t.lifebuoyOwned.lockRescue(_LIFEBUOY_RESCUE_ETH_LOCK); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.rescueETH(t.recipient, 1); - t.lifebuoyOwned.rescueERC721(address(erc721), t.recipient, t.tokenId); - } - - function testLockRescue() public { - _TestTemps memory t = _testTempsForRescue(); - vm.startPrank(t.owner); - t.lifebuoyOwned.rescueETH(t.recipient, 1); - t.lifebuoyOwned.lockRescue(_LIFEBUOY_LOCK_RESCUE_LOCK); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.lockRescue(_LIFEBUOY_LOCK_RESCUE_LOCK); - } - - function testLockEverything() public { - _TestTemps memory t = _testTempsForRescue(); - vm.startPrank(t.owner); - t.lifebuoyOwned.lockRescue(type(uint256).max); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.lockRescue(_LIFEBUOY_LOCK_RESCUE_LOCK); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.rescueETH(t.recipient, 1); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.rescueERC6909(address(erc6909), t.recipient, t.tokenId, _random()); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.rescueERC1155(address(erc1155), t.recipient, t.tokenId, _random(), ""); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.rescueERC721(address(erc721), t.recipient, t.tokenId); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.rescueERC20(address(erc20), t.recipient, _random()); - vm.expectRevert(Lifebuoy.RescueUnauthorizedOrLocked.selector); - t.lifebuoyOwned.rescueETH(t.recipient, _random()); - } -} diff --git a/grouperBot/lib/solady/test/MerkleProofLib.t.sol b/grouperBot/lib/solady/test/MerkleProofLib.t.sol deleted file mode 100644 index 835500d..0000000 --- a/grouperBot/lib/solady/test/MerkleProofLib.t.sol +++ /dev/null @@ -1,450 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MerkleProofLib} from "../src/utils/MerkleProofLib.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract MerkleProofLibTest is SoladyTest { - function testVerifyProofForHeightOneTree( - bool hasProof, - bool nonEmptyProof, - bool nonEmptyRoot, - bool nonEmptyLeaf - ) public { - bytes32 root; - if (nonEmptyRoot) { - root = bytes32("a"); - } - bytes32 leaf; - if (nonEmptyLeaf) { - leaf = bytes32("a"); - } - bytes32[] memory proof; - if (hasProof) { - proof = new bytes32[](1); - proof[0] = nonEmptyProof ? bytes32("a") : bytes32(0); - } - bool isValid = leaf == root && proof.length == 0; - assertEq(this.verify(proof, root, leaf), isValid); - } - - function testVerifyProof(bytes32[] memory data, uint256 randomness) public brutalizeMemory { - if (!(data.length > 1)) data = _randomData(); - uint256 nodeIndex = randomness % data.length; - bytes32 root = _getRoot(data); - bytes32[] memory proof = _getProof(data, nodeIndex); - bytes32 leaf = data[nodeIndex]; - - assertTrue(this.verify(proof, root, leaf)); - - // Checks verify with corrupted root returns false. - assertFalse(this.verify(proof, bytes32(uint256(root) ^ 1), leaf)); - - // Checks verify with corrupted proof returns false. - proof[0] = bytes32(uint256(proof[0]) ^ 1); - assertFalse(this.verify(proof, root, leaf)); - - // Checks verify with corrupted root and proof returns false. - assertFalse(this.verify(proof, bytes32(uint256(root) ^ 1), leaf)); - } - - function testVerifyProofBasicCaseIsValid() public { - testVerifyProofBasicCase(false, false, false, 0x00); - } - - function testVerifyProofBasicCaseIsInvalid() public { - testVerifyProofBasicCase(false, false, true, 0x00); - } - - function testVerifyMultiProofMalicious() public { - bytes32[] memory realLeaves = new bytes32[](2); - realLeaves[0] = bytes32("real leaf"); - realLeaves[1] = bytes32(0); - bytes32 root = _hashPair(realLeaves[0], realLeaves[1]); - - bytes32[] memory maliciousLeaves = new bytes32[](2); - maliciousLeaves[0] = bytes32("malicious"); - maliciousLeaves[1] = bytes32("leaves"); - bytes32[] memory maliciousProof = new bytes32[](2); - maliciousProof[0] = realLeaves[0]; - maliciousProof[1] = realLeaves[0]; - bool[] memory maliciousFlags = new bool[](3); - maliciousFlags[0] = true; - maliciousFlags[1] = true; - maliciousFlags[2] = false; - - assertFalse(this.verifyMultiProof(maliciousProof, root, maliciousLeaves, maliciousFlags)); - } - - function testVerifyProofBasicCase( - bool damageProof, - bool damageRoot, - bool damageLeaf, - bytes32 randomness - ) public { - bool noDamage = true; - uint256 ri; // Randomness index. - - bytes32[] memory proof = new bytes32[](2); - proof[0] = bytes32("b"); - proof[1] = _hashPair(bytes32("c"), bytes32(0)); - if (damageProof) { - noDamage = false; - uint256 i = uint256(uint8(randomness[ri++])) % proof.length; - proof[i] = bytes32(uint256(proof[i]) ^ 1); // Flip a bit. - } - - bytes32 root = - _hashPair(_hashPair(bytes32("a"), bytes32("b")), _hashPair(bytes32("c"), bytes32(0))); - - if (damageRoot) { - noDamage = false; - root = bytes32(uint256(root) ^ 1); // Flip a bit. - } - - bytes32 leaf = bytes32("a"); - if (damageLeaf) { - noDamage = false; - leaf = bytes32(uint256(leaf) ^ 1); // Flip a bit. - } - - assertEq(this.verify(proof, root, leaf), noDamage); - } - - function testVerifyMultiProofForSingleLeaf(bytes32[] memory data, uint256 randomness) - public - brutalizeMemory - { - if (!(data.length > 1)) data = _randomData(); - uint256 nodeIndex = randomness % data.length; - bytes32 root = _getRoot(data); - bytes32[] memory proof = _getProof(data, nodeIndex); - bytes32[] memory leaves = new bytes32[](1); - leaves[0] = data[nodeIndex]; - bool[] memory flags = new bool[](proof.length); - - assertTrue(this.verifyMultiProof(proof, root, leaves, flags)); - - // Checks verify with corrupted root returns false. - assertFalse(this.verifyMultiProof(proof, bytes32(uint256(root) ^ 1), leaves, flags)); - - // Checks verify with corrupted proof returns false. - proof[0] = bytes32(uint256(proof[0]) ^ 1); - assertFalse(this.verifyMultiProof(proof, root, leaves, flags)); - - // Checks verify with corrupted root and proof returns false. - assertFalse(this.verifyMultiProof(proof, bytes32(uint256(root) ^ 1), leaves, flags)); - } - - function testVerifyMultiProofForHeightOneTree( - bool hasProof, - bool nonEmptyProof, - bool nonEmptyRoot, - bool hasLeaf, - bool nonEmptyLeaf, - bool[] memory flags - ) public { - bytes32 root; - if (nonEmptyRoot) { - root = bytes32("a"); - } - bytes32[] memory proof; - if (hasProof) { - proof = new bytes32[](1); - proof[0] = nonEmptyProof ? bytes32("a") : bytes32(0); - } - bytes32[] memory leaves; - if (hasLeaf) { - leaves = new bytes32[](1); - leaves[0] = nonEmptyLeaf ? bytes32("a") : bytes32(0); - } - bool leafSameAsRoot = leaves.length == 1 && leaves[0] == root; - bool proofSameAsRoot = proof.length == 1 && proof[0] == root; - bool isValid = flags.length == 0 && (leafSameAsRoot || proofSameAsRoot) - && (leaves.length + proof.length == 1); - assertEq(this.verifyMultiProof(proof, root, leaves, flags), isValid); - } - - function testVerifyMultiProofForHeightTwoTree( - bool allLeaves, - bool damageRoot, - bool damageLeaves, - bool damageProof, - bool damageFlags, - bytes32 randomness - ) public { - bool noDamage = true; - uint256 ri; // Randomness index. - - bytes32 root = _hashPair(bytes32("a"), bytes32("b")); - - bytes32[] memory proof; - bytes32[] memory leaves; - bool[] memory flags = new bool[](1); - flags[0] = allLeaves; - - if (allLeaves) { - leaves = new bytes32[](2); - leaves[0] = bytes32("a"); - leaves[1] = bytes32("b"); - } else { - leaves = new bytes32[](1); - leaves[0] = bytes32("a"); - proof = new bytes32[](1); - proof[0] = bytes32("b"); - } - - if (damageRoot) { - noDamage = false; - root = bytes32(uint256(root) ^ 1); // Flip a bit. - } - - if (damageFlags) { - noDamage = false; - flags[0] = !flags[0]; // Flip a bool. - if (uint256(uint8(randomness[ri++])) & 1 == 0) delete flags; - } - - if (damageLeaves) { - noDamage = false; - uint256 i = uint256(uint8(randomness[ri++])) % leaves.length; - leaves[i] = bytes32(uint256(leaves[i]) ^ 1); // Flip a bit. - if (uint256(uint8(randomness[ri++])) & 1 == 0) delete leaves; - } - - if (damageProof && proof.length != 0) { - noDamage = false; - proof[0] = bytes32(uint256(proof[0]) ^ 1); // Flip a bit. - if (uint256(uint8(randomness[ri++])) & 1 == 0) delete proof; - } - - assertEq(this.verifyMultiProof(proof, root, leaves, flags), noDamage); - } - - function testVerifyMultiProofIsValid() public { - testVerifyMultiProof(false, false, false, false, 0x00); - } - - function testVerifyMultiProofIsInvalid() public { - testVerifyMultiProof(false, false, true, false, 0x00); - } - - function testVerifyMultiProof( - bool damageRoot, - bool damageLeaves, - bool damageProof, - bool damageFlags, - bytes32 randomness - ) public brutalizeMemory { - bool noDamage = true; - uint256 ri; // Randomness index. - - bytes32 root = _hashPair( - _hashPair(_hashPair(bytes32("a"), bytes32("b")), _hashPair(bytes32("c"), bytes32("d"))), - _hashPair(bytes32("e"), bytes32("f")) - ); - - bytes32[] memory leaves = new bytes32[](3); - leaves[0] = bytes32("d"); - leaves[1] = bytes32("e"); - leaves[2] = bytes32("f"); - - bytes32[] memory proof = new bytes32[](2); - proof[0] = bytes32("c"); - proof[1] = _hashPair(bytes32("b"), bytes32("a")); - - bool[] memory flags = new bool[](4); - flags[0] = false; - flags[1] = true; - flags[2] = false; - flags[3] = true; - - if (damageRoot) { - noDamage = false; - root = bytes32(uint256(root) ^ 1); // Flip a bit. - } - - if (damageLeaves) { - noDamage = false; - uint256 i = uint256(uint8(randomness[ri++])) % leaves.length; - leaves[i] = bytes32(uint256(leaves[i]) ^ 1); // Flip a bit. - if (uint256(uint8(randomness[ri++])) & 1 == 0) delete leaves; - } - - if (damageProof) { - noDamage = false; - uint256 i = uint256(uint8(randomness[ri++])) % proof.length; - proof[i] = bytes32(uint256(proof[i]) ^ 1); // Flip a bit. - if (uint256(uint8(randomness[ri++])) & 1 == 0) delete proof; - } - - if (damageFlags) { - noDamage = false; - uint256 i = uint256(uint8(randomness[ri++])) % flags.length; - flags[i] = !flags[i]; // Flip a bool. - if (uint256(uint8(randomness[ri++])) & 1 == 0) delete flags; - } - - assertEq(this.verifyMultiProof(proof, root, leaves, flags), noDamage); - } - - function verify(bytes32[] calldata proof, bytes32 root, bytes32 leaf) - external - returns (bool result) - { - result = MerkleProofLib.verifyCalldata(proof, root, leaf); - assertEq(MerkleProofLib.verify(proof, root, leaf), result); - } - - function verifyMultiProof( - bytes32[] calldata proof, - bytes32 root, - bytes32[] calldata leaves, - bool[] calldata flags - ) external returns (bool result) { - uint256[] memory offsetsAndLengths = new uint256[](12); - - // Basically, we want to demonstrate that the `verifyMultiProof` does not - // change the offsets and lengths. - - /// @solidity memory-safe-assembly - assembly { - mstore(add(offsetsAndLengths, shl(5, add(1, 0))), proof.offset) - mstore(add(offsetsAndLengths, shl(5, add(1, 1))), leaves.offset) - mstore(add(offsetsAndLengths, shl(5, add(1, 2))), flags.offset) - mstore(add(offsetsAndLengths, shl(5, add(1, 3))), proof.length) - mstore(add(offsetsAndLengths, shl(5, add(1, 4))), leaves.length) - mstore(add(offsetsAndLengths, shl(5, add(1, 5))), flags.length) - } - - result = MerkleProofLib.verifyMultiProofCalldata(proof, root, leaves, flags); - - /// @solidity memory-safe-assembly - assembly { - mstore(add(offsetsAndLengths, shl(5, add(1, 6))), proof.offset) - mstore(add(offsetsAndLengths, shl(5, add(1, 7))), leaves.offset) - mstore(add(offsetsAndLengths, shl(5, add(1, 8))), flags.offset) - mstore(add(offsetsAndLengths, shl(5, add(1, 9))), proof.length) - mstore(add(offsetsAndLengths, shl(5, add(1, 10))), leaves.length) - mstore(add(offsetsAndLengths, shl(5, add(1, 11))), flags.length) - } - - assertEq(offsetsAndLengths[0], offsetsAndLengths[6]); - assertEq(offsetsAndLengths[1], offsetsAndLengths[7]); - assertEq(offsetsAndLengths[2], offsetsAndLengths[8]); - assertEq(offsetsAndLengths[3], offsetsAndLengths[9]); - assertEq(offsetsAndLengths[4], offsetsAndLengths[10]); - assertEq(offsetsAndLengths[5], offsetsAndLengths[11]); - - assertEq(MerkleProofLib.verifyMultiProof(proof, root, leaves, flags), result); - } - - // Following code is adapted from https://github.com/dmfxyz/murky/blob/main/src/common/MurkyBase.sol. - - function _getRoot(bytes32[] memory data) private pure returns (bytes32) { - require(data.length > 1); - while (data.length > 1) { - data = _hashLevel(data); - } - return data[0]; - } - - function _getProof(bytes32[] memory data, uint256 nodeIndex) - private - pure - returns (bytes32[] memory) - { - require(data.length > 1); - - bytes32[] memory result = new bytes32[](64); - uint256 pos; - - while (data.length > 1) { - unchecked { - if (nodeIndex & 0x1 == 1) { - result[pos] = data[nodeIndex - 1]; - } else if (nodeIndex + 1 == data.length) { - result[pos] = bytes32(0); - } else { - result[pos] = data[nodeIndex + 1]; - } - ++pos; - nodeIndex /= 2; - } - data = _hashLevel(data); - } - // Resize the length of the array to fit. - /// @solidity memory-safe-assembly - assembly { - mstore(result, pos) - } - - return result; - } - - function _hashLevel(bytes32[] memory data) private pure returns (bytes32[] memory) { - bytes32[] memory result; - unchecked { - uint256 length = data.length; - if (length & 0x1 == 1) { - result = new bytes32[](length / 2 + 1); - result[result.length - 1] = _hashPair(data[length - 1], bytes32(0)); - } else { - result = new bytes32[](length / 2); - } - uint256 pos = 0; - for (uint256 i = 0; i < length - 1; i += 2) { - result[pos] = _hashPair(data[i], data[i + 1]); - ++pos; - } - } - return result; - } - - function _hashPair(bytes32 left, bytes32 right) private pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { - switch lt(left, right) - case 0 { - mstore(0x0, right) - mstore(0x20, left) - } - default { - mstore(0x0, left) - mstore(0x20, right) - } - result := keccak256(0x0, 0x40) - } - } - - function testEmptyCalldataHelpers() public { - assertFalse( - MerkleProofLib.verifyMultiProofCalldata( - MerkleProofLib.emptyProof(), - bytes32(0), - MerkleProofLib.emptyLeaves(), - MerkleProofLib.emptyFlags() - ) - ); - - assertFalse( - MerkleProofLib.verifyMultiProof( - MerkleProofLib.emptyProof(), - bytes32(0), - MerkleProofLib.emptyLeaves(), - MerkleProofLib.emptyFlags() - ) - ); - } - - function _randomData() internal returns (bytes32[] memory result) { - uint256 n = _bound(_random(), 2, 0xff); - result = new bytes32[](n); - unchecked { - for (uint256 i; i != n; ++i) { - result[i] = bytes32(_random()); - } - } - } -} diff --git a/grouperBot/lib/solady/test/MerkleTreeLib.t.sol b/grouperBot/lib/solady/test/MerkleTreeLib.t.sol deleted file mode 100644 index bdfbf09..0000000 --- a/grouperBot/lib/solady/test/MerkleTreeLib.t.sol +++ /dev/null @@ -1,217 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MerkleTreeLib} from "../src/utils/MerkleTreeLib.sol"; -import {MerkleProofLib} from "../src/utils/MerkleProofLib.sol"; -import {LibSort} from "../src/utils/LibSort.sol"; -import {LibPRNG} from "../src/utils/LibPRNG.sol"; -import {EfficientHashLib} from "../src/utils/EfficientHashLib.sol"; - -contract MerkleTreeLibTest is SoladyTest { - using MerkleTreeLib for bytes32[]; - using LibPRNG for *; - - function testBuildCompleteMerkleTree(bytes32[] memory leaves, bytes32 r) public { - _maybeBrutalizeMemory(r); - if (leaves.length <= 1) { - leaves = new bytes32[](1); - leaves[0] = r; - } - bytes32[] memory t = MerkleTreeLib.build(leaves); - assertEq(t.length, leaves.length * 2 - 1); - if (leaves.length == 1) { - assertEq(t[0], r); - } else { - assertNotEq(t[0], 0); - } - assertEq(t.root(), t[0]); - assertEq(leaves.length, t.numLeaves()); - assertEq(t.length, t.numLeaves() + t.numInternalNodes()); - _checkMemory(t); - if (leaves.length >= 1) { - uint256 i = _randomUniform() % leaves.length; - assertEq(t.leaf(i), leaves[i]); - } - } - - function testPad(bytes32[] memory leaves, bytes32 defaultFill, uint256 r) public { - _maybeBrutalizeMemory(r); - if (leaves.length == 0) return; - assertEq(MerkleTreeLib.pad(leaves, defaultFill), _padOriginal(leaves, defaultFill)); - _checkMemory(); - } - - function _padOriginal(bytes32[] memory leaves, bytes32 defaultFill) - internal - pure - returns (bytes32[] memory result) - { - unchecked { - uint256 p = 1; - while (p < leaves.length) p = p << 1; - result = new bytes32[](p); - for (uint256 i; i < p; ++i) { - if (i < leaves.length) { - result[i] = leaves[i]; - } else { - result[i] = defaultFill; - } - } - } - } - - function _maybeBrutalizeMemory(uint256 r) internal view { - _maybeBrutalizeMemory(bytes32(r)); - } - - function _maybeBrutalizeMemory(bytes32 r) internal view { - uint256 h = uint256(EfficientHashLib.hash(r, "hehe")); - if (h & 0xf0 == 0) _misalignFreeMemoryPointer(); - if (h & 0x0f == 0) _brutalizeMemory(); - } - - function testBuildAndGetLeaf(bytes32[] memory leaves, uint256 leafIndex) public { - if (leaves.length == 0) return; - - if (leafIndex < leaves.length) { - assertEq(this.buildAndGetLeaf(leaves, leafIndex), leaves[leafIndex]); - } else { - vm.expectRevert(MerkleTreeLib.MerkleTreeOutOfBoundsAccess.selector); - this.buildAndGetLeaf(leaves, leafIndex); - } - } - - function buildAndGetLeaf(bytes32[] memory leaves, uint256 leafIndex) - public - pure - returns (bytes32) - { - return MerkleTreeLib.build(leaves).leaf(leafIndex); - } - - function _maybePad(bytes32[] memory leaves) internal returns (bytes32[] memory) { - if (_randomChance(2)) { - if (_randomChance(2)) { - return leaves.pad(); - } - return leaves.pad(bytes32(_random())); - } - return leaves; - } - - function testBuildAndGetLeafProof(bytes32[] memory leaves, uint256 leafIndex) public { - if (leaves.length == 0) return _testBuildAndGetRoot(leaves); - leaves = _maybePad(leaves); - bytes32[] memory t = MerkleTreeLib.build(leaves); - if (leafIndex < leaves.length) { - bytes32[] memory proof = this.buildAndGetLeafProof(leaves, leafIndex); - assertTrue(MerkleProofLib.verify(proof, t.root(), leaves[leafIndex])); - } else { - vm.expectRevert(MerkleTreeLib.MerkleTreeOutOfBoundsAccess.selector); - this.buildAndGetLeafProof(leaves, leafIndex); - } - } - - function buildAndGetLeafProof(bytes32[] memory leaves, uint256 leafIndex) - public - pure - returns (bytes32[] memory proof) - { - bytes32[] memory t = MerkleTreeLib.build(leaves); - proof = t.leafProof(leafIndex); - _checkMemory(); - } - - function testBuildAndGetNodeProof(bytes32[] memory leaves, uint256 nodeIndex) public { - if (leaves.length == 0) return _testBuildAndGetRoot(leaves); - bytes32[] memory t = MerkleTreeLib.build(leaves); - if (nodeIndex < t.length) { - bytes32[] memory proof = this.buildAndGetNodeProof(leaves, nodeIndex); - assertTrue(MerkleProofLib.verify(proof, t.root(), t[nodeIndex])); - } else { - vm.expectRevert(MerkleTreeLib.MerkleTreeOutOfBoundsAccess.selector); - this.buildAndGetNodeProof(leaves, nodeIndex); - } - } - - function buildAndGetNodeProof(bytes32[] memory leaves, uint256 nodeIndex) - public - pure - returns (bytes32[] memory proof) - { - bytes32[] memory t = MerkleTreeLib.build(leaves); - proof = t.nodeProof(nodeIndex); - _checkMemory(); - } - - function _testBuildAndGetRoot(bytes32[] memory leaves) internal { - vm.expectRevert(MerkleTreeLib.MerkleTreeLeavesEmpty.selector); - this.buildAndGetRoot(leaves); - } - - function buildAndGetRoot(bytes32[] memory leaves) public pure returns (bytes32) { - return MerkleTreeLib.build(leaves).root(); - } - - function testGetRootFromEmptyTree() public { - vm.expectRevert(MerkleTreeLib.MerkleTreeOutOfBoundsAccess.selector); - this.getRootFromEmptyTree(); - } - - function getRootFromEmptyTree() public pure returns (bytes32) { - return (new bytes32[](0)).root(); - } - - struct TestMultiProofTemps { - bytes32[] leaves; - uint256[] leafIndices; - bytes32[] gathered; - bytes32[] tree; - bytes32[] proof; - bool[] flags; - } - - function testBuildAndGetLeafsMultiProof(bytes32 r) public { - _maybeBrutalizeMemory(r); - TestMultiProofTemps memory t; - t.leaves = new bytes32[](_bound(_random(), 1, 128)); - for (uint256 i; i < t.leaves.length; ++i) { - t.leaves[i] = bytes32(_random()); - } - t.leaves = _maybePad(t.leaves); - t.leafIndices = _generateUniqueLeafIndices(t.leaves); - t.tree = MerkleTreeLib.build(t.leaves); - (t.proof, t.flags) = t.tree.multiProofForLeaves(t.leafIndices); - t.gathered = t.tree.gatherLeaves(t.leafIndices); - assertTrue(MerkleProofLib.verifyMultiProof(t.proof, t.tree.root(), t.gathered, t.flags)); - } - - function _generateUniqueLeafIndices(bytes32[] memory leaves) - internal - returns (uint256[] memory indices) - { - indices = new uint256[](leaves.length); - for (uint256 i; i < leaves.length; ++i) { - indices[i] = i; - } - LibPRNG.PRNG memory prng; - prng.seed(_randomUniform()); - prng.shuffle(indices); - uint256 n = _bound(_random(), 1, indices.length); - /// @solidity memory-safe-assembly - assembly { - mstore(indices, n) - } - LibSort.sort(indices); - } - - function testMultiProofRevertsForEmptyLeafs() public { - vm.expectRevert(MerkleTreeLib.MerkleTreeInvalidLeafIndices.selector); - this.multiProofRevertsForEmptyLeafs(); - } - - function multiProofRevertsForEmptyLeafs() public pure { - (new bytes32[](1)).multiProofForLeaves(new uint256[](0)); - } -} diff --git a/grouperBot/lib/solady/test/MetadataReaderLib.t.sol b/grouperBot/lib/solady/test/MetadataReaderLib.t.sol deleted file mode 100644 index 54a7be3..0000000 --- a/grouperBot/lib/solady/test/MetadataReaderLib.t.sol +++ /dev/null @@ -1,338 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MetadataReaderLib} from "../src/utils/MetadataReaderLib.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract MetadataReaderLibTest is SoladyTest { - string internal _stringToReturn; - - uint256 internal _randomness; - - function returnsString() public view returns (string memory) { - uint256 r = _randomness; - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, add(0x100, mload(0x40))) - mstore(0x00, r) - } - string memory s = _stringToReturn; - /// @solidity memory-safe-assembly - assembly { - if iszero(and(r, 1)) { - if iszero(and(r, 2)) { - mstore(sub(s, 0x40), 0x40) - return(sub(s, 0x40), add(0x60, add(mload(s), byte(2, r)))) - } - mstore(sub(s, 0x20), 0x20) - return(sub(s, 0x20), add(0x40, add(mload(s), byte(2, r)))) - } - mstore(0x00, gas()) - mstore(0x20, r) - mstore(add(mload(s), add(s, 0x20)), shr(8, keccak256(0x00, 0x40))) - return(add(s, 0x20), add(mload(s), byte(2, r))) - } - } - - function returnsEmptyString() public view returns (string memory) { - uint256 r = _randomness; - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, add(0x100, mload(0x40))) - mstore(0x00, r) - } - string memory s = _stringToReturn; - /// @solidity memory-safe-assembly - assembly { - if iszero(and(r, 1)) { - if iszero(and(r, 2)) { - mstore(sub(s, 0x40), 0x41) - return(sub(s, 0x40), add(0x60, mload(s))) - } - mstore(sub(s, 0x20), 0x21) - return(sub(s, 0x20), add(0x40, mload(s))) - } - if iszero(and(r, 2)) { - let n := mload(s) - mstore(s, add(n, 1)) - if iszero(and(r, 2)) { - mstore(sub(s, 0x40), 0x40) - return(sub(s, 0x40), add(0x60, n)) - } - mstore(sub(s, 0x20), 0x20) - return(sub(s, 0x20), add(0x40, n)) - } - let m := mload(0x40) - codecopy(m, codesize(), 0x200) - mstore(m, and(63, byte(3, r))) - return(m, and(63, byte(2, r))) - } - } - - function returnsChoppedString(uint256 chop) public pure returns (string memory) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(add(m, 0x00), 0x20) - mstore(add(m, 0x20), 0x20) - mstore(add(m, 0x40), "112233445566778899aa112233445566") - return(add(m, 0x00), add(0x40, chop)) - } - } - - function returnsBytes32StringA() public pure returns (bytes32) { - return bytes32(hex"4d696c616479"); - } - - function returnsBytes32StringB() public pure returns (bytes32) { - return bytes32("This string has thirty two bytes"); - } - - function returnsNothing() public pure {} - - function reverts() public pure { - revert("Lorem Ipsum"); - } - - function returnsChoppedUint(uint256 v, uint256 chop) public pure returns (uint256) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, v) - return(0x00, chop) - } - } - - function name() public view returns (string memory) { - return returnsString(); - } - - function symbol() public view returns (string memory) { - return returnsString(); - } - - function returnsUint() public view returns (uint256) { - return _randomness; - } - - function decimals() public view returns (uint8) { - return uint8(_randomness); - } - - function testReadBytes32String() public brutalizeMemory { - string memory result; - result = _readString(abi.encodeWithSignature("returnsBytes32StringA()")); - _checkMemory(result); - assertEq(result, "Milady"); - result = _readString(abi.encodeWithSignature("returnsBytes32StringB()")); - _checkMemory(result); - assertEq(result, "This string has thirty two bytes"); - result = _readString(abi.encodeWithSignature("returnsNothing()")); - _checkMemory(result); - assertEq(result, ""); - result = _readString(abi.encodeWithSignature("reverts()")); - _checkMemory(result); - assertEq(result, ""); - } - - function testReadBytes32StringTruncated() public brutalizeMemory { - bytes memory data; - string memory result; - unchecked { - data = abi.encodeWithSignature("returnsBytes32StringB()"); - for (uint256 limit; limit < 39; ++limit) { - result = _readString(data, limit); - _checkMemory(result); - assertEq(result, LibString.slice("This string has thirty two bytes", 0, limit)); - } - } - } - - function testReadStringChopped() public { - bytes memory data; - string memory result; - data = abi.encodeWithSignature("returnsChoppedString(uint256)", uint256(32)); - result = _readString(data); - _checkMemory(result); - assertEq(result, "112233445566778899aa112233445566"); - - for (uint256 limit; limit < 39; limit += 5) { - for (uint256 chop; chop < 39; chop += 3) { - data = abi.encodeWithSignature("returnsChoppedString(uint256)", uint256(chop)); - result = _readString(data, limit); - _checkMemory(result); - // As long as the returndatasize is insufficient, the `abi.decode` will fail, - // and the resultant string will be empty. - // Even if the `limit` is smaller than `chop`. - string memory expected; - if (chop >= 32) { - expected = LibString.slice("112233445566778899aa112233445566", 0, limit); - } - assertEq(result, expected); - } - } - } - - function _readString(bytes memory data, uint256 limit) internal returns (string memory) { - uint256 r = _random() % 2; - if (r == 0) return MetadataReaderLib.readString(address(this), data, limit, gasleft()); - return MetadataReaderLib.readString(address(this), data, limit); - } - - function _readString(bytes memory data) internal returns (string memory) { - uint256 r = _random() % 3; - if (r == 0) { - return MetadataReaderLib.readString(address(this), data, type(uint256).max, gasleft()); - } - if (r == 1) return MetadataReaderLib.readString(address(this), data, type(uint256).max); - return MetadataReaderLib.readString(address(this), data); - } - - function _readSymbol() internal returns (string memory) { - uint256 r = _random() % 3; - if (r == 0) { - return MetadataReaderLib.readSymbol(address(this), type(uint256).max, gasleft()); - } - if (r == 1) return MetadataReaderLib.readSymbol(address(this), type(uint256).max); - return MetadataReaderLib.readSymbol(address(this)); - } - - function _readName() internal returns (string memory) { - uint256 r = _random() % 3; - if (r == 0) return MetadataReaderLib.readName(address(this), type(uint256).max, gasleft()); - if (r == 1) return MetadataReaderLib.readName(address(this), type(uint256).max); - return MetadataReaderLib.readName(address(this)); - } - - function _readUint(bytes memory data) internal returns (uint256) { - uint256 r = _random() % 2; - if (r == 0) return MetadataReaderLib.readUint(address(this), data, gasleft()); - return MetadataReaderLib.readUint(address(this), data); - } - - function _readDecimals() internal returns (uint256) { - uint256 r = _random() % 2; - if (r == 0) return MetadataReaderLib.readDecimals(address(this), gasleft()); - return MetadataReaderLib.readDecimals(address(this)); - } - - function testReadString(uint256 r) public brutalizeMemory { - string memory result; - string memory s = _generateString(); - _stringToReturn = s; - _randomness = r; - result = _readString(abi.encodeWithSignature("returnsString()")); - _checkMemory(result); - assertEq(result, s); - result = _readName(); - _checkMemory(result); - assertEq(result, s); - result = _readSymbol(); - _checkMemory(result); - assertEq(result, s); - result = _readString(abi.encodeWithSignature("returnsEmptyString()")); - _checkMemory(result); - assertEq(result, ""); - result = _readString(abi.encodeWithSignature("reverts()")); - _checkMemory(result); - assertEq(result, ""); - result = _readString(abi.encodeWithSignature("returnsNothing()")); - _checkMemory(result); - assertEq(result, ""); - } - - function testReadStringTruncated(uint256 r) public brutalizeMemory { - bytes memory data; - string memory result; - string memory s = _generateString(); - _stringToReturn = s; - _randomness = r; - unchecked { - uint256 limit = _bound(_random(), 0, bytes(s).length * 2); - data = abi.encodeWithSignature("returnsString()"); - result = MetadataReaderLib.readString(address(this), data, limit); - _checkMemory(result); - assertEq(result, LibString.slice(s, 0, limit)); - } - } - - function testReadUint(uint256 r) public { - _randomness = r; - bytes memory data = abi.encodeWithSignature("returnsUint()"); - assertEq(_readUint(data), r); - assertEq(_readDecimals(), uint8(r)); - } - - function testReadUint() public { - bytes memory data; - uint256 result; - data = abi.encodeWithSignature("returnsNothing()"); - result = _readUint(data); - assertEq(result, 0); - data = abi.encodeWithSignature("reverts()"); - result = _readUint(data); - assertEq(result, 0); - - for (uint256 j; j != 8; ++j) { - for (uint256 i; i != 70; ++i) { - uint256 k = _hash(i, j); - data = abi.encodeWithSignature("returnsChoppedUint(uint256,uint256)", k, i); - result = _readUint(data); - assertEq(result, i < 32 ? 0 : k); - } - } - } - - function testBoundsCheckDifferential(uint256) public { - uint256 rds = _bound(_random(), 0, 128); - uint256 l = _randomChance(2) ? type(uint248).max : 128; - uint256 o = _bound(_random(), 0, l); - uint256 n = _bound(_random(), 0, l); - bool result; - /// @solidity memory-safe-assembly - assembly { - if iszero(lt(rds, 0x40)) { - if iszero(gt(o, sub(rds, 0x20))) { - if iszero(gt(n, sub(rds, add(o, 0x20)))) { result := 1 } - } - } - } - bool expected = rds >= 0x40 && !(o + 0x20 > rds) && !(n + o + 0x20 > rds); - assertEq(result, expected); - } - - function _hash(uint256 i, uint256 j) internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, i) - mstore(0x20, j) - result := keccak256(0x00, 0x20) - } - } - - function _generateString() internal returns (string memory result) { - uint256 randomness = _random(); - uint256 resultLength = _randomStringLength(); - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(0x00, randomness) - mstore(0x40, and(add(add(result, 0x40), resultLength), not(31))) - mstore(result, resultLength) - - // forgefmt: disable-next-item - for { let i := 0 } lt(i, resultLength) { i := add(i, 1) } { - mstore(0x20, gas()) - let c := byte(0, keccak256(0x00, 0x40)) - mstore8(add(add(result, 0x20), i), or(c, iszero(c))) - } - } - } - - function _randomStringLength() internal returns (uint256 r) { - r = _random() % 256; - if (r < 64) return _random() % 128; - if (r < 128) return _random() % 64; - return _random() % 16; - } -} diff --git a/grouperBot/lib/solady/test/MinHeapLib.t.sol b/grouperBot/lib/solady/test/MinHeapLib.t.sol deleted file mode 100644 index 2549cd3..0000000 --- a/grouperBot/lib/solady/test/MinHeapLib.t.sol +++ /dev/null @@ -1,695 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MinHeapLib} from "../src/utils/MinHeapLib.sol"; -import {LibSort} from "../src/utils/LibSort.sol"; -import {LibPRNG} from "../src/utils/LibPRNG.sol"; - -contract MinHeapLibTest is SoladyTest { - using MinHeapLib for *; - using LibPRNG for *; - - MinHeapLib.Heap heap0; - - MinHeapLib.Heap heap1; - - uint256[] heapDataInStorage; - - function testHeapRoot(uint256 x) public { - if (_randomChance(2)) { - vm.expectRevert(MinHeapLib.HeapIsEmpty.selector); - this.root(); - } - heap0.data.push(x); - assertEq(heap0.length(), 1); - assertEq(heap0.root(), x); - } - - function root() public view returns (uint256) { - return heap0.root(); - } - - function testHeapPushAndPop(uint256) public { - unchecked { - uint256 n = _random() % 8; - uint256[] memory a = new uint256[](n); - - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - a[i] = r; - heap0.push(r); - } - LibSort.insertionSort(a); - for (uint256 i; i < n; ++i) { - assertEq(heap0.pop(), a[i]); - } - assertEq(heap0.length(), 0); - } - } - - function testHeapPushPop(uint256) public { - unchecked { - uint256 n = _random() % 8; - uint256[] memory a = new uint256[](n + 1); - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - heap0.push(r); - heap1.push(r); - a[i + 1] = r; - } - n = _random() % 8; - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - a[0] = r; - LibSort.insertionSort(a); - uint256 popped0 = heap0.pushPop(r); - heap1.push(r); - uint256 popped1 = heap1.pop(); - assertEq(popped0, popped1); - } - LibSort.insertionSort(a); - n = heap0.length(); - for (uint256 i; i < n; ++i) { - assertEq(heap0.pop(), a[i + 1]); - } - } - } - - function testHeapPushPopLength(uint256) public brutalizeMemory { - unchecked { - uint256 heap0Length; - uint256 heap1Length; - do { - if (_randomChance(2)) { - heap0.push(_random()); - assertEq(heap0.data.length, ++heap0Length); - } - if (heap0Length != 0 && _randomChance(2)) { - heap0.pop(); - assertEq(heap0.data.length, --heap0Length); - } - if (_randomChance(2)) { - heap1.push(_random()); - assertEq(heap1.data.length, ++heap1Length); - } - if (heap1Length != 0 && _randomChance(2)) { - heap1.pop(); - assertEq(heap1.data.length, --heap1Length); - } - } while (!_randomChance(16)); - } - } - - function testHeapReplace(uint256) public { - unchecked { - uint256 n = _random() % 8 + 1; - uint256[] memory a = new uint256[](n); - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - heap0.push(r); - heap1.push(r); - a[i] = r; - } - n = _random() % 8; - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - LibSort.insertionSort(a); - a[0] = r; - uint256 popped0 = heap0.replace(r); - uint256 popped1 = heap1.pop(); - heap1.push(r); - assertEq(popped0, popped1); - } - LibSort.insertionSort(a); - n = heap0.length(); - for (uint256 i; i < n; ++i) { - assertEq(heap0.pop(), a[i]); - } - } - } - - function testHeapSmallest(uint256) public brutalizeMemory { - unchecked { - uint256 n = _random() & 15 == 0 ? _random() % 256 : _random() % 32; - for (uint256 i; i < n; ++i) { - heap0.push(_random()); - } - if (_random() & 7 == 0) { - n = _random() % 32; - for (uint256 i; i < n; ++i) { - heap0.pushPop(_random()); - if (_random() & 1 == 0) { - heap0.push(_random()); - if (_random() & 1 == 0) heap0.pop(); - } - if (_random() & 1 == 0) if (heap0.length() != 0) heap0.replace(_random()); - } - } - uint256 k = _random() & 15 == 0 ? _random() % 256 : _random() % 32; - k = _random() & 31 == 0 ? 1 << 255 : k; - if (_random() & 7 == 0) _brutalizeMemory(); - uint256[] memory computed = heap0.smallest(k); - _checkMemory(); - if (_random() & 7 == 0) _brutalizeMemory(); - assertEq(computed, _smallest(heap0.data, k)); - } - } - - function testHeapSmallestGas() public { - unchecked { - for (uint256 i; i < 2048; ++i) { - heap0.push(_random()); - } - uint256 gasBefore = gasleft(); - heap0.smallest(512); - uint256 gasUsed = gasBefore - gasleft(); - emit LogUint("gasUsed", gasUsed); - } - } - - function _smallest(uint256[] memory a, uint256 n) - internal - view - returns (uint256[] memory result) - { - result = _copy(a); - LibSort.insertionSort(result); - uint256 k = _min(n, result.length); - /// @solidity memory-safe-assembly - assembly { - mstore(result, k) - } - } - - function _copy(uint256[] memory a) private view returns (uint256[] memory b) { - /// @solidity memory-safe-assembly - assembly { - b := mload(0x40) - let n := add(shl(5, mload(a)), 0x20) - pop(staticcall(gas(), 4, a, n, b, n)) - mstore(0x40, add(b, n)) - } - } - - function _min(uint256 a, uint256 b) private pure returns (uint256) { - return a < b ? a : b; - } - - function testHeapPSiftTrick(uint256 c, uint256 h, uint256 e) public { - assertEq(_heapPSiftTrick(c, h, e), _heapPSiftTrickOriginal(c, h, e)); - } - - function _heapPSiftTrick(uint256 c, uint256 h, uint256 e) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - function pValue(h_, p_) -> _v { - mstore(0x00, h_) - mstore(0x20, p_) - _v := keccak256(0x00, 0x40) - } - if lt(c, e) { - c := add(c, gt(pValue(h, c), pValue(h, add(c, lt(add(c, 1), e))))) - result := c - } - } - } - - function _heapPSiftTrickOriginal(uint256 childPos, uint256 sOffset, uint256 n) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - function pValue(h_, p_) -> _v { - mstore(0x00, h_) - mstore(0x20, p_) - _v := keccak256(0x00, 0x40) - } - if lt(childPos, n) { - let child := pValue(sOffset, childPos) - let rightPos := add(childPos, 1) - let right := pValue(sOffset, rightPos) - if or(iszero(lt(rightPos, n)), lt(child, right)) { - right := child - rightPos := childPos - } - result := rightPos - } - } - } - - function testHeapEnqueue(uint256) public { - unchecked { - uint256 maxLength = _random() % 8 + 1; - uint256 m = _random() % 32 + maxLength; - uint256[] memory a = new uint256[](m); - uint256[] memory rejected = new uint256[](m); - uint256 numRejected; - for (uint256 i; i < m; ++i) { - uint256 r = _random(); - (bool success, bool hasPopped, uint256 popped) = heap0.enqueue(r, maxLength); - if (hasPopped) { - assertEq(heap0.length(), maxLength); - assertEq(success, true); - rejected[numRejected++] = popped; - } - if (!success) { - assertEq(heap0.length(), maxLength); - rejected[numRejected++] = r; - } - a[i] = r; - } - LibSort.insertionSort(a); - /// @solidity memory-safe-assembly - assembly { - mstore(rejected, numRejected) - } - LibSort.insertionSort(rejected); - for (uint256 i; i < maxLength; ++i) { - assertEq(a[m - maxLength + i], heap0.pop()); - } - assertEq(numRejected + maxLength, m); - for (uint256 i; i < numRejected; ++i) { - assertEq(a[i], rejected[i]); - } - } - } - - function testHeapEnqueue2(uint256) public { - unchecked { - uint256 maxLength = _random() & 31 == 0 ? 1 << 255 : _random() % 32 + 1; - uint256 m = _random() % 32 + 1; - for (uint256 i; i < m; ++i) { - uint256 r = _random(); - heap0.enqueue(r, maxLength); - heap1.push(r); - if (heap1.length() > maxLength) heap1.pop(); - } - uint256 k = _random() % m; - k = _random() & 31 == 0 ? 1 << 255 : k; - assertEq(heap0.smallest(k), heap1.smallest(k)); - } - } - - function testHeapEnqueueGas() public { - unchecked { - for (uint256 t = 8; t < 16; ++t) { - uint256 maxLength = t; - for (uint256 i; i < 16; ++i) { - heap0.enqueue(i, maxLength); - } - for (uint256 i; i < 16; ++i) { - heap0.enqueue(_random() % 16, maxLength); - } - } - while (heap0.length() != 0) heap0.pop(); - } - } - - function testHeapEnqueueZeroMaxLengthReverts(uint256) public { - if (_randomChance(2)) { - vm.expectRevert(MinHeapLib.HeapIsEmpty.selector); - this.enqueue(_random(), 0); - } - this.enqueue(_random(), 1); - } - - function enqueue(uint256 x, uint256 cap) public { - heap0.enqueue(x, cap); - } - - function testHeapReplaceOrPopEmptyHeapReverts(uint256) public { - if (_randomChance(2)) { - vm.expectRevert(MinHeapLib.HeapIsEmpty.selector); - if (_randomChance(2)) { - this.replace(_random()); - } else { - this.pop(); - } - } - heap0.push(_random()); - if (_randomChance(2)) { - heap0.replace(_random()); - } else { - heap0.pop(); - } - } - - function replace(uint256 x) public { - heap0.replace(x); - } - - function pop() public { - heap0.pop(); - } - - function testMemHeapRoot(uint256 x) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - if (_randomChance(2)) { - vm.expectRevert(MinHeapLib.HeapIsEmpty.selector); - this.emptyMemHeapRoot(); - } - heapA.push(x); - assertEq(heapA.length(), 1); - assertEq(heapA.root(), x); - } - - function emptyMemHeapRoot() public pure { - MinHeapLib.MemHeap memory heapA; - heapA.root(); - } - - function testMemHeapPushAndPop(uint256) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - unchecked { - uint256 n = _random() % 64; - uint256[] memory a = new uint256[](n); - - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - a[i] = r; - if (_randomChance(16)) heapA.reserve(_random() % 256); - heapA.push(r); - _checkMemory(); - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(16)) heapA.reserve(_random() % 256); - } - LibSort.insertionSort(a); - for (uint256 i; i < n; ++i) { - assertEq(heapA.pop(), a[i]); - } - assertEq(heapA.length(), 0); - } - } - - function testMemHeapPushPop(uint256) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - MinHeapLib.MemHeap memory heapB; - unchecked { - uint256 n = _random() % 64; - uint256[] memory a = new uint256[](n + 1); - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - if (_randomChance(16)) heapA.reserve(_random() % 256); - heapA.push(r); - _checkMemory(); - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(16)) heapA.reserve(_random() % 256); - if (_randomChance(16)) heapB.reserve(_random() % 256); - heapB.push(r); - _checkMemory(); - if (_randomChance(32)) _brutalizeMemory(); - if (_randomChance(16)) heapB.reserve(_random() % 256); - a[i + 1] = r; - } - n = _random() % 8; - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - a[0] = r; - LibSort.insertionSort(a); - uint256 popped0 = heapA.pushPop(r); - heapB.push(r); - uint256 popped1 = heapB.pop(); - assertEq(popped0, popped1); - } - LibSort.insertionSort(a); - n = heapA.length(); - for (uint256 i; i < n; ++i) { - assertEq(heapA.pop(), a[i + 1]); - } - } - } - - function testMemHeapPushPopLength(uint256) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - MinHeapLib.MemHeap memory heapB; - unchecked { - uint256 heapALength; - uint256 heapBLength; - do { - if (_randomChance(2)) { - if (_randomChance(16)) heapA.reserve(_random() % 256); - heapA.push(_random()); - assertEq(heapA.data.length, ++heapALength); - if (_randomChance(16)) heapA.reserve(_random() % 256); - } - if (heapALength != 0 && _randomChance(2)) { - if (_randomChance(16)) heapA.reserve(_random() % 256); - heapA.pop(); - assertEq(heapA.data.length, --heapALength); - if (_randomChance(16)) heapA.reserve(_random() % 256); - } - if (_randomChance(2)) { - if (_randomChance(16)) heapB.reserve(_random() % 256); - heapB.push(_random()); - assertEq(heapB.data.length, ++heapBLength); - if (_randomChance(16)) heapB.reserve(_random() % 256); - } - if (heapBLength != 0 && _randomChance(2)) { - if (_randomChance(16)) heapB.reserve(_random() % 256); - heapB.pop(); - assertEq(heapB.data.length, --heapBLength); - if (_randomChance(16)) heapB.reserve(_random() % 256); - } - } while (!_randomChance(16)); - } - } - - function testMemHeapReplace(uint256) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - MinHeapLib.MemHeap memory heapB; - unchecked { - uint256 n = _random() % 64 + 1; - uint256[] memory a = new uint256[](n); - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - heapA.push(r); - heapB.push(r); - a[i] = r; - } - n = _random() % 8; - for (uint256 i; i < n; ++i) { - uint256 r = _random(); - LibSort.insertionSort(a); - a[0] = r; - uint256 popped0 = heapA.replace(r); - uint256 popped1 = heapB.pop(); - heapB.push(r); - assertEq(popped0, popped1); - } - LibSort.insertionSort(a); - n = heapA.length(); - for (uint256 i; i < n; ++i) { - assertEq(heapA.pop(), a[i]); - } - } - } - - function testMemHeapSmallest(uint256) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - unchecked { - uint256 n = _random() & 15 == 0 ? _random() % 256 : _random() % 64; - for (uint256 i; i < n; ++i) { - heapA.push(_random()); - } - if (_random() & 7 == 0) { - n = _random() % 32; - for (uint256 i; i < n; ++i) { - heapA.pushPop(_random()); - if (_random() & 1 == 0) { - heapA.push(_random()); - if (_random() & 1 == 0) heapA.pop(); - } - if (_random() & 1 == 0) if (heapA.length() != 0) heapA.replace(_random()); - } - } - uint256 k = _random() & 15 == 0 ? _random() % 256 : _random() % 64; - k = _random() & 31 == 0 ? 1 << 255 : k; - if (_random() & 7 == 0) _brutalizeMemory(); - uint256[] memory computed = heapA.smallest(k); - _checkMemory(); - if (_random() & 7 == 0) _brutalizeMemory(); - assertEq(computed, _smallest(heapA.data, k)); - } - } - - function testMemHeapSmallestGas() public { - MinHeapLib.MemHeap memory heapA; - LibPRNG.PRNG memory prng; - unchecked { - for (uint256 i; i < 2048; ++i) { - heapA.push(prng.next()); - } - uint256 gasBefore = gasleft(); - heapA.smallest(512); - uint256 gasUsed = gasBefore - gasleft(); - emit LogUint("gasUsed", gasUsed); - } - } - - function testMemHeapEnqueue(uint256) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - unchecked { - uint256 maxLength = _random() % 64 + 1; - uint256[] memory a = new uint256[](_random() % 32 + maxLength); - uint256[] memory rejected = new uint256[](a.length); - uint256 numRejected; - bool testReinit = _randomChance(2); - for (uint256 i; i < a.length; ++i) { - uint256 r = _random(); - (bool success, bool hasPopped, uint256 popped) = heapA.enqueue(r, maxLength); - if (testReinit) { - if (_randomChance(2)) { - heapDataInStorage = heapA.data; - heapA = MinHeapLib.MemHeap(heapDataInStorage); - _checkMemory(); - } - if (_randomChance(2)) { - heapDataInStorage = heapA.data; - uint256[] memory data = heapDataInStorage; - heapA = MinHeapLib.MemHeap(data); - _checkMemory(); - } - } - if (hasPopped) { - assertEq(heapA.length(), maxLength); - assertEq(success, true); - rejected[numRejected++] = popped; - } - if (!success) { - assertEq(heapA.length(), maxLength); - rejected[numRejected++] = r; - } - a[i] = r; - } - LibSort.insertionSort(a); - /// @solidity memory-safe-assembly - assembly { - mstore(rejected, numRejected) - } - LibSort.insertionSort(rejected); - for (uint256 i; i < maxLength; ++i) { - assertEq(a[a.length - maxLength + i], heapA.pop()); - } - assertEq(numRejected + maxLength, a.length); - for (uint256 i; i < numRejected; ++i) { - assertEq(a[i], rejected[i]); - } - } - } - - function testMemHeapEnqueue2(uint256) public brutalizeMemory { - MinHeapLib.MemHeap memory heapA; - MinHeapLib.MemHeap memory heapB; - unchecked { - uint256 maxLength = _random() & 31 == 0 ? 1 << 255 : _random() % 64 + 1; - uint256 m = _random() % 64 + 1; - for (uint256 i; i < m; ++i) { - uint256 r = _random(); - heapA.enqueue(r, maxLength); - heapB.push(r); - if (heapB.length() > maxLength) heapB.pop(); - } - uint256 k = _random() % m; - k = _random() & 31 == 0 ? 1 << 255 : k; - assertEq(heapA.smallest(k), heapB.smallest(k)); - } - } - - function testMemHeapPushGas() public pure { - MinHeapLib.MemHeap memory heapA; - unchecked { - for (uint256 i; i < 64; ++i) { - heapA.push(i); - } - } - } - - function testMemHeapEnqueueZeroMaxLengthReverts(uint256) public { - MinHeapLib.MemHeap memory heapA; - if (_randomChance(2)) { - vm.expectRevert(MinHeapLib.HeapIsEmpty.selector); - this.memHeapEnqueueZeroMaxLengthReverts(_random()); - } - heapA.enqueue(_random(), 1); - } - - function memHeapEnqueueZeroMaxLengthReverts(uint256 x) public pure { - MinHeapLib.MemHeap memory heapA; - heapA.enqueue(x, 0); - } - - function testMemHeapReplaceOrPopEmptyHeapReverts(uint256) public { - MinHeapLib.MemHeap memory heapA; - if (_randomChance(2)) { - vm.expectRevert(MinHeapLib.HeapIsEmpty.selector); - this.memHeapReplaceOrPopEmptyHeapReverts(_random(), _randomChance(2)); - } - heapA.push(_random()); - if (_randomChance(2)) { - heapA.replace(_random()); - } else { - heapA.pop(); - } - } - - function memHeapReplaceOrPopEmptyHeapReverts(uint256 x, bool r) public pure { - MinHeapLib.MemHeap memory heapA; - if (r) { - heapA.replace(x); - } else { - heapA.pop(); - } - } - - function testMemHeapEnqueueGas() public pure { - MinHeapLib.MemHeap memory heapA; - LibPRNG.PRNG memory prng; - unchecked { - for (uint256 t = 8; t < 16; ++t) { - uint256 maxLength = t; - for (uint256 i; i < 16; ++i) { - heapA.enqueue(i, maxLength); - } - for (uint256 i; i < 16; ++i) { - heapA.enqueue(prng.next() % 16, maxLength); - } - } - while (heapA.length() != 0) heapA.pop(); - } - } - - function testMemHeapWriteAndReadFromStorage() public { - MinHeapLib.MemHeap memory heapA = MinHeapLib.MemHeap(new uint256[](0)); - MinHeapLib.push(heapA, 9999999999999999999999999999999999999999999999); - - heapDataInStorage = heapA.data; - - MinHeapLib.MemHeap memory heapB = MinHeapLib.MemHeap(heapDataInStorage); - for (uint256 i = 0; i < 32; i++) { - MinHeapLib.push(heapB, 69 + i); - } - - assertEq(MinHeapLib.root(heapB), 69); - } - - function testMemHeapWriteAndReadFromStorage2() public { - MinHeapLib.MemHeap memory heapA = MinHeapLib.MemHeap(new uint256[](0)); - MinHeapLib.push(heapA, 9999999999999999999999999999999999999999999999); - - heapDataInStorage = heapA.data; - - uint256[] memory unstore = heapDataInStorage; - - MinHeapLib.MemHeap memory heapB = MinHeapLib.MemHeap(unstore); - for (uint256 i = 0; i < 32; i++) { - MinHeapLib.push(heapB, 69 + i); - } - } -} diff --git a/grouperBot/lib/solady/test/Multicallable.t.sol b/grouperBot/lib/solady/test/Multicallable.t.sol deleted file mode 100644 index c0f1460..0000000 --- a/grouperBot/lib/solady/test/Multicallable.t.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {MockMulticallable} from "./utils/mocks/MockMulticallable.sol"; - -contract MulticallableTest is SoladyTest { - MockMulticallable multicallable; - - function setUp() public { - multicallable = new MockMulticallable(); - } - - function testMulticallableRevertWithMessage(string memory revertMessage) public { - bytes[] memory data = new bytes[](1); - data[0] = - abi.encodeWithSelector(MockMulticallable.revertsWithString.selector, revertMessage); - vm.expectRevert(bytes(revertMessage)); - multicallable.multicall(data); - } - - function testMulticallableRevertWithMessage() public { - testMulticallableRevertWithMessage("Milady"); - } - - function testMulticallableRevertWithCustomError() public { - bytes[] memory data = new bytes[](1); - data[0] = abi.encodeWithSelector(MockMulticallable.revertsWithCustomError.selector); - vm.expectRevert(MockMulticallable.CustomError.selector); - multicallable.multicall(data); - } - - function testMulticallableRevertWithNothing() public { - bytes[] memory data = new bytes[](1); - data[0] = abi.encodeWithSelector(MockMulticallable.revertsWithNothing.selector); - vm.expectRevert(); - multicallable.multicall(data); - } - - function testMulticallableReturnDataIsProperlyEncoded( - uint256 a0, - uint256 b0, - uint256 a1, - uint256 b1 - ) public { - bytes[] memory data = new bytes[](2); - data[0] = abi.encodeWithSelector(MockMulticallable.returnsTuple.selector, a0, b0); - data[1] = abi.encodeWithSelector(MockMulticallable.returnsTuple.selector, a1, b1); - bytes[] memory returnedData; - if (_randomChance(2)) { - returnedData = multicallable.multicall(data); - } else { - returnedData = multicallable.multicallBrutalized(data); - } - MockMulticallable.Tuple memory t0 = abi.decode(returnedData[0], (MockMulticallable.Tuple)); - MockMulticallable.Tuple memory t1 = abi.decode(returnedData[1], (MockMulticallable.Tuple)); - assertEq(t0.a, a0); - assertEq(t0.b, b0); - assertEq(t1.a, a1); - assertEq(t1.b, b1); - } - - function testMulticallableReturnDataIsProperlyEncoded( - string memory sIn0, - string memory sIn1, - uint256 n - ) public { - n = n % 2; - bytes[] memory dataIn = new bytes[](n); - if (n > 0) { - dataIn[0] = - abi.encodeWithSelector(MockMulticallable.returnsRandomizedString.selector, sIn0); - } - if (n > 1) { - dataIn[1] = - abi.encodeWithSelector(MockMulticallable.returnsRandomizedString.selector, sIn1); - } - bytes[] memory dataOut; - if (_randomChance(2)) { - dataOut = multicallable.multicall(dataIn); - } else { - dataOut = multicallable.multicallBrutalized(dataIn); - } - if (n > 0) { - assertEq(abi.decode(dataOut[0], (string)), multicallable.returnsRandomizedString(sIn0)); - } - if (n > 1) { - assertEq(abi.decode(dataOut[1], (string)), multicallable.returnsRandomizedString(sIn1)); - } - } - - function testMulticallableReturnDataIsProperlyEncoded() public { - testMulticallableReturnDataIsProperlyEncoded(0, 1, 2, 3); - } - - function testMulticallableBenchmark() public { - unchecked { - bytes[] memory data = new bytes[](10); - for (uint256 i; i != data.length; ++i) { - data[i] = abi.encodeWithSelector(MockMulticallable.returnsTuple.selector, i, i + 1); - } - bytes[] memory returnedData = multicallable.multicall(data); - assertEq(returnedData.length, data.length); - } - } - - function testMulticallableOriginalBenchmark() public { - unchecked { - bytes[] memory data = new bytes[](10); - for (uint256 i; i != data.length; ++i) { - data[i] = abi.encodeWithSelector(MockMulticallable.returnsTuple.selector, i, i + 1); - } - bytes[] memory returnedData = multicallable.multicallOriginal(data); - assertEq(returnedData.length, data.length); - } - } - - function testMulticallableWithNoData() public { - bytes[] memory data = new bytes[](0); - assertEq(multicallable.multicall(data).length, 0); - } - - function testMulticallablePreservesMsgSender() public { - address caller = address(uint160(0xbeef)); - bytes[] memory data = new bytes[](1); - data[0] = abi.encodeWithSelector(MockMulticallable.returnsSender.selector); - vm.prank(caller); - address returnedAddress = abi.decode(multicallable.multicall(data)[0], (address)); - assertEq(caller, returnedAddress); - } -} diff --git a/grouperBot/lib/solady/test/Ownable.t.sol b/grouperBot/lib/solady/test/Ownable.t.sol deleted file mode 100644 index 393c45a..0000000 --- a/grouperBot/lib/solady/test/Ownable.t.sol +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import "./utils/mocks/MockOwnable.sol"; - -contract OwnableTest is SoladyTest { - event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); - - event OwnershipHandoverRequested(address indexed pendingOwner); - - event OwnershipHandoverCanceled(address indexed pendingOwner); - - MockOwnable mockOwnable; - - function setUp() public { - mockOwnable = new MockOwnable(); - } - - function testBytecodeSize() public { - MockOwnableBytecodeSizer mock = new MockOwnableBytecodeSizer(); - assertTrue(address(mock).code.length > 0); - assertEq(mock.owner(), address(this)); - } - - function testInitializeOwnerDirect() public { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(0), address(1)); - mockOwnable.initializeOwnerDirect(address(1)); - } - - function testSetOwnerDirect(address newOwner) public { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), _cleaned(newOwner)); - mockOwnable.setOwnerDirect(newOwner); - assertEq(mockOwnable.owner(), newOwner); - } - - function testSetOwnerDirect() public { - testSetOwnerDirect(address(1)); - } - - function testRenounceOwnership() public { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), address(0)); - mockOwnable.renounceOwnership(); - assertEq(mockOwnable.owner(), address(0)); - } - - function testTransferOwnership( - address newOwner, - bool setNewOwnerToZeroAddress, - bool callerIsOwner - ) public { - assertEq(mockOwnable.owner(), address(this)); - - while (newOwner == address(this)) newOwner = _randomNonZeroAddress(); - - if (newOwner == address(0) || setNewOwnerToZeroAddress) { - newOwner = address(0); - vm.expectRevert(Ownable.NewOwnerIsZeroAddress.selector); - } else if (callerIsOwner) { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), _cleaned(newOwner)); - } else { - vm.prank(newOwner); - vm.expectRevert(Ownable.Unauthorized.selector); - } - - mockOwnable.transferOwnership(newOwner); - - if (newOwner != address(0) && callerIsOwner) { - assertEq(mockOwnable.owner(), newOwner); - } - } - - function testTransferOwnership() public { - testTransferOwnership(address(1), false, true); - } - - function testOnlyOwnerModifier(address nonOwner, bool callerIsOwner) public { - while (nonOwner == address(this)) nonOwner = _randomNonZeroAddress(); - - if (!callerIsOwner) { - vm.prank(nonOwner); - vm.expectRevert(Ownable.Unauthorized.selector); - } - mockOwnable.updateFlagWithOnlyOwner(); - } - - function testHandoverOwnership(address pendingOwner) public { - vm.prank(pendingOwner); - vm.expectEmit(true, true, true, true); - emit OwnershipHandoverRequested(_cleaned(pendingOwner)); - mockOwnable.requestOwnershipHandover(); - assertTrue(mockOwnable.ownershipHandoverExpiresAt(pendingOwner) > block.timestamp); - - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), _cleaned(pendingOwner)); - - mockOwnable.completeOwnershipHandover(pendingOwner); - - assertEq(mockOwnable.owner(), pendingOwner); - } - - function testHandoverOwnership() public { - testHandoverOwnership(address(1)); - } - - function testHandoverOwnershipRevertsIfCompleteIsNotOwner() public { - address pendingOwner = address(1); - vm.prank(pendingOwner); - mockOwnable.requestOwnershipHandover(); - - vm.prank(pendingOwner); - vm.expectRevert(Ownable.Unauthorized.selector); - mockOwnable.completeOwnershipHandover(pendingOwner); - } - - function testHandoverOwnershipWithCancellation() public { - address pendingOwner = address(1); - - vm.prank(pendingOwner); - vm.expectEmit(true, true, true, true); - emit OwnershipHandoverRequested(_cleaned(pendingOwner)); - mockOwnable.requestOwnershipHandover(); - assertTrue(mockOwnable.ownershipHandoverExpiresAt(pendingOwner) > block.timestamp); - - vm.expectEmit(true, true, true, true); - emit OwnershipHandoverCanceled(_cleaned(pendingOwner)); - vm.prank(pendingOwner); - mockOwnable.cancelOwnershipHandover(); - assertEq(mockOwnable.ownershipHandoverExpiresAt(pendingOwner), 0); - vm.expectRevert(Ownable.NoHandoverRequest.selector); - - mockOwnable.completeOwnershipHandover(pendingOwner); - } - - function testHandoverOwnershipBeforeExpiration() public { - address pendingOwner = address(1); - vm.prank(pendingOwner); - mockOwnable.requestOwnershipHandover(); - - vm.warp(block.timestamp + mockOwnable.ownershipHandoverValidFor()); - - mockOwnable.completeOwnershipHandover(pendingOwner); - } - - function testHandoverOwnershipAfterExpiration() public { - address pendingOwner = address(1); - vm.prank(pendingOwner); - mockOwnable.requestOwnershipHandover(); - - vm.warp(block.timestamp + mockOwnable.ownershipHandoverValidFor() + 1); - - vm.expectRevert(Ownable.NoHandoverRequest.selector); - - mockOwnable.completeOwnershipHandover(pendingOwner); - } - - function testOwnershipHandoverValidForDefaultValue() public { - assertEq(mockOwnable.ownershipHandoverValidFor(), 48 * 3600); - } -} diff --git a/grouperBot/lib/solady/test/OwnableRoles.t.sol b/grouperBot/lib/solady/test/OwnableRoles.t.sol deleted file mode 100644 index 82d5ebb..0000000 --- a/grouperBot/lib/solady/test/OwnableRoles.t.sol +++ /dev/null @@ -1,388 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import "./utils/mocks/MockOwnableRoles.sol"; - -contract OwnableRolesTest is SoladyTest { - event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); - - event OwnershipHandoverRequested(address indexed pendingOwner); - - event OwnershipHandoverCanceled(address indexed pendingOwner); - - event RolesUpdated(address indexed user, uint256 indexed roles); - - MockOwnableRoles mockOwnableRoles; - - function setUp() public { - mockOwnableRoles = new MockOwnableRoles(); - } - - function testBytecodeSize() public { - MockOwnableRolesBytecodeSizer mock = new MockOwnableRolesBytecodeSizer(); - assertTrue(address(mock).code.length > 0); - assertEq(mock.owner(), address(this)); - } - - function testInitializeOwnerDirect() public { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(0), address(1)); - mockOwnableRoles.initializeOwnerDirect(address(1)); - } - - function testSetOwnerDirect(address newOwner) public { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), _cleaned(newOwner)); - mockOwnableRoles.setOwnerDirect(newOwner); - assertEq(mockOwnableRoles.owner(), newOwner); - } - - function testGrantAndRemoveRolesDirect( - address user, - uint256 rolesToGrant, - uint256 rolesToRemove - ) public { - mockOwnableRoles.removeRolesDirect(user, mockOwnableRoles.rolesOf(user)); - assertEq(mockOwnableRoles.rolesOf(user), 0); - mockOwnableRoles.grantRolesDirect(user, rolesToGrant); - assertEq(mockOwnableRoles.rolesOf(user), rolesToGrant); - mockOwnableRoles.removeRolesDirect(user, rolesToRemove); - assertEq(mockOwnableRoles.rolesOf(user), rolesToGrant ^ (rolesToGrant & rolesToRemove)); - } - - struct _TestTemps { - address userA; - address userB; - uint256 rolesA; - uint256 rolesB; - } - - function testSetRolesDirect(uint256) public { - _TestTemps memory t; - t.userA = _randomNonZeroAddress(); - t.userB = _randomNonZeroAddress(); - while (t.userA == t.userB) t.userA = _randomNonZeroAddress(); - _testSetRolesDirect(t); - _testSetRolesDirect(t); - } - - function _testSetRolesDirect(_TestTemps memory t) internal { - t.rolesA = _random(); - t.rolesB = _random(); - vm.expectEmit(true, true, true, true); - emit RolesUpdated(_cleaned(t.userA), t.rolesA); - mockOwnableRoles.setRolesDirect(t.userA, t.rolesA); - emit RolesUpdated(_cleaned(t.userB), t.rolesB); - mockOwnableRoles.setRolesDirect(t.userB, t.rolesB); - assertEq(mockOwnableRoles.rolesOf(t.userA), t.rolesA); - assertEq(mockOwnableRoles.rolesOf(t.userB), t.rolesB); - } - - function testSetOwnerDirect() public { - testSetOwnerDirect(address(1)); - } - - function testRenounceOwnership() public { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), address(0)); - mockOwnableRoles.renounceOwnership(); - assertEq(mockOwnableRoles.owner(), address(0)); - } - - function testTransferOwnership( - address newOwner, - bool setNewOwnerToZeroAddress, - bool callerIsOwner - ) public { - assertEq(mockOwnableRoles.owner(), address(this)); - - while (newOwner == address(this)) newOwner = _randomNonZeroAddress(); - - if (newOwner == address(0) || setNewOwnerToZeroAddress) { - newOwner = address(0); - vm.expectRevert(Ownable.NewOwnerIsZeroAddress.selector); - } else if (callerIsOwner) { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), _cleaned(newOwner)); - } else { - vm.prank(newOwner); - vm.expectRevert(Ownable.Unauthorized.selector); - } - - mockOwnableRoles.transferOwnership(newOwner); - - if (newOwner != address(0) && callerIsOwner) { - assertEq(mockOwnableRoles.owner(), newOwner); - } - } - - function testTransferOwnership() public { - testTransferOwnership(address(1), false, true); - } - - function testGrantRoles() public { - vm.expectEmit(true, true, true, true); - emit RolesUpdated(address(1), 111111); - mockOwnableRoles.grantRoles(address(1), 111111); - } - - function testGrantAndRevokeOrRenounceRoles( - address user, - bool granterIsOwner, - bool useRenounce, - bool revokerIsOwner, - uint256 rolesToGrant, - uint256 rolesToRevoke - ) public { - while (user == address(this)) user = _randomNonZeroAddress(); - - uint256 rolesAfterRevoke = rolesToGrant ^ (rolesToGrant & rolesToRevoke); - - assertTrue(rolesAfterRevoke & rolesToRevoke == 0); - assertTrue((rolesAfterRevoke | rolesToRevoke) & rolesToGrant == rolesToGrant); - - if (granterIsOwner) { - vm.expectEmit(true, true, true, true); - emit RolesUpdated(_cleaned(user), rolesToGrant); - } else { - vm.prank(user); - vm.expectRevert(Ownable.Unauthorized.selector); - } - mockOwnableRoles.grantRoles(user, rolesToGrant); - - if (!granterIsOwner) return; - - assertEq(mockOwnableRoles.rolesOf(user), rolesToGrant); - - if (useRenounce) { - vm.expectEmit(true, true, true, true); - emit RolesUpdated(_cleaned(user), rolesAfterRevoke); - vm.prank(user); - mockOwnableRoles.renounceRoles(rolesToRevoke); - } else if (revokerIsOwner) { - vm.expectEmit(true, true, true, true); - emit RolesUpdated(_cleaned(user), rolesAfterRevoke); - mockOwnableRoles.revokeRoles(user, rolesToRevoke); - } else { - vm.prank(user); - vm.expectRevert(Ownable.Unauthorized.selector); - mockOwnableRoles.revokeRoles(user, rolesToRevoke); - return; - } - - assertEq(mockOwnableRoles.rolesOf(user), rolesAfterRevoke); - } - - function testHasAllRoles( - address user, - uint256 rolesToGrant, - uint256 rolesToGrantBrutalizer, - uint256 rolesToCheck, - bool useSameRoles - ) public { - if (useSameRoles) { - rolesToGrant = rolesToCheck; - } - rolesToGrant |= rolesToGrantBrutalizer; - mockOwnableRoles.grantRoles(user, rolesToGrant); - - bool hasAllRoles = (rolesToGrant & rolesToCheck) == rolesToCheck; - assertEq(mockOwnableRoles.hasAllRoles(user, rolesToCheck), hasAllRoles); - } - - function testHasAnyRole(address user, uint256 rolesToGrant, uint256 rolesToCheck) public { - mockOwnableRoles.grantRoles(user, rolesToGrant); - assertEq(mockOwnableRoles.hasAnyRole(user, rolesToCheck), rolesToGrant & rolesToCheck != 0); - } - - function testRolesFromOrdinals(uint8[] memory ordinals) public { - uint256 roles; - unchecked { - for (uint256 i; i < ordinals.length; ++i) { - roles |= 1 << uint256(ordinals[i]); - } - } - assertEq(mockOwnableRoles.rolesFromOrdinals(ordinals), roles); - } - - function testRolesFromOrdinals() public { - unchecked { - for (uint256 t; t != 32; ++t) { - uint8[] memory ordinals = new uint8[](_random() % 32); - for (uint256 i; i != ordinals.length; ++i) { - uint256 randomness = _random(); - uint8 r; - assembly { - r := randomness - } - ordinals[i] = r; - } - testRolesFromOrdinals(ordinals); - } - } - } - - function testOrdinalsFromRoles(uint256 roles) public { - uint8[] memory ordinals = new uint8[](256); - uint256 n; - unchecked { - for (uint256 i; i < 256; ++i) { - if (roles & (1 << i) != 0) ordinals[n++] = uint8(i); - } - } - uint8[] memory results = mockOwnableRoles.ordinalsFromRoles(roles); - assertEq(results.length, n); - unchecked { - for (uint256 i; i < n; ++i) { - assertEq(results[i], ordinals[i]); - } - } - } - - function testOrdinalsFromRoles() public { - unchecked { - for (uint256 t; t != 32; ++t) { - testOrdinalsFromRoles(_random()); - } - } - } - - function testOnlyOwnerModifier(address nonOwner, bool callerIsOwner) public { - while (nonOwner == address(this)) nonOwner = _randomNonZeroAddress(); - - if (!callerIsOwner) { - vm.prank(nonOwner); - vm.expectRevert(Ownable.Unauthorized.selector); - } - mockOwnableRoles.updateFlagWithOnlyOwner(); - } - - function testOnlyRolesModifier(address user, uint256 rolesToGrant, uint256 rolesToCheck) - public - { - mockOwnableRoles.grantRoles(user, rolesToGrant); - - if (rolesToGrant & rolesToCheck == 0) { - vm.expectRevert(Ownable.Unauthorized.selector); - } - vm.prank(user); - mockOwnableRoles.updateFlagWithOnlyRoles(rolesToCheck); - } - - function testOnlyOwnerOrRolesModifier( - address user, - bool callerIsOwner, - uint256 rolesToGrant, - uint256 rolesToCheck - ) public { - while (user == address(this)) user = _randomNonZeroAddress(); - - mockOwnableRoles.grantRoles(user, rolesToGrant); - - if ((rolesToGrant & rolesToCheck == 0) && !callerIsOwner) { - vm.expectRevert(Ownable.Unauthorized.selector); - } - if (!callerIsOwner) { - vm.prank(user); - } - mockOwnableRoles.updateFlagWithOnlyOwnerOrRoles(rolesToCheck); - } - - function testOnlyRolesOrOwnerModifier( - address user, - bool callerIsOwner, - uint256 rolesToGrant, - uint256 rolesToCheck - ) public { - while (user == address(this)) user = _randomNonZeroAddress(); - - mockOwnableRoles.grantRoles(user, rolesToGrant); - - if ((rolesToGrant & rolesToCheck == 0) && !callerIsOwner) { - vm.expectRevert(Ownable.Unauthorized.selector); - } - if (!callerIsOwner) { - vm.prank(user); - } - mockOwnableRoles.updateFlagWithOnlyRolesOrOwner(rolesToCheck); - } - - function testOnlyOwnerOrRolesModifier() public { - testOnlyOwnerOrRolesModifier(address(1), false, 1, 2); - } - - function testHandoverOwnership(address pendingOwner) public { - vm.prank(pendingOwner); - vm.expectEmit(true, true, true, true); - emit OwnershipHandoverRequested(_cleaned(pendingOwner)); - mockOwnableRoles.requestOwnershipHandover(); - assertTrue(mockOwnableRoles.ownershipHandoverExpiresAt(pendingOwner) > block.timestamp); - - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), _cleaned(pendingOwner)); - - mockOwnableRoles.completeOwnershipHandover(pendingOwner); - - assertEq(mockOwnableRoles.owner(), pendingOwner); - } - - function testHandoverOwnership() public { - testHandoverOwnership(address(1)); - } - - function testHandoverOwnershipRevertsIfCompleteIsNotOwner() public { - address pendingOwner = address(1); - vm.prank(pendingOwner); - mockOwnableRoles.requestOwnershipHandover(); - - vm.prank(pendingOwner); - vm.expectRevert(Ownable.Unauthorized.selector); - mockOwnableRoles.completeOwnershipHandover(pendingOwner); - } - - function testHandoverOwnershipWithCancellation() public { - address pendingOwner = address(1); - - vm.prank(pendingOwner); - vm.expectEmit(true, true, true, true); - emit OwnershipHandoverRequested(_cleaned(pendingOwner)); - mockOwnableRoles.requestOwnershipHandover(); - assertTrue(mockOwnableRoles.ownershipHandoverExpiresAt(pendingOwner) > block.timestamp); - - vm.expectEmit(true, true, true, true); - emit OwnershipHandoverCanceled(_cleaned(pendingOwner)); - vm.prank(pendingOwner); - mockOwnableRoles.cancelOwnershipHandover(); - assertEq(mockOwnableRoles.ownershipHandoverExpiresAt(pendingOwner), 0); - vm.expectRevert(Ownable.NoHandoverRequest.selector); - - mockOwnableRoles.completeOwnershipHandover(pendingOwner); - } - - function testHandoverOwnershipBeforeExpiration() public { - address pendingOwner = address(1); - vm.prank(pendingOwner); - mockOwnableRoles.requestOwnershipHandover(); - - vm.warp(block.timestamp + mockOwnableRoles.ownershipHandoverValidFor()); - - mockOwnableRoles.completeOwnershipHandover(pendingOwner); - } - - function testHandoverOwnershipAfterExpiration() public { - address pendingOwner = address(1); - vm.prank(pendingOwner); - mockOwnableRoles.requestOwnershipHandover(); - - vm.warp(block.timestamp + mockOwnableRoles.ownershipHandoverValidFor() + 1); - - vm.expectRevert(Ownable.NoHandoverRequest.selector); - - mockOwnableRoles.completeOwnershipHandover(pendingOwner); - } - - function testOwnershipHandoverValidForDefaultValue() public { - assertEq(mockOwnableRoles.ownershipHandoverValidFor(), 48 * 3600); - } -} diff --git a/grouperBot/lib/solady/test/P256.t.sol b/grouperBot/lib/solady/test/P256.t.sol deleted file mode 100644 index c38b16d..0000000 --- a/grouperBot/lib/solady/test/P256.t.sol +++ /dev/null @@ -1,427 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibString} from "../src/utils/LibString.sol"; -import {P256} from "../src/utils/P256.sol"; - -contract P256VerifierEtcher is SoladyTest { - bytes internal constant _VERIFIER_BYTECODE = - hex"3d604052610216565b60008060006ffffffffeffffffffffffffffffffffff60601b19808687098188890982838389096004098384858485093d510985868b8c096003090891508384828308850385848509089650838485858609600809850385868a880385088509089550505050808188880960020991505093509350939050565b81513d83015160408401516ffffffffeffffffffffffffffffffffff60601b19808384098183840982838388096004098384858485093d510985868a8b096003090896508384828308850385898a09089150610102848587890960020985868787880960080987038788878a0387088c0908848b523d8b015260408a0152565b505050505050505050565b81513d830151604084015185513d87015160408801518361013d578287523d870182905260408701819052610102565b80610157578587523d870185905260408701849052610102565b6ffffffffeffffffffffffffffffffffff60601b19808586098183840982818a099850828385830989099750508188830383838809089450818783038384898509870908935050826101be57836101be576101b28a89610082565b50505050505050505050565b808485098181860982828a09985082838a8b0884038483860386898a09080891506102088384868a0988098485848c09860386878789038f088a0908848d523d8d015260408c0152565b505050505050505050505050565b6020357fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325513d6040357f7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a88111156102695782035b60206108005260206108205260206108405280610860526002830361088052826108a0526ffffffffeffffffffffffffffffffffff60601b198060031860205260603560803560203d60c061080060055afa60203d1416837f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b8585873d5189898a09080908848384091484831085851016888710871510898b108b151016609f3611161616166103195760206080f35b60809182523d820152600160c08190527f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2966102009081527f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f53d909101526102405261038992509050610100610082565b610397610200610400610082565b6103a7610100608061018061010d565b6103b7610200608061028061010d565b6103c861020061010061030061010d565b6103d961020061018061038061010d565b6103e9610400608061048061010d565b6103fa61040061010061050061010d565b61040b61040061018061058061010d565b61041c61040061020061060061010d565b61042c610600608061068061010d565b61043d61060061010061070061010d565b61044e61060061018061078061010d565b81815182350982825185098283846ffffffffeffffffffffffffffffffffff60601b193d515b82156105245781858609828485098384838809600409848586848509860986878a8b096003090885868384088703878384090886878887880960080988038889848b03870885090887888a8d096002098882830996508881820995508889888509600409945088898a8889098a098a8b86870960030908935088898687088a038a868709089a5088898284096002099950505050858687868709600809870387888b8a0386088409089850505050505b61018086891b60f71c16610600888a1b60f51c16176040810151801585151715610564578061055357506105fe565b81513d8301519750955093506105fe565b83858609848283098581890986878584098b0991508681880388858851090887838903898a8c88093d8a015109089350836105b957806105b9576105a9898c8c610008565b9a509b50995050505050506105fe565b8781820988818309898285099350898a8586088b038b838d038d8a8b0908089b50898a8287098b038b8c8f8e0388088909089c5050508788868b098209985050505050505b5082156106af5781858609828485098384838809600409848586848509860986878a8b096003090885868384088703878384090886878887880960080988038889848b03870885090887888a8d096002098882830996508881820995508889888509600409945088898a8889098a098a8b86870960030908935088898687088a038a868709089a5088898284096002099950505050858687868709600809870387888b8a0386088409089850505050505b61018086891b60f51c16610600888a1b60f31c161760408101518015851517156106ef57806106de5750610789565b81513d830151975095509350610789565b83858609848283098581890986878584098b0991508681880388858851090887838903898a8c88093d8a01510908935083610744578061074457610734898c8c610008565b9a509b5099505050505050610789565b8781820988818309898285099350898a8586088b038b838d038d8a8b0908089b50898a8287098b038b8c8f8e0388088909089c5050508788868b098209985050505050505b50600488019760fb19016104745750816107a2573d6040f35b81610860526002810361088052806108a0523d3d60c061080060055afa898983843d513d510987090614163d525050505050505050503d3df3fea264697066735822122063ce32ec0e56e7893a1f6101795ce2e38aca14dd12adb703c71fe3bee27da71e64736f6c634300081a0033"; - - bytes internal constant _PASSTHROUGH_BYTECODE = hex"600160005260206000f3"; - - function _etchBytecode(address target, bytes memory bytecode, bool active) internal { - if (target == P256.RIP_PRECOMPILE) { - if (active && _hasNativeRIPPrecompile()) return; - if (!active && _hasNativeRIPPrecompile()) { - /// @solidity memory-safe-assembly - assembly { - return(0x00, 0x00) - } - } - } - - if (active) { - if (target.code.length == 0) vm.etch(target, bytecode); - } else { - if (target.code.length != 0) vm.etch(target, ""); - } - } - - function _hasNativeRIPPrecompile() internal view returns (bool) { - return P256.hasPrecompile() && P256.RIP_PRECOMPILE.code.length == 0; - } - - function _etchPassthroughBytecode(address target, bool active) internal { - _etchBytecode(target, _PASSTHROUGH_BYTECODE, active); - } - - function _etchVerifierBytecode(address target, bool active) internal { - _etchBytecode(target, _VERIFIER_BYTECODE, active); - } - - function _etchRIPPrecompilePassthrough(bool active) internal { - _etchPassthroughBytecode(P256.RIP_PRECOMPILE, active); - } - - function _etchVerifierPassthrough(bool active) internal { - _etchPassthroughBytecode(P256.VERIFIER, active); - } - - function _etchRIPPrecompile(bool active) internal { - _etchVerifierBytecode(P256.RIP_PRECOMPILE, active); - } - - function _etchVerifier(bool active) internal { - _etchVerifierBytecode(P256.VERIFIER, active); - } -} - -contract P256Test is P256VerifierEtcher { - // Public key x and y. - uint256 private constant _X = 0x65a2fa44daad46eab0278703edb6c4dcf5e30b8a9aec09fdc71a56f52aa392e4; - uint256 private constant _Y = 0x4a7a9e4604aa36898209997288e902ac544a555e4b5e0a9efef2b59233f3f437; - uint256 private constant _R = 0x01655c1753db6b61a9717e4ccc5d6c4bf7681623dd54c2d6babc55125756661c; - uint256 private constant _NON_MALLEABLE_S = - 0xf8cfdc3921ecf0f7aef50be09b0f98383392dd8079014df95fde2a04b79023a; - uint256 private constant _MALLEABLE_S = - 0xf073023b6de130f18510af41f64f067c39adccd59f8789a55dbbe822b0ea2317; - bytes32 private constant _HASH = - 0x267f9ea080b54bbea2443dff8aa543604564329783b6a515c6663a691c555490; - uint256 private constant _N = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551; - uint256 private constant _MALLEABILITY_THRESHOLD = - 0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8; - - mapping(bytes32 => bool) internal _vectorTested; - mapping(bytes32 => bool) internal _vectorResult; - - function setUp() public { - _etchRIPPrecompile(true); - _etchVerifier(true); - } - - function testP256VerifyMalleableRIPPrecompile() public { - _testP256VerifyMalleable(); - } - - function testP256VerifyMalleableVerifier() public { - _testP256VerifyMalleable(); - } - - function _verifySignatureAllowMalleability( - bytes32 hash, - uint256 r, - uint256 s, - uint256 x, - uint256 y - ) internal view returns (bool) { - return P256.verifySignatureAllowMalleability( - hash, bytes32(r), bytes32(s), bytes32(x), bytes32(y) - ); - } - - function _verifySignature(bytes32 hash, uint256 r, uint256 s, uint256 x, uint256 y) - internal - view - returns (bool) - { - return P256.verifySignature(hash, bytes32(r), bytes32(s), bytes32(x), bytes32(y)); - } - - function _testP256VerifyMalleable() internal { - assertTrue(_verifySignatureAllowMalleability(_HASH, _R, _MALLEABLE_S, _X, _Y)); - assertFalse(_verifySignature(_HASH, _R, _MALLEABLE_S, _X, _Y)); - } - - function testP256VerifyNonMalleableRIPPrecompile() public { - _testP256VerifyNonMalleable(); - } - - function testP256VerifyNonMalleableVerifier() public { - _testP256VerifyNonMalleable(); - } - - function verifySignature(bytes32 hash, bytes32 r, bytes32 s, bytes32 x, bytes32 y) - public - view - returns (bool) - { - return P256.verifySignature(hash, r, s, x, y); - } - - function verifySignatureAllowMalleability( - bytes32 hash, - bytes32 r, - bytes32 s, - bytes32 x, - bytes32 y - ) public view returns (bool) { - return P256.verifySignatureAllowMalleability(hash, r, s, x, y); - } - - function _testP256VerifyNonMalleable() internal { - assertTrue(_verifySignatureAllowMalleability(_HASH, _R, _NON_MALLEABLE_S, _X, _Y)); - assertTrue(_verifySignature(_HASH, _R, _NON_MALLEABLE_S, _X, _Y)); - } - - function testP256Verify(uint256 seed, bytes32 hash) public { - uint256 privateKey = _bound(uint256(keccak256(abi.encode(seed))), 1, _N - 1); - (bytes32 x, bytes32 y) = P256PublicKey.getPublicKey(privateKey); - (bytes32 r, bytes32 s) = vm.signP256(privateKey, hash); - assertTrue(_verifyViaVerifier(hash, r, s, x, y)); - assertFalse(_verifyViaVerifier(hash, r, s, x, bytes32(uint256(y) ^ 1))); - } - - function testP256VerifyWycheproof() public { - _testP256VerifyWycheproof("./test/data/wycheproof.jsonl"); - } - - function _testP256VerifyWycheproof(string memory file) internal { - vm.pauseGasMetering(); - uint256 numParseFails; - for (uint256 i = 1;; ++i) { - string memory vector = vm.readLine(file); - bool expected; - try vm.parseJsonBool(vector, ".valid") returns (bool valid) { - expected = valid; - } catch { - if (++numParseFails == 8) break; - continue; - } - bool result = _verifyViaVerifier( - vm.parseJsonBytes32(vector, ".hash"), - vm.parseJsonBytes32(vector, ".r"), - vm.parseJsonBytes32(vector, ".s"), - vm.parseJsonBytes32(vector, ".x"), - vm.parseJsonBytes32(vector, ".y") - ); - if (result != expected) { - bytes memory err = abi.encodePacked("Line: ", LibString.toString(i)); - err = abi.encodePacked(err, ", Expected: ", expected ? "1" : "0"); - err = abi.encodePacked(err, ", Returned: ", result ? "1" : "0"); - err = abi.encodePacked(err, ", Comment: ", vm.parseJsonString(vector, ".comment")); - revert(string(err)); - } - } - vm.resumeGasMetering(); - } - - function _verifyViaVerifier(bytes32 hash, uint256 r, uint256 s, uint256 x, uint256 y) - internal - returns (bool) - { - return _verifyViaVerifier(hash, bytes32(r), bytes32(s), bytes32(x), bytes32(y)); - } - - function _verifyViaVerifier(bytes32 hash, bytes32 r, bytes32 s, bytes32 x, bytes32 y) - internal - returns (bool) - { - bytes memory payload = abi.encode(hash, r, s, x, y); - if (uint256(y) & 0xff == 0) { - bytes memory truncatedPayload = abi.encodePacked(hash, r, s, x, bytes31(y)); - assertEq(truncatedPayload.length, 0x9f); - assertEq(abi.encodePacked(truncatedPayload, bytes1(0)), payload); - assertFalse(_verifierCall(truncatedPayload)); - } - if (_random() & 0x1f == 0) { - payload = abi.encodePacked(payload, new bytes(_random() & 0xff)); - } - bytes32 payloadHash = keccak256(payload); - if (_vectorTested[payloadHash]) return _vectorResult[payloadHash]; - _vectorTested[payloadHash] = true; - return (_vectorResult[payloadHash] = _verifierCall(payload)); - } - - function _verifierCall(bytes memory payload) internal returns (bool) { - (bool success, bytes memory result) = P256.VERIFIER.call(payload); - assertTrue(success); - return abi.decode(result, (bool)); - } - - function testP256VerifyOutOfBounds() public { - uint256 p = P256PublicKey.P; - assertFalse(_verifyViaVerifier(bytes32(0), 1, 1, 1, 1)); - assertFalse(_verifyViaVerifier(bytes32(0), 1, 1, 0, 1)); - assertFalse(_verifyViaVerifier(bytes32(0), 1, 1, 1, 0)); - assertFalse(_verifyViaVerifier(bytes32(0), 1, 1, 1, p)); - assertFalse(_verifyViaVerifier(bytes32(0), 1, 1, p, 1)); - assertFalse(_verifyViaVerifier(bytes32(0), 1, 1, p - 1, 1)); - } - - function testTryDecodePoint(bytes32 x, bytes32 y) public { - bytes memory encoded = abi.encodePacked(x, y); - (bytes32 xDecoded, bytes32 yDecoded) = P256.tryDecodePoint(encoded); - assertEq(xDecoded, x); - assertEq(yDecoded, y); - this.tryDecodePointCalldata(encoded, x, y); - } - - function tryDecodePointCalldata(bytes calldata encoded, bytes32 x, bytes32 y) public { - (bytes32 xDecoded, bytes32 yDecoded) = P256.tryDecodePointCalldata(encoded); - assertEq(xDecoded, x); - assertEq(yDecoded, y); - } - - function check_P256Normalized(uint256 s) public pure { - uint256 n = uint256(P256.N); - unchecked { - uint256 expected = s > (n / 2) ? n - s : s; - assert(uint256(P256.normalized(bytes32(s))) == expected); - } - } - - function testP256Normalized(uint256 privateKey, bytes32 hash) public { - while (privateKey == 0 || privateKey >= P256.N) { - privateKey = uint256(keccak256(abi.encode(privateKey))); - } - (uint256 x, uint256 y) = vm.publicKeyP256(privateKey); - - // Note that `vm.signP256` can produce `s` above `N / 2`. - (bytes32 r, bytes32 s) = vm.signP256(privateKey, hash); - - if (uint256(s) > P256.N / 2) { - assertFalse(P256.verifySignature(hash, r, s, bytes32(x), bytes32(y))); - assertTrue(P256.verifySignature(hash, r, P256.normalized(s), bytes32(x), bytes32(y))); - } else { - assertTrue(P256.verifySignature(hash, r, s, bytes32(x), bytes32(y))); - } - assertTrue(P256.verifySignatureAllowMalleability(hash, r, s, bytes32(x), bytes32(y))); - } - - function testHasPrecompileOrVerifier(bytes32) public { - bool etchPrecompile = _randomChance(2); - bool etchVerifier = _randomChance(2); - _etchRIPPrecompile(etchPrecompile); - _etchVerifier(etchVerifier); - assertEq(P256.hasPrecompileOrVerifier(), etchPrecompile || etchVerifier); - } -} - -/// @dev Library to derive P256 public key from private key -/// Should be removed if Foundry adds this functionality -/// See: https://github.com/foundry-rs/foundry/issues/7908 -/// From: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/P256.sol -library P256PublicKey { - uint256 internal constant GX = - 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296; - uint256 internal constant GY = - 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5; - uint256 internal constant P = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF; - uint256 internal constant N = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551; - uint256 internal constant A = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC; - uint256 internal constant B = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B; - uint256 internal constant P1DIV4 = - 0x3fffffffc0000000400000000000000000000000400000000000000000000000; - uint256 internal constant HALF_N = - 0x7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8; - - function getPublicKey(uint256 privateKey) internal view returns (bytes32, bytes32) { - (uint256 x, uint256 y, uint256 z) = _jMult(GX, GY, 1, privateKey); - return _affineFromJacobian(x, y, z); - } - - function _jMult(uint256 x, uint256 y, uint256 z, uint256 k) - private - pure - returns (uint256 rx, uint256 ry, uint256 rz) - { - unchecked { - for (uint256 i; i != 256; ++i) { - if (rz > 0) { - (rx, ry, rz) = _jDouble(rx, ry, rz); - } - if (k >> 255 > 0) { - if (rz == 0) { - (rx, ry, rz) = (x, y, z); - } else { - (rx, ry, rz) = _jAdd(rx, ry, rz, x, y, z); - } - } - k <<= 1; - } - } - } - - function _affineFromJacobian(uint256 jx, uint256 jy, uint256 jz) - private - view - returns (bytes32 ax, bytes32 ay) - { - if (jz == uint256(0)) return (0, 0); - uint256 zinv = invModPrime(jz, P); - uint256 zzinv = mulmod(zinv, zinv, P); - uint256 zzzinv = mulmod(zzinv, zinv, P); - ax = bytes32(mulmod(jx, zzinv, P)); - ay = bytes32(mulmod(jy, zzzinv, P)); - } - - function _jDouble(uint256 x, uint256 y, uint256 z) - private - pure - returns (uint256 rx, uint256 ry, uint256 rz) - { - uint256 p = P; - /// @solidity memory-safe-assembly - assembly { - let yy := mulmod(y, y, p) - let zz := mulmod(z, z, p) - mstore(0x00, mulmod(4, mulmod(x, yy, p), p)) - mstore(0x20, addmod(mulmod(3, mulmod(x, x, p), p), mulmod(A, mulmod(zz, zz, p), p), p)) - rx := addmod(mulmod(mload(0x20), mload(0x20), p), sub(p, mulmod(2, mload(0x00), p)), p) - ry := - addmod( - mulmod(mload(0x20), addmod(mload(0x00), sub(p, rx), p), p), - sub(p, mulmod(8, mulmod(yy, yy, p), p)), - p - ) - rz := mulmod(2, mulmod(y, z, p), p) - } - } - - function _jAdd(uint256 x1, uint256 y1, uint256 z1, uint256 x2, uint256 y2, uint256 z2) - private - pure - returns (uint256 rx, uint256 ry, uint256 rz) - { - uint256 p = P; - /// @solidity memory-safe-assembly - assembly { - let zz1 := mulmod(z1, z1, p) - mstore(0x60, mulmod(z2, z2, p)) - mstore(0x00, mulmod(x1, mload(0x60), p)) - mstore(0x20, mulmod(y1, mulmod(mload(0x60), z2, p), p)) - mstore(0x60, addmod(mulmod(x2, zz1, p), sub(p, mload(0x00)), p)) - let hh := mulmod(mload(0x60), mload(0x60), p) - let hhh := mulmod(mload(0x60), hh, p) - let r := addmod(mulmod(y2, mulmod(zz1, z1, p), p), sub(p, mload(0x20)), p) - rx := - addmod( - addmod(mulmod(r, r, p), sub(p, hhh), p), - sub(p, mulmod(2, mulmod(mload(0x00), hh, p), p)), - p - ) - ry := - addmod( - mulmod(r, addmod(mulmod(mload(0x00), hh, p), sub(p, rx), p), p), - sub(p, mulmod(mload(0x20), hhh, p)), - p - ) - rz := mulmod(mload(0x60), mulmod(z1, z2, p), p) - mstore(0x60, 0) - } - } - - function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { - unchecked { - return modExp(a, p - 2, p); - } - } - - function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { - (bool success, uint256 result) = tryModExp(b, e, m); - if (!success) revert(); - return result; - } - - function tryModExp(uint256 b, uint256 e, uint256 m) - internal - view - returns (bool success, uint256 result) - { - if (m == 0) return (false, 0); - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) - mstore(ptr, 0x20) - mstore(add(ptr, 0x20), 0x20) - mstore(add(ptr, 0x40), 0x20) - mstore(add(ptr, 0x60), b) - mstore(add(ptr, 0x80), e) - mstore(add(ptr, 0xa0), m) - success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) - result := mload(0x00) - } - } -} diff --git a/grouperBot/lib/solady/test/README.md b/grouperBot/lib/solady/test/README.md deleted file mode 100644 index 17268ea..0000000 --- a/grouperBot/lib/solady/test/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## WARNING! - -All test files are strictly intended for testing purposes only. - -Do NOT copy anything here into production code unless you really know what you are doing. \ No newline at end of file diff --git a/grouperBot/lib/solady/test/Receiver.t.sol b/grouperBot/lib/solady/test/Receiver.t.sol deleted file mode 100644 index 68fa005..0000000 --- a/grouperBot/lib/solady/test/Receiver.t.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {Receiver} from "../src/accounts/Receiver.sol"; -import {MockERC721} from "./utils/mocks/MockERC721.sol"; -import {MockERC1155} from "./utils/mocks/MockERC1155.sol"; -import {MockReceiver} from "./utils/mocks/MockReceiver.sol"; - -contract ReceiverTest is SoladyTest { - MockERC721 immutable erc721 = new MockERC721(); - MockERC1155 immutable erc1155 = new MockERC1155(); - MockReceiver immutable receiver = new MockReceiver(); - address immutable alice = address(bytes20("milady")); - - function setUp() public {} - - function testETHReceived() public { - payable(address(receiver)).transfer(1 ether); - } - - function testOnERC721Received() public { - erc721.mint(alice, 1); - vm.prank(alice); - erc721.safeTransferFrom(alice, address(receiver), 1); - } - - function testOnERC1155Received() public { - erc1155.mint(alice, 1, 1, ""); - vm.prank(alice); - erc1155.safeTransferFrom(alice, address(receiver), 1, 1, ""); - } - - function testOnERC1155BatchReceived() public { - erc1155.mint(alice, 1, 1, ""); - uint256[] memory ids = new uint256[](1); - ids[0] = 1; - uint256[] memory amts = new uint256[](1); - amts[0] = 1; - vm.prank(alice); - erc1155.safeBatchTransferFrom(alice, address(receiver), ids, amts, ""); - } -} diff --git a/grouperBot/lib/solady/test/RedBlackTree.t.sol b/grouperBot/lib/solady/test/RedBlackTree.t.sol deleted file mode 100644 index 559581f..0000000 --- a/grouperBot/lib/solady/test/RedBlackTree.t.sol +++ /dev/null @@ -1,638 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {LibSort} from "../src/utils/LibSort.sol"; -import {LibPRNG} from "../src/utils/LibPRNG.sol"; -import {RedBlackTreeLib} from "../src/utils/RedBlackTreeLib.sol"; - -contract RedBlackTreeLibTest is SoladyTest { - using RedBlackTreeLib for *; - using LibPRNG for *; - - RedBlackTreeLib.Tree tree; - RedBlackTreeLib.Tree tree2; - - function testRedBlackTreeInsertBenchStep() public { - unchecked { - LibPRNG.PRNG memory prng = LibPRNG.PRNG(123); - uint256 n = 128; - uint256 m = (1 << 160) - 1; - for (uint256 i; i != n; ++i) { - uint256 r = 1 | (prng.next() & m); - tree.insert(r); - } - _testIterateTree(); - } - } - - function testRedBlackTreeInsertBenchUint160() public { - unchecked { - LibPRNG.PRNG memory prng = LibPRNG.PRNG(123); - uint256 n = 128; - uint256[] memory a = _makeArray(n); - uint256 m = (1 << 160) - 1; - for (uint256 i; i != n; ++i) { - uint256 r = 1 | (prng.next() & m); - a[i] = r; - tree.insert(r); - } - } - } - - function testRedBlackTreeBenchUint160() public { - unchecked { - LibPRNG.PRNG memory prng = LibPRNG.PRNG(123); - uint256 n = 128; - uint256[] memory a = _makeArray(n); - uint256 m = (1 << 160) - 1; - for (uint256 i; i != n; ++i) { - uint256 r = 1 | (prng.next() & m); - a[i] = r; - tree.insert(r); - } - prng.shuffle(a); - for (uint256 i; i != n; ++i) { - tree.remove(a[i]); - } - assertEq(tree.size(), 0); - } - } - - function testRedBlackTreeInsertBenchUint256() public { - unchecked { - LibPRNG.PRNG memory prng = LibPRNG.PRNG(123); - uint256 n = 128; - uint256[] memory a = _makeArray(n); - for (uint256 i; i != n; ++i) { - uint256 r = 1 | prng.next(); - a[i] = r; - tree.insert(r); - } - } - } - - function testRedBlackTreeBenchUint256() public { - unchecked { - LibPRNG.PRNG memory prng = LibPRNG.PRNG(123); - uint256 n = 128; - uint256[] memory a = _makeArray(n); - for (uint256 i; i != n; ++i) { - uint256 r = 1 | prng.next(); - a[i] = r; - tree.insert(r); - } - prng.shuffle(a); - for (uint256 i; i != n; ++i) { - tree.remove(a[i]); - } - assertEq(tree.size(), 0); - } - } - - function testRedBlackTreeInsertAndRemove(uint256) public { - unchecked { - for (uint256 t; t < 2; ++t) { - _testRedBlackTreeInsertAndRemove(); - } - } - } - - function _testRemoveAndInsertBack(uint256[] memory a, uint256 n, uint256 t) internal { - unchecked { - uint256 choice = a[_random() % n]; - bytes32 ptr = tree.find(choice); - bool exists = !ptr.isEmpty(); - if (exists) { - assertEq(ptr.value(), choice); - _brutalizeScratchSpace(); - ptr.remove(); - if (_randomChance(4)) { - _brutalizeScratchSpace(); - tree.tryRemove(choice); - } - assertTrue(tree.find(choice).isEmpty()); - assertFalse(tree.exists(choice)); - } - if (t != 0) { - _testRemoveAndInsertBack(a, n, t - 1); - } - if (exists) { - _brutalizeScratchSpace(); - tree.insert(choice); - if (_randomChance(4)) { - _brutalizeScratchSpace(); - tree.tryInsert(choice); - } - assertFalse(tree.find(choice).isEmpty()); - assertTrue(tree.exists(choice)); - } - } - } - - function _testIterateTree() internal { - bytes32 ptr = tree.first(); - uint256 prevValue; - while (!ptr.isEmpty()) { - uint256 v = ptr.value(); - assertTrue(prevValue < v); - prevValue = v; - ptr = ptr.next(); - } - assertEq(ptr.next().value(), 0); - - ptr = tree.last(); - prevValue = 0; - while (!ptr.isEmpty()) { - uint256 v = ptr.value(); - assertTrue(prevValue == 0 || prevValue > v); - prevValue = v; - ptr = ptr.prev(); - } - assertEq(ptr.prev().value(), 0); - } - - function _testRedBlackTreeInsertAndRemove() internal { - uint256 n = _random() % (_randomChance(128) ? 32 : 8); - uint256[] memory a = _fillTree(n); - - LibSort.sort(a); - LibSort.uniquifySorted(a); - assertEq(a.length, n); - assertEq(tree.size(), n); - - assertEq(tree2.size(), 0); - - unchecked { - uint256 i; - bytes32 ptr = tree.first(); - while (!ptr.isEmpty()) { - assertEq(a[i++], ptr.value()); - ptr = ptr.next(); - } - assertEq(ptr.next().value(), 0); - } - - unchecked { - uint256 i = n; - bytes32 ptr = tree.last(); - while (!ptr.isEmpty()) { - assertEq(a[--i], ptr.value()); - ptr = ptr.prev(); - } - assertEq(ptr.prev().value(), 0); - } - - _testIterateTree(); - - LibPRNG.PRNG memory prng = LibPRNG.PRNG(_random()); - prng.shuffle(a); - - unchecked { - uint256 m = n < 8 ? 4 : n; - for (uint256 i; i != n; ++i) { - _brutalizeScratchSpace(); - tree.remove(a[i]); - assertEq(tree.size(), n - i - 1); - if (_random() % m == 0) { - _testIterateTree(); - } - } - } - assertEq(tree.size(), 0); - - unchecked { - if (_randomChance(2)) { - for (uint256 i; i != n; ++i) { - assertTrue(tree.find(a[i]).isEmpty()); - } - } - assertTrue(tree.first().isEmpty()); - assertEq(tree.first().value(), 0); - assertTrue(tree.last().isEmpty()); - assertEq(tree.last().value(), 0); - } - - assertEq(tree2.size(), 0); - } - - function testRedBlackTreeInsertAndRemove2(uint256) public { - unchecked { - uint256 n = _randomChance(2) ? 16 : 32; - uint256[] memory candidates = _makeArray(n); - for (uint256 i; i != n; ++i) { - candidates[i] = _bound(_random(), 1, type(uint256).max); - } - uint256[] memory records = _makeArray(0); - uint256 mode = 0; - for (uint256 t = _random() % 32 + 1; t != 0; --t) { - uint256 r = candidates[_random() % n]; - bytes32 ptr = tree.find(r); - if (mode == 0) { - if (ptr.isEmpty()) { - _brutalizeScratchSpace(); - tree.insert(r); - _addToArray(records, r); - } - } else { - if (!ptr.isEmpty()) { - _brutalizeScratchSpace(); - tree.remove(r); - _removeFromArray(records, r); - } - } - if (_randomChance(3)) mode = _random() % 2; - } - LibSort.sort(records); - assertEq(tree.size(), records.length); - - assertEq(tree2.size(), 0); - - { - uint256 i = 0; - bytes32 ptr = tree.first(); - while (!ptr.isEmpty()) { - assertEq(records[i++], ptr.value()); - ptr = ptr.next(); - } - assertEq(ptr.next().value(), 0); - } - } - } - - function _makeArray(uint256 size, uint256 maxCap) - internal - pure - returns (uint256[] memory result) - { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - mstore(result, size) - mstore(0x40, add(result, shl(5, add(maxCap, 1)))) - } - } - - function _makeArray(uint256 size) internal pure returns (uint256[] memory result) { - require(size <= 512, "Size too big."); - result = _makeArray(size, 512); - } - - function _addToArray(uint256[] memory a, uint256 x) internal pure { - /// @solidity memory-safe-assembly - assembly { - let exists := 0 - let n := mload(a) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - let o := add(add(a, 0x20), shl(5, i)) - if eq(mload(o), x) { - exists := 1 - break - } - } - if iszero(exists) { - n := add(n, 1) - mstore(add(a, shl(5, n)), x) - mstore(a, n) - } - } - } - - function _removeFromArray(uint256[] memory a, uint256 x) internal pure { - /// @solidity memory-safe-assembly - assembly { - let n := mload(a) - for { let i := 0 } lt(i, n) { i := add(i, 1) } { - let o := add(add(a, 0x20), shl(5, i)) - if eq(mload(o), x) { - mstore(o, mload(add(a, shl(5, n)))) - mstore(a, sub(n, 1)) - break - } - } - } - } - - function testRedBlackTreeInsertAndRemove3() public { - unchecked { - uint256 m = type(uint256).max; - for (uint256 i; i < 256; ++i) { - _brutalizeScratchSpace(); - tree.insert(m - i); - assertEq(tree.size(), i + 1); - } - for (uint256 i; i < 256; ++i) { - tree2.insert(i + 1); - assertEq(tree2.size(), i + 1); - } - for (uint256 i; i < 256; ++i) { - assertTrue(tree.exists(m - i)); - assertFalse(tree.exists(i + 1)); - assertTrue(tree2.exists(i + 1)); - assertFalse(tree2.exists(m - i)); - } - bytes32[] memory ptrs = new bytes32[](256); - for (uint256 i; i < 256; ++i) { - bytes32 ptr = tree.find(m - i); - _brutalizeScratchSpace(); - ptr.remove(); - assertTrue(ptr.value() != m - i); - ptrs[i] = ptr; - assertEq(tree.size(), 256 - (i + 1)); - } - for (uint256 i; i < 256; ++i) { - assertEq(ptrs[i].value(), 0); - vm.expectRevert(RedBlackTreeLib.PointerOutOfBounds.selector); - _brutalizeScratchSpace(); - this.remove(ptrs[i]); - } - for (uint256 i; i < 256; ++i) { - _brutalizeScratchSpace(); - tree2.remove(i + 1); - assertEq(tree2.size(), 256 - (i + 1)); - } - } - } - - function find(uint256 x) public view { - tree.find(x); - } - - function insert(uint256 x) public { - tree.insert(x); - } - - function remove(bytes32 ptr) public { - ptr.remove(); - } - - function testRedBlackTreeInsertOneGas() public { - unchecked { - for (uint256 i; i != 1; ++i) { - tree.insert(i + 1); - } - } - } - - function testRedBlackTreeInsertTwoGas() public { - unchecked { - for (uint256 i; i != 2; ++i) { - tree.insert(i + 1); - } - } - } - - function testRedBlackTreeInsertThreeGas() public { - unchecked { - for (uint256 i; i != 3; ++i) { - tree.insert(i + 1); - } - } - } - - function testRedBlackTreeInsertTenGas() public { - unchecked { - for (uint256 i; i != 10; ++i) { - tree.insert(i + 1); - } - } - } - - function testRedBlackTreeValues() public { - testRedBlackTreeValues(3); - } - - function testRedBlackTreeValues(uint256 n) public { - unchecked { - n = n & 7; - while (true) { - uint256[] memory values = new uint256[](n); - for (uint256 i; i != n; ++i) { - values[i] = 1 | _random(); - _brutalizeScratchSpace(); - tree.tryInsert(values[i]); - } - LibSort.sort(values); - LibSort.uniquifySorted(values); - uint256[] memory retrieved = tree.values(); - _checkMemory(); - assertEq(retrieved, values); - n = values.length; - if (_random() & 1 == 0) { - LibPRNG.PRNG memory prng = LibPRNG.PRNG(_random()); - prng.shuffle(values); - for (uint256 i; i != n; ++i) { - _brutalizeScratchSpace(); - tree.tryRemove(values[i]); - } - assertEq(tree.values(), new uint256[](0)); - if (_random() & 1 == 0) { - n += _random() & 15; - continue; - } - } - break; - } - } - } - - function testRedBlackTreeRejectsEmptyValue() public { - vm.expectRevert(RedBlackTreeLib.ValueIsEmpty.selector); - this.insert(0); - vm.expectRevert(RedBlackTreeLib.ValueDoesNotExist.selector); - this.remove(0); - vm.expectRevert(RedBlackTreeLib.ValueIsEmpty.selector); - this.find(0); - } - - function testRedBlackTreeRemoveViaPointer() public { - tree.insert(1); - tree.insert(2); - - bytes32 ptr = tree.find(1); - ptr.remove(); - ptr.remove(); - - vm.expectRevert(RedBlackTreeLib.PointerOutOfBounds.selector); - this.remove(ptr); - - ptr = bytes32(0); - vm.expectRevert(RedBlackTreeLib.ValueDoesNotExist.selector); - this.remove(ptr); - } - - function testRedBlackTreeTryInsertAndRemove() public { - tree.tryInsert(1); - tree.tryInsert(2); - assertEq(tree.size(), 2); - tree.tryInsert(1); - assertEq(tree.size(), 2); - tree.tryRemove(2); - assertEq(tree.size(), 1); - tree.tryRemove(2); - assertEq(tree.size(), 1); - } - - function testRedBlackTreeTreeFullReverts() public { - tree.insert(1); - bytes32 ptr = tree.find(1); - /// @solidity memory-safe-assembly - assembly { - ptr := shl(32, shr(32, ptr)) - sstore(ptr, or(sload(ptr), sub(shl(31, 1), 1))) - } - vm.expectRevert(RedBlackTreeLib.TreeIsFull.selector); - this.insert(2); - assertEq(tree.size(), 2 ** 31 - 1); - } - - function testRedBlackTreePointers() public { - assertTrue(tree.find(1).isEmpty()); - assertTrue(tree.find(2).isEmpty()); - - tree.insert(1); - tree.insert(2); - - assertFalse(tree.find(1).isEmpty()); - assertFalse(tree.find(2).isEmpty()); - - assertTrue(tree.find(1).prev().isEmpty()); - assertFalse(tree.find(1).next().isEmpty()); - - assertFalse(tree.find(2).prev().isEmpty()); - assertTrue(tree.find(2).next().isEmpty()); - - assertEq(tree.find(1).next(), tree.find(2)); - assertEq(tree.find(1), tree.find(2).prev()); - - assertTrue(tree.find(1).prev().isEmpty()); - assertTrue(tree.find(1).prev().prev().isEmpty()); - assertTrue(tree.find(1).prev().next().isEmpty()); - - assertTrue(tree.find(2).next().isEmpty()); - assertTrue(tree.find(2).next().next().isEmpty()); - assertTrue(tree.find(2).next().prev().isEmpty()); - - assertEq(tree.first(), tree.find(1)); - assertEq(tree.last(), tree.find(2)); - - assertTrue(tree.find(3).isEmpty()); - } - - function testRedBlackTreeNearest(uint256) public { - assertEq(tree.nearest(1), bytes32(0)); - uint256[] memory a = _fillTree(_random() % 8); - uint256 x = _bound(_random(), 1, type(uint256).max); - (uint256 nearestIndex, bool found) = _nearestIndex(a, x); - if (found) { - assertEq(tree.nearest(x).value(), a[nearestIndex]); - } else { - assertEq(tree.nearest(x), bytes32(0)); - } - } - - function _nearestIndex(uint256[] memory a, uint256 x) - internal - pure - returns (uint256 nearestIndex, bool found) - { - unchecked { - uint256 nearestValue = type(uint256).max; - uint256 nearestDist = type(uint256).max; - uint256 n = a.length; - for (uint256 i; i != n; ++i) { - uint256 y = a[i]; - uint256 dist = x < y ? y - x : x - y; - if (dist < nearestDist || (dist == nearestDist && y < nearestValue)) { - nearestIndex = i; - nearestValue = y; - nearestDist = dist; - found = true; - } - } - } - } - - function testRedBlackTreeNearestBefore(uint256) public { - assertEq(tree.nearestBefore(1), bytes32(0)); - uint256[] memory a = _fillTree(_random() % 8); - uint256 x = _bound(_random(), 1, type(uint256).max); - (uint256 nearestIndexBefore, bool found) = _nearestIndexBefore(a, x); - if (found) { - assertEq(tree.nearestBefore(x).value(), a[nearestIndexBefore]); - } else { - assertEq(tree.nearestBefore(x), bytes32(0)); - } - } - - function _nearestIndexBefore(uint256[] memory a, uint256 x) - internal - pure - returns (uint256 nearestIndex, bool found) - { - unchecked { - uint256 nearestDist = type(uint256).max; - uint256 n = a.length; - for (uint256 i; i != n; ++i) { - uint256 y = a[i]; - if (y > x) continue; - uint256 dist = x - y; - if (dist < nearestDist) { - nearestIndex = i; - nearestDist = dist; - found = true; - } - } - } - } - - function testRedBlackTreeNearestAfter(uint256) public { - assertEq(tree.nearestAfter(1), bytes32(0)); - uint256[] memory a = _fillTree(_random() % 8); - uint256 x = _bound(_random(), 1, type(uint256).max); - (uint256 nearestIndexAfter, bool found) = _nearestIndexAfter(a, x); - if (found) { - assertEq(tree.nearestAfter(x).value(), a[nearestIndexAfter]); - } else { - assertEq(tree.nearestAfter(x), bytes32(0)); - } - } - - function _nearestIndexAfter(uint256[] memory a, uint256 x) - internal - pure - returns (uint256 nearestIndex, bool found) - { - unchecked { - uint256 nearestDist = type(uint256).max; - uint256 n = a.length; - for (uint256 i; i != n; ++i) { - uint256 y = a[i]; - if (y < x) continue; - uint256 dist = y - x; - if (dist < nearestDist) { - nearestIndex = i; - nearestDist = dist; - found = true; - } - } - } - } - - function _fillTree(uint256 n) internal returns (uint256[] memory a) { - a = _makeArray(n); - unchecked { - for (uint256 i; i != n;) { - uint256 r = _bound(_random(), 1, type(uint256).max); - if (tree.find(r).isEmpty()) { - a[i++] = r; - _brutalizeScratchSpace(); - tree.insert(r); - } - if (_randomChance(4)) { - _testRemoveAndInsertBack(a, i, (3 + i >> 2)); - } - } - } - } -} diff --git a/grouperBot/lib/solady/test/ReentrancyGuard.t.sol b/grouperBot/lib/solady/test/ReentrancyGuard.t.sol deleted file mode 100644 index 9cc0392..0000000 --- a/grouperBot/lib/solady/test/ReentrancyGuard.t.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {ReentrancyGuard} from "../src/utils/ReentrancyGuard.sol"; -import {MockReentrancyGuard, ReentrancyAttack} from "./utils/mocks/MockReentrancyGuard.sol"; - -contract ReentrancyGuardTest is SoladyTest { - MockReentrancyGuard immutable target = new MockReentrancyGuard(); - ReentrancyAttack immutable reentrancyAttack = new ReentrancyAttack(); - - // Before and after each test, the reentrancy guard should be unlocked. - modifier expectBeforeAfterReentrancyGuardUnlocked() { - assertEq(target.isReentrancyGuardLocked(), false); - _; - assertEq(target.isReentrancyGuardLocked(), false); - } - - function testRevertGuardLocked() external expectBeforeAfterReentrancyGuardUnlocked { - // Attempt to call a `nonReentrant` methiod with an unprotected method. - // Expect a success. - target.callUnguardedToGuarded(); - assertEq(target.enterTimes(), 1); - - // Attempt to call a `nonReentrant` method within a `nonReentrant` method. - // Expect a revert with the `Reentrancy` error. - vm.expectRevert(ReentrancyGuard.Reentrancy.selector); - target.callGuardedToGuarded(); - } - - function testRevertReadGuardLocked() external expectBeforeAfterReentrancyGuardUnlocked { - // Attempt to call a `nonReadReentrant` methiod with an unprotected method. - // Expect a success. - target.callUnguardedToReadGuarded(); - assertEq(target.enterTimes(), 1); - - // Attempt to call a `nonReadReentrant` method within a `nonReentrant` method. - // Expect a revert with the `Reentrancy` error. - vm.expectRevert(ReentrancyGuard.Reentrancy.selector); - target.callGuardedToReadGuarded(); - } - - function testRevertRemoteCallback() external expectBeforeAfterReentrancyGuardUnlocked { - // Attempt to reenter a `nonReentrant` method from a remote contract. - vm.expectRevert(ReentrancyAttack.ReentrancyAttackFailed.selector); - target.countAndCall(reentrancyAttack); - } - - function testRecursiveDirectUnguardedCall() external expectBeforeAfterReentrancyGuardUnlocked { - // Expect to be able to call unguarded methods recursively. - // Expect a success. - target.countUnguardedDirectRecursive(10); - assertEq(target.enterTimes(), 10); - } - - function testRevertRecursiveDirectGuardedCall() - external - expectBeforeAfterReentrancyGuardUnlocked - { - // Attempt to reenter a `nonReentrant` method from a direct call. - // Expect a revert with the `Reentrancy` error. - vm.expectRevert(ReentrancyGuard.Reentrancy.selector); - target.countGuardedDirectRecursive(10); - assertEq(target.enterTimes(), 0); - } - - function testRecursiveIndirectUnguardedCall() - external - expectBeforeAfterReentrancyGuardUnlocked - { - // Expect to be able to call unguarded methods recursively. - // Expect a success. - target.countUnguardedIndirectRecursive(10); - assertEq(target.enterTimes(), 10); - } - - function testRevertRecursiveIndirectGuardedCall() - external - expectBeforeAfterReentrancyGuardUnlocked - { - // Attempt to reenter a `nonReentrant` method from an indirect call. - vm.expectRevert(ReentrancyGuard.Reentrancy.selector); - target.countGuardedIndirectRecursive(10); - assertEq(target.enterTimes(), 0); - } -} diff --git a/grouperBot/lib/solady/test/ReentrancyGuardTransient.t.sol b/grouperBot/lib/solady/test/ReentrancyGuardTransient.t.sol deleted file mode 100644 index 66d35f8..0000000 --- a/grouperBot/lib/solady/test/ReentrancyGuardTransient.t.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "./utils/SoladyTest.sol"; -import {ReentrancyGuardTransient} from "../src/utils/ReentrancyGuardTransient.sol"; -import { - MockReentrancyGuardTransient, - ReentrancyAttack -} from "./utils/mocks/MockReentrancyGuardTransient.sol"; - -contract ReentrancyGuardTransientTest is SoladyTest { - MockReentrancyGuardTransient immutable target = new MockReentrancyGuardTransient(); - ReentrancyAttack immutable reentrancyAttack = new ReentrancyAttack(); - - // Before and after each test, the reentrancy guard should be unlocked. - modifier expectBeforeAfterReentrancyGuardTransientUnlocked() { - assertEq(target.isReentrancyGuardLocked(), false); - _; - assertEq(target.isReentrancyGuardLocked(), false); - } - - function testRevertGuardLocked(uint8 chainId, bool transientOnlyOnMainnet) - external - expectBeforeAfterReentrancyGuardTransientUnlocked - { - vm.chainId(chainId); - target.setTransientOnlyOnMainnet(transientOnlyOnMainnet); - // Attempt to call a `nonReentrant` methiod with an unprotected method. - // Expect a success. - target.callUnguardedToGuarded(); - assertEq(target.enterTimes(), 1); - - // Attempt to call a `nonReentrant` method within a `nonReentrant` method. - // Expect a revert with the `Reentrancy` error. - vm.expectRevert(ReentrancyGuardTransient.Reentrancy.selector); - target.callGuardedToGuarded(); - } - - function testRevertReadGuardLocked(uint8 chainId, bool transientOnlyOnMainnet) - external - expectBeforeAfterReentrancyGuardTransientUnlocked - { - vm.chainId(chainId); - target.setTransientOnlyOnMainnet(transientOnlyOnMainnet); - // Attempt to call a `nonReadReentrant` methiod with an unprotected method. - // Expect a success. - target.callUnguardedToReadGuarded(); - assertEq(target.enterTimes(), 1); - - // Attempt to call a `nonReadReentrant` method within a `nonReentrant` method. - // Expect a revert with the `Reentrancy` error. - vm.expectRevert(ReentrancyGuardTransient.Reentrancy.selector); - target.callGuardedToReadGuarded(); - } - - function testRevertRemoteCallback(uint8 chainId, bool transientOnlyOnMainnet) - external - expectBeforeAfterReentrancyGuardTransientUnlocked - { - vm.chainId(chainId); - target.setTransientOnlyOnMainnet(transientOnlyOnMainnet); - // Attempt to reenter a `nonReentrant` method from a remote contract. - vm.expectRevert(ReentrancyAttack.ReentrancyAttackFailed.selector); - target.countAndCall(reentrancyAttack); - } - - function testRecursiveDirectUnguardedCall(uint8 chainId, bool transientOnlyOnMainnet) - external - expectBeforeAfterReentrancyGuardTransientUnlocked - { - vm.chainId(chainId); - target.setTransientOnlyOnMainnet(transientOnlyOnMainnet); - // Expect to be able to call unguarded methods recursively. - // Expect a success. - target.countUnguardedDirectRecursive(10); - assertEq(target.enterTimes(), 10); - } - - function testRevertRecursiveDirectGuardedCall(uint8 chainId, bool transientOnlyOnMainnet) - external - expectBeforeAfterReentrancyGuardTransientUnlocked - { - vm.chainId(chainId); - target.setTransientOnlyOnMainnet(transientOnlyOnMainnet); - // Attempt to reenter a `nonReentrant` method from a direct call. - // Expect a revert with the `Reentrancy` error. - vm.expectRevert(ReentrancyGuardTransient.Reentrancy.selector); - target.countGuardedDirectRecursive(10); - assertEq(target.enterTimes(), 0); - } - - function testRecursiveIndirectUnguardedCall(uint8 chainId, bool transientOnlyOnMainnet) - external - expectBeforeAfterReentrancyGuardTransientUnlocked - { - vm.chainId(chainId); - target.setTransientOnlyOnMainnet(transientOnlyOnMainnet); - // Expect to be able to call unguarded methods recursively. - // Expect a success. - target.countUnguardedIndirectRecursive(10); - assertEq(target.enterTimes(), 10); - } - - function testRevertRecursiveIndirectGuardedCall(uint8 chainId, bool transientOnlyOnMainnet) - external - expectBeforeAfterReentrancyGuardTransientUnlocked - { - vm.chainId(chainId); - target.setTransientOnlyOnMainnet(transientOnlyOnMainnet); - // Attempt to reenter a `nonReentrant` method from an indirect call. - vm.expectRevert(ReentrancyGuardTransient.Reentrancy.selector); - target.countGuardedIndirectRecursive(10); - assertEq(target.enterTimes(), 0); - } -} diff --git a/grouperBot/lib/solady/test/SSTORE2.t.sol b/grouperBot/lib/solady/test/SSTORE2.t.sol deleted file mode 100644 index 1879df5..0000000 --- a/grouperBot/lib/solady/test/SSTORE2.t.sol +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {SSTORE2} from "../src/utils/SSTORE2.sol"; -import {LibString} from "../src/utils/LibString.sol"; -import {FixedPointMathLib} from "../src/utils/FixedPointMathLib.sol"; - -contract SSTORE2Test is SoladyTest { - uint256 internal constant _DATA_MAX_LENGTH = 0xfffe; - - function testWriteRead() public { - bytes memory data = "this is a test"; - assertEq(SSTORE2.read(SSTORE2.write(data)), data); - } - - function testWriteReadFullStartBound() public { - assertEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 0), hex"11223344"); - } - - function testWriteReadCustomStartBound() public { - assertEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1), hex"223344"); - } - - function testWriteReadFullBoundedRead() public { - bytes memory data = "this is a test"; - assertEq(SSTORE2.read(SSTORE2.write(data), 0, data.length), data); - } - - function testWriteReadCustomBounds() public { - assertEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1, 3), hex"2233"); - } - - function testWriteReadEmptyBound() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 3, 3); - } - - function testReadRevertsOnZeroCodeAddress(address pointer) public { - while (pointer.code.length != 0) pointer = _randomNonZeroAddress(); - _maybeBrutalizeMemory(); - if (_randomChance(2)) { - vm.expectRevert(); - _mustCompute(this.read(pointer)); - return; - } - if (_randomChance(2)) { - vm.expectRevert(); - _mustCompute(this.read(pointer, _random())); - return; - } - if (_randomChance(2)) { - vm.expectRevert(); - _mustCompute(this.read(pointer, _random(), _random())); - return; - } - pointer = SSTORE2.write(""); - assertEq(this.read(pointer), ""); - assertEq(this.read(pointer, _random()), ""); - assertEq(this.read(pointer, _random(), _random()), ""); - } - - function read(address pointer) public view returns (bytes memory) { - return SSTORE2.read(pointer); - } - - function read(address pointer, uint256 start) public view returns (bytes memory) { - return SSTORE2.read(pointer, start); - } - - function read(address pointer, uint256 start, uint256 end) public view returns (bytes memory) { - return SSTORE2.read(pointer, start, end); - } - - function _mustCompute(bytes memory s) internal { - /// @solidity memory-safe-assembly - assembly { - if eq(keccak256(s, 0x80), 123) { sstore(keccak256(0x00, 0x21), 1) } - } - } - - function testWriteRead(uint256 startIndex, uint256 endIndex) public { - bytes memory data = _truncateBytes(_randomBytes(), _DATA_MAX_LENGTH); - - if (_randomChance(2)) { - startIndex = _bound(_random(), 0, data.length + 2); - endIndex = _bound(_random(), 0, data.length + 2); - } - - _maybeBrutalizeMemory(); - - address pointer = SSTORE2.write(data); - - if (_randomChance(2)) assertEq(pointer.code, abi.encodePacked(hex"00", data)); - - _maybeBrutalizeMemory(); - - bytes memory readResult = SSTORE2.read(pointer, startIndex, endIndex); - _checkMemory(readResult); - assertEq(readResult, bytes(LibString.slice(string(data), startIndex, endIndex))); - - _maybeBrutalizeMemory(); - - if (_randomChance(2)) { - readResult = SSTORE2.read(pointer, startIndex); - _checkMemory(readResult); - assertEq(readResult, bytes(LibString.slice(string(data), startIndex))); - } - - readResult = SSTORE2.read(pointer); - _checkMemory(readResult); - assertEq(readResult, data); - } - - function testWriteWithTooBigDataReverts() public { - bytes memory data = new bytes(_DATA_MAX_LENGTH); - address pointer = this.write(data); - assertEq(SSTORE2.read(pointer), data); - vm.expectRevert(); - pointer = this.write(new bytes(_DATA_MAX_LENGTH + 1)); - } - - function write(bytes memory data) public returns (address) { - return SSTORE2.write(data); - } - - function testWriteReadDeterministic() public { - bytes32 salt = keccak256("salt"); - bytes memory data = "this is a test"; - assertEq(SSTORE2.writeDeterministic(data, salt).code, abi.encodePacked(hex"00", data)); - } - - function testWriteReadDeterministic(bytes memory data, bytes32 salt) public { - address predicted = SSTORE2.predictDeterministicAddress(salt, _brutalized(address(this))); - address pointer = SSTORE2.writeDeterministic(data, salt); - assertEq(pointer, predicted); - assertEq(SSTORE2.read(predicted), data); - if (_randomChance(32)) { - if (_randomChance(2)) data = _truncateBytes(_randomBytes(), 0xfffe); - vm.expectRevert(SSTORE2.DeploymentFailed.selector); - this.testWriteReadDeterministic(data, salt); - } - } - - function testWriteReadCounterfactual(bytes calldata data, bytes32 salt, address deployer) - public - { - while (deployer.code.length != 0) deployer = _randomHashedAddress(); - address predicted = SSTORE2.predictCounterfactualAddress(data, salt, deployer); - - vm.prank(deployer); - address pointer = SSTORE2.writeCounterfactual(data, salt); - assertEq(SSTORE2.read(pointer), data); - assertEq(pointer, predicted); - - assertEq(SSTORE2.write(data).code, pointer.code); - - if (_randomChance(32)) { - vm.expectRevert(SSTORE2.DeploymentFailed.selector); - this.testWriteReadCounterfactual(data, salt, deployer); - } - } - - function testReadSlicing() public { - bytes memory data = "1234567890123456789012345678901234567890123456789012345678901234"; - address pointer = SSTORE2.write(data); - assertEq(SSTORE2.read(pointer), data); - assertEq(SSTORE2.read(pointer, 32), "34567890123456789012345678901234"); - assertEq(SSTORE2.read(pointer, 0, 64), data); - assertEq(SSTORE2.read(pointer, 0, 65), data); - assertEq(SSTORE2.read(pointer, 0, 32), "12345678901234567890123456789012"); - assertEq(SSTORE2.read(pointer, 1, 32), "2345678901234567890123456789012"); - } - - function _maybeBrutalizeMemory() internal { - if (_randomChance(2)) _misalignFreeMemoryPointer(); - if (_randomChance(16)) _brutalizeMemory(); - } -} diff --git a/grouperBot/lib/solady/test/SafeCastLib.t.sol b/grouperBot/lib/solady/test/SafeCastLib.t.sol deleted file mode 100644 index 4a64da9..0000000 --- a/grouperBot/lib/solady/test/SafeCastLib.t.sol +++ /dev/null @@ -1,1407 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {SafeCastLib} from "../src/utils/SafeCastLib.sol"; - -contract SafeCastLibTest is SoladyTest { - function toUint8(uint256 x) public pure returns (uint8) { - return SafeCastLib.toUint8(x); - } - - function toUint16(uint256 x) public pure returns (uint16) { - return SafeCastLib.toUint16(x); - } - - function toUint24(uint256 x) public pure returns (uint24) { - return SafeCastLib.toUint24(x); - } - - function toUint32(uint256 x) public pure returns (uint32) { - return SafeCastLib.toUint32(x); - } - - function toUint40(uint256 x) public pure returns (uint40) { - return SafeCastLib.toUint40(x); - } - - function toUint48(uint256 x) public pure returns (uint48) { - return SafeCastLib.toUint48(x); - } - - function toUint56(uint256 x) public pure returns (uint56) { - return SafeCastLib.toUint56(x); - } - - function toUint64(uint256 x) public pure returns (uint64) { - return SafeCastLib.toUint64(x); - } - - function toUint72(uint256 x) public pure returns (uint72) { - return SafeCastLib.toUint72(x); - } - - function toUint80(uint256 x) public pure returns (uint80) { - return SafeCastLib.toUint80(x); - } - - function toUint88(uint256 x) public pure returns (uint88) { - return SafeCastLib.toUint88(x); - } - - function toUint96(uint256 x) public pure returns (uint96) { - return SafeCastLib.toUint96(x); - } - - function toUint104(uint256 x) public pure returns (uint104) { - return SafeCastLib.toUint104(x); - } - - function toUint112(uint256 x) public pure returns (uint112) { - return SafeCastLib.toUint112(x); - } - - function toUint120(uint256 x) public pure returns (uint120) { - return SafeCastLib.toUint120(x); - } - - function toUint128(uint256 x) public pure returns (uint128) { - return SafeCastLib.toUint128(x); - } - - function toUint136(uint256 x) public pure returns (uint136) { - return SafeCastLib.toUint136(x); - } - - function toUint144(uint256 x) public pure returns (uint144) { - return SafeCastLib.toUint144(x); - } - - function toUint152(uint256 x) public pure returns (uint152) { - return SafeCastLib.toUint152(x); - } - - function toUint160(uint256 x) public pure returns (uint160) { - return SafeCastLib.toUint160(x); - } - - function toUint168(uint256 x) public pure returns (uint168) { - return SafeCastLib.toUint168(x); - } - - function toUint176(uint256 x) public pure returns (uint176) { - return SafeCastLib.toUint176(x); - } - - function toUint184(uint256 x) public pure returns (uint184) { - return SafeCastLib.toUint184(x); - } - - function toUint192(uint256 x) public pure returns (uint192) { - return SafeCastLib.toUint192(x); - } - - function toUint200(uint256 x) public pure returns (uint200) { - return SafeCastLib.toUint200(x); - } - - function toUint208(uint256 x) public pure returns (uint208) { - return SafeCastLib.toUint208(x); - } - - function toUint216(uint256 x) public pure returns (uint216) { - return SafeCastLib.toUint216(x); - } - - function toUint224(uint256 x) public pure returns (uint224) { - return SafeCastLib.toUint224(x); - } - - function toUint232(uint256 x) public pure returns (uint232) { - return SafeCastLib.toUint232(x); - } - - function toUint240(uint256 x) public pure returns (uint240) { - return SafeCastLib.toUint240(x); - } - - function toUint248(uint256 x) public pure returns (uint248) { - return SafeCastLib.toUint248(x); - } - - function toInt8(int256 x) public pure returns (int8) { - return SafeCastLib.toInt8(x); - } - - function toInt16(int256 x) public pure returns (int16) { - return SafeCastLib.toInt16(x); - } - - function toInt24(int256 x) public pure returns (int24) { - return SafeCastLib.toInt24(x); - } - - function toInt32(int256 x) public pure returns (int32) { - return SafeCastLib.toInt32(x); - } - - function toInt40(int256 x) public pure returns (int40) { - return SafeCastLib.toInt40(x); - } - - function toInt48(int256 x) public pure returns (int48) { - return SafeCastLib.toInt48(x); - } - - function toInt56(int256 x) public pure returns (int56) { - return SafeCastLib.toInt56(x); - } - - function toInt64(int256 x) public pure returns (int64) { - return SafeCastLib.toInt64(x); - } - - function toInt72(int256 x) public pure returns (int72) { - return SafeCastLib.toInt72(x); - } - - function toInt80(int256 x) public pure returns (int80) { - return SafeCastLib.toInt80(x); - } - - function toInt88(int256 x) public pure returns (int88) { - return SafeCastLib.toInt88(x); - } - - function toInt96(int256 x) public pure returns (int96) { - return SafeCastLib.toInt96(x); - } - - function toInt104(int256 x) public pure returns (int104) { - return SafeCastLib.toInt104(x); - } - - function toInt112(int256 x) public pure returns (int112) { - return SafeCastLib.toInt112(x); - } - - function toInt120(int256 x) public pure returns (int120) { - return SafeCastLib.toInt120(x); - } - - function toInt128(int256 x) public pure returns (int128) { - return SafeCastLib.toInt128(x); - } - - function toInt136(int256 x) public pure returns (int136) { - return SafeCastLib.toInt136(x); - } - - function toInt144(int256 x) public pure returns (int144) { - return SafeCastLib.toInt144(x); - } - - function toInt152(int256 x) public pure returns (int152) { - return SafeCastLib.toInt152(x); - } - - function toInt160(int256 x) public pure returns (int160) { - return SafeCastLib.toInt160(x); - } - - function toInt168(int256 x) public pure returns (int168) { - return SafeCastLib.toInt168(x); - } - - function toInt176(int256 x) public pure returns (int176) { - return SafeCastLib.toInt176(x); - } - - function toInt184(int256 x) public pure returns (int184) { - return SafeCastLib.toInt184(x); - } - - function toInt192(int256 x) public pure returns (int192) { - return SafeCastLib.toInt192(x); - } - - function toInt200(int256 x) public pure returns (int200) { - return SafeCastLib.toInt200(x); - } - - function toInt208(int256 x) public pure returns (int208) { - return SafeCastLib.toInt208(x); - } - - function toInt216(int256 x) public pure returns (int216) { - return SafeCastLib.toInt216(x); - } - - function toInt224(int256 x) public pure returns (int224) { - return SafeCastLib.toInt224(x); - } - - function toInt232(int256 x) public pure returns (int232) { - return SafeCastLib.toInt232(x); - } - - function toInt240(int256 x) public pure returns (int240) { - return SafeCastLib.toInt240(x); - } - - function toInt248(int256 x) public pure returns (int248) { - return SafeCastLib.toInt248(x); - } - - function toInt8(uint256 x) public pure returns (int8) { - return SafeCastLib.toInt8(x); - } - - function toInt16(uint256 x) public pure returns (int16) { - return SafeCastLib.toInt16(x); - } - - function toInt24(uint256 x) public pure returns (int24) { - return SafeCastLib.toInt24(x); - } - - function toInt32(uint256 x) public pure returns (int32) { - return SafeCastLib.toInt32(x); - } - - function toInt40(uint256 x) public pure returns (int40) { - return SafeCastLib.toInt40(x); - } - - function toInt48(uint256 x) public pure returns (int48) { - return SafeCastLib.toInt48(x); - } - - function toInt56(uint256 x) public pure returns (int56) { - return SafeCastLib.toInt56(x); - } - - function toInt64(uint256 x) public pure returns (int64) { - return SafeCastLib.toInt64(x); - } - - function toInt72(uint256 x) public pure returns (int72) { - return SafeCastLib.toInt72(x); - } - - function toInt80(uint256 x) public pure returns (int80) { - return SafeCastLib.toInt80(x); - } - - function toInt88(uint256 x) public pure returns (int88) { - return SafeCastLib.toInt88(x); - } - - function toInt96(uint256 x) public pure returns (int96) { - return SafeCastLib.toInt96(x); - } - - function toInt104(uint256 x) public pure returns (int104) { - return SafeCastLib.toInt104(x); - } - - function toInt112(uint256 x) public pure returns (int112) { - return SafeCastLib.toInt112(x); - } - - function toInt120(uint256 x) public pure returns (int120) { - return SafeCastLib.toInt120(x); - } - - function toInt128(uint256 x) public pure returns (int128) { - return SafeCastLib.toInt128(x); - } - - function toInt136(uint256 x) public pure returns (int136) { - return SafeCastLib.toInt136(x); - } - - function toInt144(uint256 x) public pure returns (int144) { - return SafeCastLib.toInt144(x); - } - - function toInt152(uint256 x) public pure returns (int152) { - return SafeCastLib.toInt152(x); - } - - function toInt160(uint256 x) public pure returns (int160) { - return SafeCastLib.toInt160(x); - } - - function toInt168(uint256 x) public pure returns (int168) { - return SafeCastLib.toInt168(x); - } - - function toInt176(uint256 x) public pure returns (int176) { - return SafeCastLib.toInt176(x); - } - - function toInt184(uint256 x) public pure returns (int184) { - return SafeCastLib.toInt184(x); - } - - function toInt192(uint256 x) public pure returns (int192) { - return SafeCastLib.toInt192(x); - } - - function toInt200(uint256 x) public pure returns (int200) { - return SafeCastLib.toInt200(x); - } - - function toInt208(uint256 x) public pure returns (int208) { - return SafeCastLib.toInt208(x); - } - - function toInt216(uint256 x) public pure returns (int216) { - return SafeCastLib.toInt216(x); - } - - function toInt224(uint256 x) public pure returns (int224) { - return SafeCastLib.toInt224(x); - } - - function toInt232(uint256 x) public pure returns (int232) { - return SafeCastLib.toInt232(x); - } - - function toInt240(uint256 x) public pure returns (int240) { - return SafeCastLib.toInt240(x); - } - - function toInt248(uint256 x) public pure returns (int248) { - return SafeCastLib.toInt248(x); - } - - function testSafeCastUintToUint(uint256 x, uint256 r) public { - do { - r = r % 31; - if (r == 0) { - assertEq(SafeCastLib.toUint8(uint8(x)), uint8(x)); - if (x >= 1 << 8) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint8(x); - } else { - assertEq(this.toUint8(x), uint8(x)); - } - } - if (r == 1) { - assertEq(SafeCastLib.toUint16(uint16(x)), uint16(x)); - if (x >= 1 << 16) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint16(x); - } else { - assertEq(this.toUint16(x), uint16(x)); - } - } - if (r == 2) { - assertEq(SafeCastLib.toUint24(uint24(x)), uint24(x)); - if (x >= 1 << 24) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint24(x); - } else { - assertEq(this.toUint24(x), uint24(x)); - } - } - if (r == 3) { - assertEq(SafeCastLib.toUint32(uint32(x)), uint32(x)); - if (x >= 1 << 32) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint32(x); - } else { - assertEq(this.toUint32(x), uint32(x)); - } - } - if (r == 4) { - assertEq(SafeCastLib.toUint40(uint40(x)), uint40(x)); - if (x >= 1 << 40) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint40(x); - } else { - assertEq(this.toUint40(x), uint40(x)); - } - } - if (r == 5) { - assertEq(SafeCastLib.toUint48(uint48(x)), uint48(x)); - if (x >= 1 << 48) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint48(x); - } else { - assertEq(this.toUint48(x), uint48(x)); - } - } - if (r == 6) { - assertEq(SafeCastLib.toUint56(uint56(x)), uint56(x)); - if (x >= 1 << 56) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint56(x); - } else { - assertEq(this.toUint56(x), uint56(x)); - } - } - if (r == 7) { - assertEq(SafeCastLib.toUint64(uint64(x)), uint64(x)); - if (x >= 1 << 64) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint64(x); - } else { - assertEq(this.toUint64(x), uint64(x)); - } - } - if (r == 8) { - assertEq(SafeCastLib.toUint72(uint72(x)), uint72(x)); - if (x >= 1 << 72) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint72(x); - } else { - assertEq(this.toUint72(x), uint72(x)); - } - } - if (r == 9) { - assertEq(SafeCastLib.toUint80(uint80(x)), uint80(x)); - if (x >= 1 << 80) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint80(x); - } else { - assertEq(this.toUint80(x), uint80(x)); - } - } - if (r == 10) { - assertEq(SafeCastLib.toUint88(uint88(x)), uint88(x)); - if (x >= 1 << 88) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint88(x); - } else { - assertEq(this.toUint88(x), uint88(x)); - } - } - if (r == 11) { - assertEq(SafeCastLib.toUint96(uint96(x)), uint96(x)); - if (x >= 1 << 96) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint96(x); - } else { - assertEq(this.toUint96(x), uint96(x)); - } - } - if (r == 12) { - assertEq(SafeCastLib.toUint104(uint104(x)), uint104(x)); - if (x >= 1 << 104) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint104(x); - } else { - assertEq(this.toUint104(x), uint104(x)); - } - } - if (r == 13) { - assertEq(SafeCastLib.toUint112(uint112(x)), uint112(x)); - if (x >= 1 << 112) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint112(x); - } else { - assertEq(this.toUint112(x), uint112(x)); - } - } - if (r == 14) { - assertEq(SafeCastLib.toUint120(uint120(x)), uint120(x)); - if (x >= 1 << 120) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint120(x); - } else { - assertEq(this.toUint120(x), uint120(x)); - } - } - if (r == 15) { - assertEq(SafeCastLib.toUint128(uint128(x)), uint128(x)); - if (x >= 1 << 128) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint128(x); - } else { - assertEq(this.toUint128(x), uint128(x)); - } - } - if (r == 16) { - assertEq(SafeCastLib.toUint136(uint136(x)), uint136(x)); - if (x >= 1 << 136) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint136(x); - } else { - assertEq(this.toUint136(x), uint136(x)); - } - } - if (r == 17) { - assertEq(SafeCastLib.toUint144(uint144(x)), uint144(x)); - if (x >= 1 << 144) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint144(x); - } else { - assertEq(this.toUint144(x), uint144(x)); - } - } - if (r == 18) { - assertEq(SafeCastLib.toUint152(uint152(x)), uint152(x)); - if (x >= 1 << 152) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint152(x); - } else { - assertEq(this.toUint152(x), uint152(x)); - } - } - if (r == 19) { - assertEq(SafeCastLib.toUint160(uint160(x)), uint160(x)); - if (x >= 1 << 160) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint160(x); - } else { - assertEq(this.toUint160(x), uint160(x)); - } - } - if (r == 20) { - assertEq(SafeCastLib.toUint168(uint168(x)), uint168(x)); - if (x >= 1 << 168) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint168(x); - } else { - assertEq(this.toUint168(x), uint168(x)); - } - } - if (r == 21) { - assertEq(SafeCastLib.toUint176(uint176(x)), uint176(x)); - if (x >= 1 << 176) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint176(x); - } else { - assertEq(this.toUint176(x), uint176(x)); - } - } - if (r == 22) { - assertEq(SafeCastLib.toUint184(uint184(x)), uint184(x)); - if (x >= 1 << 184) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint184(x); - } else { - assertEq(this.toUint184(x), uint184(x)); - } - } - if (r == 23) { - assertEq(SafeCastLib.toUint192(uint192(x)), uint192(x)); - if (x >= 1 << 192) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint192(x); - } else { - assertEq(this.toUint192(x), uint192(x)); - } - } - if (r == 24) { - assertEq(SafeCastLib.toUint200(uint200(x)), uint200(x)); - if (x >= 1 << 200) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint200(x); - } else { - assertEq(this.toUint200(x), uint200(x)); - } - } - if (r == 25) { - assertEq(SafeCastLib.toUint208(uint208(x)), uint208(x)); - if (x >= 1 << 208) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint208(x); - } else { - assertEq(this.toUint208(x), uint208(x)); - } - } - if (r == 26) { - assertEq(SafeCastLib.toUint216(uint216(x)), uint216(x)); - if (x >= 1 << 216) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint216(x); - } else { - assertEq(this.toUint216(x), uint216(x)); - } - } - if (r == 27) { - assertEq(SafeCastLib.toUint224(uint224(x)), uint224(x)); - if (x >= 1 << 224) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint224(x); - } else { - assertEq(this.toUint224(x), uint224(x)); - } - } - if (r == 28) { - assertEq(SafeCastLib.toUint232(uint232(x)), uint232(x)); - if (x >= 1 << 232) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint232(x); - } else { - assertEq(this.toUint232(x), uint232(x)); - } - } - if (r == 29) { - assertEq(SafeCastLib.toUint240(uint240(x)), uint240(x)); - if (x >= 1 << 240) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint240(x); - } else { - assertEq(this.toUint240(x), uint240(x)); - } - } - if (r == 30) { - assertEq(SafeCastLib.toUint248(uint248(x)), uint248(x)); - if (x >= 1 << 248) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint248(x); - } else { - assertEq(this.toUint248(x), uint248(x)); - } - } - r = _random(); - x = _random(); - } while (_randomChance(2)); - } - - function testSafeCastUint256ToUintBench() public { - unchecked { - uint256 sum; - for (uint256 i; i != 127; ++i) { - sum += uint256(SafeCastLib.toUint8(i)); - sum += uint256(SafeCastLib.toUint16(i)); - sum += uint256(SafeCastLib.toUint24(i)); - sum += uint256(SafeCastLib.toUint32(i)); - sum += uint256(SafeCastLib.toUint40(i)); - sum += uint256(SafeCastLib.toUint48(i)); - sum += uint256(SafeCastLib.toUint56(i)); - sum += uint256(SafeCastLib.toUint64(i)); - sum += uint256(SafeCastLib.toUint72(i)); - sum += uint256(SafeCastLib.toUint80(i)); - sum += uint256(SafeCastLib.toUint88(i)); - sum += uint256(SafeCastLib.toUint96(i)); - sum += uint256(SafeCastLib.toUint104(i)); - sum += uint256(SafeCastLib.toUint112(i)); - sum += uint256(SafeCastLib.toUint120(i)); - sum += uint256(SafeCastLib.toUint128(i)); - sum += uint256(SafeCastLib.toUint136(i)); - sum += uint256(SafeCastLib.toUint144(i)); - sum += uint256(SafeCastLib.toUint152(i)); - sum += uint256(SafeCastLib.toUint160(i)); - sum += uint256(SafeCastLib.toUint168(i)); - sum += uint256(SafeCastLib.toUint176(i)); - sum += uint256(SafeCastLib.toUint184(i)); - sum += uint256(SafeCastLib.toUint192(i)); - sum += uint256(SafeCastLib.toUint200(i)); - sum += uint256(SafeCastLib.toUint208(i)); - sum += uint256(SafeCastLib.toUint216(i)); - sum += uint256(SafeCastLib.toUint224(i)); - sum += uint256(SafeCastLib.toUint232(i)); - sum += uint256(SafeCastLib.toUint240(i)); - sum += uint256(SafeCastLib.toUint248(i)); - } - assertTrue(sum > 100); - } - } - - function check_SafeCastInt256ToIntTrickEquivalence(int256 x) public pure { - unchecked { - bool expected = x == int32(x); - bool optimized = ((1 << 31) + uint256(x)) >> 32 == uint256(0); - assert(optimized == expected); - } - } - - function testSafeCastInt256ToIntTrickEquivalence(int256 x) public pure { - check_SafeCastInt256ToIntTrickEquivalence(x); - } - - function testSafeCastInt256ToInt(int256 x, uint256 r) public { - do { - r = r % 31; - if (r == 0) { - assertEq(SafeCastLib.toInt8(int8(x)), int8(x)); - if (int8(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt8(x); - } else { - assertEq(this.toInt8(x), int8(x)); - } - } - if (r == 1) { - assertEq(this.toInt16(int16(x)), int16(x)); - if (int16(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt16(x); - } else { - assertEq(this.toInt16(x), int16(x)); - } - } - if (r == 2) { - assertEq(this.toInt24(int24(x)), int24(x)); - if (int24(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt24(x); - } else { - assertEq(this.toInt24(x), int24(x)); - } - } - if (r == 3) { - assertEq(this.toInt32(int32(x)), int32(x)); - if (int32(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt32(x); - } else { - assertEq(this.toInt32(x), int32(x)); - } - } - if (r == 4) { - assertEq(this.toInt40(int40(x)), int40(x)); - if (int40(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt40(x); - } else { - assertEq(this.toInt40(x), int40(x)); - } - } - if (r == 5) { - assertEq(this.toInt48(int48(x)), int48(x)); - if (int48(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt48(x); - } else { - assertEq(this.toInt48(x), int48(x)); - } - } - if (r == 6) { - assertEq(this.toInt56(int56(x)), int56(x)); - if (int56(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt56(x); - } else { - assertEq(this.toInt56(x), int56(x)); - } - } - if (r == 7) { - assertEq(this.toInt64(int64(x)), int64(x)); - if (int64(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt64(x); - } else { - assertEq(this.toInt64(x), int64(x)); - } - } - if (r == 8) { - assertEq(this.toInt72(int72(x)), int72(x)); - if (int72(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt72(x); - } else { - assertEq(this.toInt72(x), int72(x)); - } - } - if (r == 9) { - assertEq(this.toInt80(int80(x)), int80(x)); - if (int80(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt80(x); - } else { - assertEq(this.toInt80(x), int80(x)); - } - } - if (r == 10) { - assertEq(this.toInt88(int88(x)), int88(x)); - if (int88(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt88(x); - } else { - assertEq(this.toInt88(x), int88(x)); - } - } - if (r == 11) { - assertEq(this.toInt96(int96(x)), int96(x)); - if (int96(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt96(x); - } else { - assertEq(this.toInt96(x), int96(x)); - } - } - if (r == 12) { - assertEq(this.toInt104(int104(x)), int104(x)); - if (int104(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt104(x); - } else { - assertEq(this.toInt104(x), int104(x)); - } - } - if (r == 13) { - assertEq(this.toInt112(int112(x)), int112(x)); - if (int112(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt112(x); - } else { - assertEq(this.toInt112(x), int112(x)); - } - } - if (r == 14) { - assertEq(this.toInt120(int120(x)), int120(x)); - if (int120(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt120(x); - } else { - assertEq(this.toInt120(x), int120(x)); - } - } - if (r == 15) { - assertEq(this.toInt128(int128(x)), int128(x)); - if (int128(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt128(x); - } else { - assertEq(this.toInt128(x), int128(x)); - } - } - if (r == 16) { - assertEq(this.toInt136(int136(x)), int136(x)); - if (int136(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt136(x); - } else { - assertEq(this.toInt136(x), int136(x)); - } - } - if (r == 17) { - assertEq(this.toInt144(int144(x)), int144(x)); - if (int144(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt144(x); - } else { - assertEq(this.toInt144(x), int144(x)); - } - } - if (r == 18) { - assertEq(this.toInt152(int152(x)), int152(x)); - if (int152(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt152(x); - } else { - assertEq(this.toInt152(x), int152(x)); - } - } - if (r == 19) { - assertEq(this.toInt160(int160(x)), int160(x)); - if (int160(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt160(x); - } else { - assertEq(this.toInt160(x), int160(x)); - } - } - if (r == 20) { - assertEq(this.toInt168(int168(x)), int168(x)); - if (int168(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt168(x); - } else { - assertEq(this.toInt168(x), int168(x)); - } - } - if (r == 21) { - assertEq(this.toInt176(int176(x)), int176(x)); - if (int176(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt176(x); - } else { - assertEq(this.toInt176(x), int176(x)); - } - } - if (r == 22) { - assertEq(this.toInt184(int184(x)), int184(x)); - if (int184(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt184(x); - } else { - assertEq(this.toInt184(x), int184(x)); - } - } - if (r == 23) { - assertEq(this.toInt192(int192(x)), int192(x)); - if (int192(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt192(x); - } else { - assertEq(this.toInt192(x), int192(x)); - } - } - if (r == 24) { - assertEq(this.toInt200(int200(x)), int200(x)); - if (int200(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt200(x); - } else { - assertEq(this.toInt200(x), int200(x)); - } - } - if (r == 25) { - assertEq(this.toInt208(int208(x)), int208(x)); - if (int208(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt208(x); - } else { - assertEq(this.toInt208(x), int208(x)); - } - } - if (r == 26) { - assertEq(this.toInt216(int216(x)), int216(x)); - if (int216(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt216(x); - } else { - assertEq(this.toInt216(x), int216(x)); - } - } - if (r == 27) { - assertEq(this.toInt224(int224(x)), int224(x)); - if (int224(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt224(x); - } else { - assertEq(this.toInt224(x), int224(x)); - } - } - if (r == 28) { - assertEq(this.toInt232(int232(x)), int232(x)); - if (int232(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt232(x); - } else { - assertEq(this.toInt232(x), int232(x)); - } - } - if (r == 29) { - assertEq(this.toInt240(int240(x)), int240(x)); - if (int240(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt240(x); - } else { - assertEq(this.toInt240(x), int240(x)); - } - } - if (r == 30) { - assertEq(this.toInt248(int248(x)), int248(x)); - if (int248(x) != x) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt248(x); - } else { - assertEq(this.toInt248(x), int248(x)); - } - } - r = _random(); - x = int256(_random()); - } while (_randomChance(2)); - } - - function testSafeCastUint256ToIntBench() public { - unchecked { - int256 sum; - for (uint256 i; i != 127; ++i) { - sum += int256(SafeCastLib.toInt8(i)); - sum += int256(SafeCastLib.toInt16(i)); - sum += int256(SafeCastLib.toInt24(i)); - sum += int256(SafeCastLib.toInt32(i)); - sum += int256(SafeCastLib.toInt40(i)); - sum += int256(SafeCastLib.toInt48(i)); - sum += int256(SafeCastLib.toInt56(i)); - sum += int256(SafeCastLib.toInt64(i)); - sum += int256(SafeCastLib.toInt72(i)); - sum += int256(SafeCastLib.toInt80(i)); - sum += int256(SafeCastLib.toInt88(i)); - sum += int256(SafeCastLib.toInt96(i)); - sum += int256(SafeCastLib.toInt104(i)); - sum += int256(SafeCastLib.toInt112(i)); - sum += int256(SafeCastLib.toInt120(i)); - sum += int256(SafeCastLib.toInt128(i)); - sum += int256(SafeCastLib.toInt136(i)); - sum += int256(SafeCastLib.toInt144(i)); - sum += int256(SafeCastLib.toInt152(i)); - sum += int256(SafeCastLib.toInt160(i)); - sum += int256(SafeCastLib.toInt168(i)); - sum += int256(SafeCastLib.toInt176(i)); - sum += int256(SafeCastLib.toInt184(i)); - sum += int256(SafeCastLib.toInt192(i)); - sum += int256(SafeCastLib.toInt200(i)); - sum += int256(SafeCastLib.toInt208(i)); - sum += int256(SafeCastLib.toInt216(i)); - sum += int256(SafeCastLib.toInt224(i)); - sum += int256(SafeCastLib.toInt232(i)); - sum += int256(SafeCastLib.toInt240(i)); - sum += int256(SafeCastLib.toInt248(i)); - sum += int256(SafeCastLib.toInt256(i)); - } - assertTrue(sum > 100); - } - } - - function testSafeCastUint256ToInt(uint256 x, uint256 r) public { - do { - r = _random() % 31; - if (r == 0) { - assertEq(SafeCastLib.toInt8(int256(int8(int256(x)))), int256(int8(int256(x)))); - if (x >= 1 << 7) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt8(x); - } else { - assertEq(this.toInt8(x), int8(int256(x))); - } - } - if (r == 1) { - assertEq(SafeCastLib.toInt16(int256(int16(int256(x)))), int256(int16(int256(x)))); - if (x >= 1 << 15) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt16(x); - } else { - assertEq(this.toInt16(x), int16(int256(x))); - } - } - if (r == 2) { - assertEq(SafeCastLib.toInt24(int256(int24(int256(x)))), int256(int24(int256(x)))); - if (x >= 1 << 23) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt24(x); - } else { - assertEq(this.toInt24(x), int24(int256(x))); - } - } - if (r == 3) { - assertEq(SafeCastLib.toInt32(int256(int32(int256(x)))), int256(int32(int256(x)))); - if (x >= 1 << 31) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt32(x); - } else { - assertEq(this.toInt32(x), int32(int256(x))); - } - } - if (r == 4) { - assertEq(SafeCastLib.toInt40(int256(int40(int256(x)))), int256(int40(int256(x)))); - if (x >= 1 << 39) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt40(x); - } else { - assertEq(this.toInt40(x), int40(int256(x))); - } - } - if (r == 5) { - assertEq(SafeCastLib.toInt48(int256(int48(int256(x)))), int256(int48(int256(x)))); - if (x >= 1 << 47) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt48(x); - } else { - assertEq(this.toInt48(x), int48(int256(x))); - } - } - if (r == 6) { - assertEq(SafeCastLib.toInt56(int256(int56(int256(x)))), int256(int56(int256(x)))); - if (x >= 1 << 55) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt56(x); - } else { - assertEq(this.toInt56(x), int56(int256(x))); - } - } - if (r == 7) { - assertEq(SafeCastLib.toInt64(int256(int64(int256(x)))), int256(int64(int256(x)))); - if (x >= 1 << 63) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt64(x); - } else { - assertEq(this.toInt64(x), int64(int256(x))); - } - } - if (r == 8) { - assertEq(SafeCastLib.toInt72(int256(int72(int256(x)))), int256(int72(int256(x)))); - if (x >= 1 << 71) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt72(x); - } else { - assertEq(this.toInt72(x), int72(int256(x))); - } - } - if (r == 9) { - assertEq(SafeCastLib.toInt80(int256(int80(int256(x)))), int256(int80(int256(x)))); - if (x >= 1 << 79) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt80(x); - } else { - assertEq(this.toInt80(x), int80(int256(x))); - } - } - if (r == 10) { - assertEq(SafeCastLib.toInt88(int256(int88(int256(x)))), int256(int88(int256(x)))); - if (x >= 1 << 87) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt88(x); - } else { - assertEq(this.toInt88(x), int88(int256(x))); - } - } - if (r == 11) { - assertEq(SafeCastLib.toInt96(int256(int96(int256(x)))), int256(int96(int256(x)))); - if (x >= 1 << 95) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt96(x); - } else { - assertEq(this.toInt96(x), int96(int256(x))); - } - } - if (r == 12) { - assertEq(SafeCastLib.toInt104(int256(int104(int256(x)))), int256(int104(int256(x)))); - if (x >= 1 << 103) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt104(x); - } else { - assertEq(this.toInt104(x), int104(int256(x))); - } - } - if (r == 13) { - assertEq(SafeCastLib.toInt112(int256(int112(int256(x)))), int256(int112(int256(x)))); - if (x >= 1 << 111) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt112(x); - } else { - assertEq(this.toInt112(x), int112(int256(x))); - } - } - if (r == 14) { - assertEq(SafeCastLib.toInt120(int256(int120(int256(x)))), int256(int120(int256(x)))); - if (x >= 1 << 119) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt120(x); - } else { - assertEq(this.toInt120(x), int120(int256(x))); - } - } - if (r == 15) { - assertEq(SafeCastLib.toInt128(int256(int128(int256(x)))), int256(int128(int256(x)))); - if (x >= 1 << 127) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt128(x); - } else { - assertEq(this.toInt128(x), int128(int256(x))); - } - } - if (r == 16) { - assertEq(SafeCastLib.toInt136(int256(int136(int256(x)))), int256(int136(int256(x)))); - if (x >= 1 << 135) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt136(x); - } else { - assertEq(this.toInt136(x), int136(int256(x))); - } - } - if (r == 17) { - assertEq(SafeCastLib.toInt144(int256(int144(int256(x)))), int256(int144(int256(x)))); - if (x >= 1 << 143) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt144(x); - } else { - assertEq(this.toInt144(x), int144(int256(x))); - } - } - if (r == 18) { - assertEq(SafeCastLib.toInt152(int256(int152(int256(x)))), int256(int152(int256(x)))); - if (x >= 1 << 151) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt152(x); - } else { - assertEq(this.toInt152(x), int152(int256(x))); - } - } - if (r == 19) { - assertEq(SafeCastLib.toInt160(int256(int160(int256(x)))), int256(int160(int256(x)))); - if (x >= 1 << 159) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt160(x); - } else { - assertEq(this.toInt160(x), int160(int256(x))); - } - } - if (r == 20) { - assertEq(SafeCastLib.toInt168(int256(int168(int256(x)))), int256(int168(int256(x)))); - if (x >= 1 << 167) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt168(x); - } else { - assertEq(this.toInt168(x), int168(int256(x))); - } - } - if (r == 21) { - assertEq(SafeCastLib.toInt176(int256(int176(int256(x)))), int256(int176(int256(x)))); - if (x >= 1 << 175) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt176(x); - } else { - assertEq(this.toInt176(x), int176(int256(x))); - } - } - if (r == 22) { - assertEq(SafeCastLib.toInt184(int256(int184(int256(x)))), int256(int184(int256(x)))); - if (x >= 1 << 183) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt184(x); - } else { - assertEq(this.toInt184(x), int184(int256(x))); - } - } - if (r == 23) { - assertEq(SafeCastLib.toInt192(int256(int192(int256(x)))), int256(int192(int256(x)))); - if (x >= 1 << 191) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt192(x); - } else { - assertEq(this.toInt192(x), int192(int256(x))); - } - } - if (r == 24) { - assertEq(SafeCastLib.toInt200(int256(int200(int256(x)))), int256(int200(int256(x)))); - if (x >= 1 << 199) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt200(x); - } else { - assertEq(this.toInt200(x), int200(int256(x))); - } - } - if (r == 25) { - assertEq(SafeCastLib.toInt208(int256(int208(int256(x)))), int256(int208(int256(x)))); - if (x >= 1 << 207) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt208(x); - } else { - assertEq(this.toInt208(x), int208(int256(x))); - } - } - if (r == 26) { - assertEq(SafeCastLib.toInt216(int256(int216(int256(x)))), int256(int216(int256(x)))); - if (x >= 1 << 215) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt216(x); - } else { - assertEq(this.toInt216(x), int216(int256(x))); - } - } - if (r == 27) { - assertEq(SafeCastLib.toInt224(int256(int224(int256(x)))), int256(int224(int256(x)))); - if (x >= 1 << 223) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt224(x); - } else { - assertEq(this.toInt224(x), int224(int256(x))); - } - } - if (r == 28) { - assertEq(SafeCastLib.toInt232(int256(int232(int256(x)))), int256(int232(int256(x)))); - if (x >= 1 << 231) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt232(x); - } else { - assertEq(this.toInt232(x), int232(int256(x))); - } - } - if (r == 29) { - assertEq(SafeCastLib.toInt240(int256(int240(int256(x)))), int256(int240(int256(x)))); - if (x >= 1 << 239) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt240(x); - } else { - assertEq(this.toInt240(x), int240(int256(x))); - } - } - if (r == 30) { - assertEq(SafeCastLib.toInt248(int256(int248(int256(x)))), int256(int248(int256(x)))); - if (x >= 1 << 247) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt248(x); - } else { - assertEq(this.toInt248(x), int248(int256(x))); - } - } - r = _random(); - x = _random(); - } while (_randomChance(2)); - } - - function testSafeCastUint256ToInt256Bench() public pure { - unchecked { - for (uint256 i; i != 256; ++i) { - SafeCastLib.toInt256(1 << i - 1); - } - } - } - - function toInt256(uint256 x) public pure returns (int256) { - return SafeCastLib.toInt256(x); - } - - function testSafeCastToInt256(uint256 x) public { - if (x > uint256(type(int256).max)) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toInt256(x); - } else { - assertEq(this.toInt256(x), int256(x)); - } - } - - function toUint256(int256 x) public pure returns (uint256) { - return SafeCastLib.toUint256(x); - } - - function testSafeCastToUint256(int256 x) public { - if (x < 0) { - vm.expectRevert(SafeCastLib.Overflow.selector); - this.toUint256(x); - } else { - assertEq(this.toUint256(x), uint256(x)); - } - } - - function testSafeCastInt256ToIntBench() public { - unchecked { - int256 sum; - for (int256 i; i != 127; ++i) { - sum += int256(SafeCastLib.toInt8(i)); - sum += int256(SafeCastLib.toInt16(i)); - sum += int256(SafeCastLib.toInt24(i)); - sum += int256(SafeCastLib.toInt32(i)); - sum += int256(SafeCastLib.toInt40(i)); - sum += int256(SafeCastLib.toInt48(i)); - sum += int256(SafeCastLib.toInt56(i)); - sum += int256(SafeCastLib.toInt64(i)); - sum += int256(SafeCastLib.toInt72(i)); - sum += int256(SafeCastLib.toInt80(i)); - sum += int256(SafeCastLib.toInt88(i)); - sum += int256(SafeCastLib.toInt96(i)); - sum += int256(SafeCastLib.toInt104(i)); - sum += int256(SafeCastLib.toInt112(i)); - sum += int256(SafeCastLib.toInt120(i)); - sum += int256(SafeCastLib.toInt128(i)); - sum += int256(SafeCastLib.toInt136(i)); - sum += int256(SafeCastLib.toInt144(i)); - sum += int256(SafeCastLib.toInt152(i)); - sum += int256(SafeCastLib.toInt160(i)); - sum += int256(SafeCastLib.toInt168(i)); - sum += int256(SafeCastLib.toInt176(i)); - sum += int256(SafeCastLib.toInt184(i)); - sum += int256(SafeCastLib.toInt192(i)); - sum += int256(SafeCastLib.toInt200(i)); - sum += int256(SafeCastLib.toInt208(i)); - sum += int256(SafeCastLib.toInt216(i)); - sum += int256(SafeCastLib.toInt224(i)); - sum += int256(SafeCastLib.toInt232(i)); - sum += int256(SafeCastLib.toInt240(i)); - sum += int256(SafeCastLib.toInt248(i)); - } - assertTrue(sum > 100); - } - } -} diff --git a/grouperBot/lib/solady/test/SafeTransferLib.t.sol b/grouperBot/lib/solady/test/SafeTransferLib.t.sol deleted file mode 100644 index be55655..0000000 --- a/grouperBot/lib/solady/test/SafeTransferLib.t.sol +++ /dev/null @@ -1,1286 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {MockERC20} from "./utils/mocks/MockERC20.sol"; -import {MockERC20LikeUSDT} from "./utils/mocks/MockERC20LikeUSDT.sol"; -import {MockETHRecipient} from "./utils/mocks/MockETHRecipient.sol"; -import {RevertingToken} from "./utils/weird-tokens/RevertingToken.sol"; -import {ReturnsTwoToken} from "./utils/weird-tokens/ReturnsTwoToken.sol"; -import {ReturnsFalseToken} from "./utils/weird-tokens/ReturnsFalseToken.sol"; -import {MissingReturnToken} from "./utils/weird-tokens/MissingReturnToken.sol"; -import {ReturnsTooMuchToken} from "./utils/weird-tokens/ReturnsTooMuchToken.sol"; -import {ReturnsRawBytesToken} from "./utils/weird-tokens/ReturnsRawBytesToken.sol"; -import {ReturnsTooLittleToken} from "./utils/weird-tokens/ReturnsTooLittleToken.sol"; - -import "./utils/SoladyTest.sol"; - -import {ERC20} from "../src/tokens/ERC20.sol"; -import {SafeTransferLib} from "../src/utils/SafeTransferLib.sol"; - -interface IPermit2 { - struct PermitDetails { - address token; - // By right, this is uint160, but we use uint256 to test the overflow errors. - uint256 amount; - uint48 expiration; - uint48 nonce; - } - - struct PermitSingle { - PermitDetails details; - address spender; - uint256 sigDeadline; - } - - function allowance(address owner, address token, address spender) - external - view - returns (uint160 amount, uint48 expiration, uint48 nonce); -} - -contract SafeTransferLibTest is SoladyTest { - uint256 internal constant _SUCCESS = 1; - uint256 internal constant _REVERTS_WITH_SELECTOR = 2; - uint256 internal constant _REVERTS_WITH_ANY = 3; - - RevertingToken reverting; - ReturnsTwoToken returnsTwo; - ReturnsFalseToken returnsFalse; - MissingReturnToken missingReturn; - ReturnsTooMuchToken returnsTooMuch; - ReturnsRawBytesToken returnsRawBytes; - ReturnsTooLittleToken returnsTooLittle; - - MockERC20 erc20; - - address internal constant _DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; - address internal constant _WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; - address internal constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; - - bytes32 public constant _PERMIT_DETAILS_TYPEHASH = - keccak256("PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)"); - - bytes32 public constant _PERMIT_SINGLE_TYPEHASH = keccak256( - "PermitSingle(PermitDetails details,address spender,uint256 sigDeadline)PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)" - ); - - bytes32 internal constant _DAI_PERMIT_TYPEHASH = keccak256( - "Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)" - ); - bytes32 internal constant _PERMIT_TYPEHASH = keccak256( - "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" - ); - - function setUp() public { - vm.chainId(1); - reverting = new RevertingToken(); - returnsTwo = new ReturnsTwoToken(); - returnsFalse = new ReturnsFalseToken(); - missingReturn = new MissingReturnToken(); - returnsTooMuch = new ReturnsTooMuchToken(); - returnsRawBytes = new ReturnsRawBytesToken(); - returnsTooLittle = new ReturnsTooLittleToken(); - - erc20 = new MockERC20("StandardToken", "ST", 18); - erc20.mint(address(this), type(uint256).max); - - _deployWETH9(); - _deployDAI(); - _deployPermit2(); - } - - function _deployWETH9() internal { - bytes memory bytecode = - hex"6060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029"; - vm.etch(_WETH9, bytecode); - } - - function _deployDAI() internal { - bytes memory bytecode = - hex"608060405234801561001057600080fd5b50600436106101425760003560e01c80637ecebe00116100b8578063a9059cbb1161007c578063a9059cbb146106b4578063b753a98c1461071a578063bb35783b14610768578063bf353dbb146107d6578063dd62ed3e1461082e578063f2d5d56b146108a657610142565b80637ecebe00146104a15780638fcbaf0c146104f957806395d89b411461059f5780639c52a7f1146106225780639dc29fac1461066657610142565b8063313ce5671161010a578063313ce567146102f25780633644e5151461031657806340c10f191461033457806354fd4d501461038257806365fae35e1461040557806370a082311461044957610142565b806306fdde0314610147578063095ea7b3146101ca57806318160ddd1461023057806323b872dd1461024e57806330adf81f146102d4575b600080fd5b61014f6108f4565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561018f578082015181840152602081019050610174565b50505050905090810190601f1680156101bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610216600480360360408110156101e057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061092d565b604051808215151515815260200191505060405180910390f35b610238610a1f565b6040518082815260200191505060405180910390f35b6102ba6004803603606081101561026457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a25565b604051808215151515815260200191505060405180910390f35b6102dc610f3a565b6040518082815260200191505060405180910390f35b6102fa610f61565b604051808260ff1660ff16815260200191505060405180910390f35b61031e610f66565b6040518082815260200191505060405180910390f35b6103806004803603604081101561034a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f6c565b005b61038a611128565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103ca5780820151818401526020810190506103af565b50505050905090810190601f1680156103f75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104476004803603602081101561041b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611161565b005b61048b6004803603602081101561045f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061128f565b6040518082815260200191505060405180910390f35b6104e3600480360360208110156104b757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112a7565b6040518082815260200191505060405180910390f35b61059d600480360361010081101561051057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803515159060200190929190803560ff16906020019092919080359060200190929190803590602001909291905050506112bf565b005b6105a76117fa565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105e75780820151818401526020810190506105cc565b50505050905090810190601f1680156106145780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6106646004803603602081101561063857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611833565b005b6106b26004803603604081101561067c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611961565b005b610700600480360360408110156106ca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611df4565b604051808215151515815260200191505060405180910390f35b6107666004803603604081101561073057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e09565b005b6107d46004803603606081101561077e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e19565b005b610818600480360360208110156107ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e2a565b6040518082815260200191505060405180910390f35b6108906004803603604081101561084457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e42565b6040518082815260200191505060405180910390f35b6108f2600480360360408110156108bc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611e67565b005b6040518060400160405280600e81526020017f44616920537461626c65636f696e00000000000000000000000000000000000081525081565b600081600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60015481565b600081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610adc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f4461692f696e73756666696369656e742d62616c616e6365000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015610bb457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b15610db25781600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610cab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4461692f696e73756666696369656e742d616c6c6f77616e636500000000000081525060200191505060405180910390fd5b610d31600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611e77565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b610dfb600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611e77565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610e87600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611e91565b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b81565b601281565b60055481565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611020576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f6e6f742d617574686f72697a6564000000000000000000000000000081525060200191505060405180910390fd5b611069600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611e91565b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506110b860015482611e91565b6001819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611215576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f6e6f742d617574686f72697a6564000000000000000000000000000081525060200191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505961012081016040526020815260e0602082015260e0600060408301376024356004353360003560e01c60e01b61012085a45050565b60026020528060005260406000206000915090505481565b60046020528060005260406000206000915090505481565b60006005547fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb60001b8a8a8a8a8a604051602001808781526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018215151515815260200196505050505050506040516020818303038152906040528051906020012060405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16141561148c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4461692f696e76616c69642d616464726573732d30000000000000000000000081525060200191505060405180910390fd5b60018185858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114e9573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614611593576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f696e76616c69642d7065726d6974000000000000000000000000000081525060200191505060405180910390fd5b60008614806115a25750854211155b611614576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f7065726d69742d65787069726564000000000000000000000000000081525060200191505060405180910390fd5b600460008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001019190505587146116d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f4461692f696e76616c69642d6e6f6e636500000000000000000000000000000081525060200191505060405180910390fd5b6000856116e4576000611706565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b905080600360008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a350505050505050505050565b6040518060400160405280600381526020017f444149000000000000000000000000000000000000000000000000000000000081525081565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146118e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4461692f6e6f742d617574686f72697a6564000000000000000000000000000081525060200191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505961012081016040526020815260e0602082015260e0600060408301376024356004353360003560e01c60e01b61012085a45050565b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611a16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f4461692f696e73756666696369656e742d62616c616e6365000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611aee57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b15611cec5780600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611be5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4461692f696e73756666696369656e742d616c6c6f77616e636500000000000081525060200191505060405180910390fd5b611c6b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611e77565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b611d35600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611e77565b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611d8460015482611e77565b600181905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000611e01338484610a25565b905092915050565b611e14338383610a25565b505050565b611e24838383610a25565b50505050565b60006020528060005260406000206000915090505481565b6003602052816000526040600020602052806000526040600020600091509150505481565b611e72823383610a25565b505050565b6000828284039150811115611e8b57600080fd5b92915050565b6000828284019150811015611ea557600080fd5b9291505056fea265627a7a72315820c0ae2c29860c0a59d5586a579abbcddfe4bcef0524a87301425cbc58c3e94e3164736f6c634300050c0032"; - vm.etch(_DAI, bytecode); - vm.store(_DAI, bytes32(uint256(5)), SafeTransferLib.DAI_DOMAIN_SEPARATOR); - } - - function _deployPermit2() internal { - bytes memory bytecode = - hex"6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000103611b69577f866a5aba21966af95d6c7ab78eb2b2fc913915c28be3b9aa07cc04ff903e3f2890565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a"; - vm.etch(_PERMIT2, bytecode); - } - - function testSuccessTrick(bool success, uint256 extCodeSize, uint256 returnDataSize) public { - bool expected = success && extCodeSize != 0 && returnDataSize == 0; - bool computed; - /// @solidity memory-safe-assembly - assembly { - computed := lt(or(iszero(extCodeSize), returnDataSize), success) - } - assertEq(computed, expected); - } - - function testTransferWithMissingReturn() public { - verifySafeTransfer(address(missingReturn), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferWithStandardERC20() public { - verifySafeTransfer(address(erc20), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferWithReturnsTooMuch() public { - verifySafeTransfer(address(returnsTooMuch), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.TransferFailed.selector); - this.safeTransfer(address(0xBADBEEF), address(0xBEEF), 1e18); - } - - function testTransferFromWithMissingReturn() public { - verifySafeTransferFrom( - address(missingReturn), address(0xFEED), address(0xBEEF), 1e18, _SUCCESS - ); - } - - function testTransferFromWithStandardERC20() public { - verifySafeTransferFrom(address(erc20), address(0xFEED), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferFromWithReturnsTooMuch() public { - verifySafeTransferFrom( - address(returnsTooMuch), address(0xFEED), address(0xBEEF), 1e18, _SUCCESS - ); - } - - function testTransferFromWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - this.safeTransferFrom(address(0xBADBEEF), address(0xFEED), address(0xBEEF), 1e18); - } - - function safeTransferFrom(address token, address from, address to, uint256 amount) public { - SafeTransferLib.safeTransferFrom( - _brutalized(token), _brutalized(from), _brutalized(to), amount - ); - } - - function testApproveWithMissingReturn() public { - verifySafeApprove(address(missingReturn), address(0xBEEF), 1e18, _SUCCESS); - } - - function testApproveWithStandardERC20() public { - verifySafeApprove(address(erc20), address(0xBEEF), 1e18, _SUCCESS); - } - - function testApproveWithReturnsTooMuch() public { - verifySafeApprove(address(returnsTooMuch), address(0xBEEF), 1e18, _SUCCESS); - } - - function testApproveWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApprove(address(0xBADBEEF), address(0xBEEF), 1e18); - } - - function safeApprove(address token, address to, uint256 amount) public { - SafeTransferLib.safeApprove(token, to, amount); - } - - function testApproveWithRetryWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApproveWithRetry(address(0xBADBEEF), address(0xBEEF), 1e18); - } - - function safeApproveWithRetry(address token, address to, uint256 amount) public { - SafeTransferLib.safeApproveWithRetry(token, to, amount); - } - - function testTransferETH() public { - SafeTransferLib.safeTransferETH(address(0xBEEF), 1e18); - } - - function testTransferAllETH() public { - SafeTransferLib.safeTransferAllETH(address(0xBEEF)); - } - - function testTryTransferETH() public { - MockETHRecipient recipient = new MockETHRecipient(false, false); - bool success = SafeTransferLib.trySafeTransferETH(address(recipient), 1e18, gasleft()); - assertTrue(success); - } - - function testTryTransferAllETH() public { - MockETHRecipient recipient = new MockETHRecipient(false, false); - bool success = SafeTransferLib.trySafeTransferAllETH(address(recipient), gasleft()); - assertTrue(success); - } - - function testTryTransferETHWithNoStorageWrites() public { - MockETHRecipient recipient = new MockETHRecipient(true, false); - - { - bool success = SafeTransferLib.trySafeTransferETH( - address(recipient), 1e18, SafeTransferLib.GAS_STIPEND_NO_STORAGE_WRITES - ); - assertFalse(success); - } - - { - uint256 counterBefore = recipient.counter(); - bool success = SafeTransferLib.trySafeTransferETH( - address(recipient), 1e18, SafeTransferLib.GAS_STIPEND_NO_GRIEF - ); - assertTrue(success); - assertEq(recipient.counter(), counterBefore + 1); - } - - { - uint256 counterBefore = recipient.counter(); - bool success = SafeTransferLib.trySafeTransferETH(address(recipient), 1e18, gasleft()); - assertTrue(success); - assertEq(recipient.counter(), counterBefore + 1); - } - } - - function testTryTransferETHWithNoGrief() public { - MockETHRecipient recipient = new MockETHRecipient(false, true); - - { - bool success = SafeTransferLib.trySafeTransferETH( - address(recipient), 1e18, SafeTransferLib.GAS_STIPEND_NO_STORAGE_WRITES - ); - assertFalse(success); - assertTrue(recipient.garbage() == 0); - } - - { - bool success = SafeTransferLib.trySafeTransferETH( - address(recipient), 1e18, SafeTransferLib.GAS_STIPEND_NO_GRIEF - ); - assertFalse(success); - assertTrue(recipient.garbage() == 0); - } - - { - bool success = SafeTransferLib.trySafeTransferETH(address(recipient), 1e18, gasleft()); - assertTrue(success); - assertTrue(recipient.garbage() != 0); - } - } - - function testForceTransferETHToGriever(uint256 amount, uint256 randomness) public { - amount = amount % 1000 ether; - uint256 originalBalance = address(this).balance; - vm.deal(address(this), amount * 2); - - MockETHRecipient recipient = new MockETHRecipient(false, true); - - { - uint256 recipientBalanceBefore = address(recipient).balance; - uint256 senderBalanceBefore = address(this).balance; - uint256 r = uint256(keccak256(abi.encode(randomness))) % 3; - // Send to a griever with a gas stipend. Should not revert. - if (r == 0) { - this.forceSafeTransferETH( - address(recipient), amount, SafeTransferLib.GAS_STIPEND_NO_STORAGE_WRITES - ); - } else if (r == 1) { - this.forceSafeTransferETH( - address(recipient), amount, SafeTransferLib.GAS_STIPEND_NO_GRIEF - ); - } else { - this.forceSafeTransferETH(address(recipient), amount); - } - assertEq(address(recipient).balance - recipientBalanceBefore, amount); - assertEq(senderBalanceBefore - address(this).balance, amount); - // We use the `SELFDESTRUCT` to send, and thus the `garbage` should NOT be updated. - assertTrue(recipient.garbage() == 0); - } - - { - uint256 recipientBalanceBefore = address(recipient).balance; - uint256 senderBalanceBefore = address(this).balance; - // Send more than remaining balance without gas stipend. Should revert. - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.forceSafeTransferETH(address(recipient), address(this).balance + 1, gasleft()); - assertEq(address(recipient).balance - recipientBalanceBefore, 0); - assertEq(senderBalanceBefore - address(this).balance, 0); - // We did not send anything, and thus the `garbage` should NOT be updated. - assertTrue(recipient.garbage() == 0); - } - - { - uint256 recipientBalanceBefore = address(recipient).balance; - uint256 senderBalanceBefore = address(this).balance; - // Send all the remaining balance without gas stipend. Should not revert. - amount = address(this).balance; - this.forceSafeTransferETH(address(recipient), amount, gasleft()); - assertEq(address(recipient).balance - recipientBalanceBefore, amount); - assertEq(senderBalanceBefore - address(this).balance, amount); - // We use the normal `CALL` to send, and thus the `garbage` should be updated. - assertTrue(recipient.garbage() != 0); - } - - vm.deal(address(this), originalBalance); - } - - function testForceTransferETHToGriever() public { - testForceTransferETHToGriever(1 ether, 0); - testForceTransferETHToGriever(1 ether, 1); - testForceTransferETHToGriever(1 ether, 2); - } - - function testTransferWithReturnsFalseReverts() public { - verifySafeTransfer(address(returnsFalse), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithRevertingReverts() public { - verifySafeTransfer(address(reverting), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithReturnsTooLittleReverts() public { - verifySafeTransfer(address(returnsTooLittle), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithReturnsFalseReverts() public { - verifySafeTransferFrom( - address(returnsFalse), address(0xFEED), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR - ); - } - - function testTransferFromWithRevertingReverts() public { - verifySafeTransferFrom( - address(reverting), address(0xFEED), address(0xBEEF), 1e18, _REVERTS_WITH_ANY - ); - } - - function testTransferFromWithReturnsTooLittleReverts() public { - verifySafeTransferFrom( - address(returnsTooLittle), - address(0xFEED), - address(0xBEEF), - 1e18, - _REVERTS_WITH_SELECTOR - ); - } - - function testApproveWithReturnsFalseReverts() public { - verifySafeApprove(address(returnsFalse), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithRevertingReverts() public { - verifySafeApprove(address(reverting), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithReturnsTooLittleReverts() public { - verifySafeApprove(address(returnsTooLittle), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testBalanceOfStandardERC20() public view { - erc20.balanceOf(address(this)); - } - - function testBalanceOfStandardERC20(address to, uint256 amount) public { - uint256 originalBalance = erc20.balanceOf(address(this)); - while (originalBalance < amount) amount = _random(); - while (to == address(this)) to = _randomHashedAddress(); - - SafeTransferLib.safeTransfer(address(erc20), _brutalized(to), originalBalance - amount); - assertEq(SafeTransferLib.balanceOf(address(erc20), _brutalized(address(this))), amount); - } - - function testCheckBalanceOfNonImplemented() public { - (bool implemented,) = SafeTransferLib.checkBalanceOf(address(0), _brutalized(address(this))); - assertFalse(implemented); - } - - function testCheckBalanceOf(address to, uint256 amount) public { - uint256 originalBalance = erc20.balanceOf(address(this)); - while (originalBalance < amount) amount = _random(); - while (to == address(this)) to = _randomHashedAddress(); - - SafeTransferLib.safeTransfer(address(erc20), _brutalized(to), originalBalance - amount); - (bool implemented, uint256 retrievedAmount) = - SafeTransferLib.checkBalanceOf(address(erc20), _brutalized(address(this))); - assertEq(retrievedAmount, amount); - assertTrue(implemented); - } - - function testTransferAllWithStandardERC20() public { - SafeTransferLib.safeTransferAll(address(erc20), address(1)); - } - - function testTransferAllWithStandardERC20(address to, uint256 amount) public { - uint256 originalBalance = erc20.balanceOf(address(this)); - while (originalBalance < amount) amount = _random(); - while (to == address(this)) to = _randomHashedAddress(); - - SafeTransferLib.safeTransfer(address(erc20), _brutalized(to), originalBalance - amount); - assertEq(erc20.balanceOf(address(this)), amount); - - assertEq(SafeTransferLib.safeTransferAll(address(erc20), _brutalized(to)), amount); - - assertEq(erc20.balanceOf(address(this)), 0); - assertEq(erc20.balanceOf(to), originalBalance); - } - - function testTrySafeTransferFrom(address from, address to, uint256 amount) public { - uint256 balance = _random(); - while (from == address(this) || to == address(this) || from == to) { - from = _randomNonZeroAddress(); - to = _randomNonZeroAddress(); - } - erc20.transfer(from, balance); - vm.prank(from); - erc20.approve(address(this), type(uint256).max); - bool result = SafeTransferLib.trySafeTransferFrom(address(erc20), from, to, amount); - assertEq(result, amount <= balance); - } - - function testTransferAllFromWithStandardERC20() public { - forceApprove(address(erc20), address(this), address(this), type(uint256).max); - SafeTransferLib.safeTransferAllFrom(address(erc20), address(this), address(1)); - } - - function testTransferAllFromWithStandardERC20(address from, address to, uint256 amount) - public - { - while (!(to != from && to != address(this) && from != address(this))) { - to = _randomNonZeroAddress(); - from = _randomNonZeroAddress(); - } - - SafeTransferLib.safeTransferAll(address(erc20), _brutalized(from)); - - uint256 originalBalance = erc20.balanceOf(from); - while (originalBalance < amount) amount = _random(); - - forceApprove(address(erc20), from, address(this), type(uint256).max); - - SafeTransferLib.safeTransferFrom( - address(erc20), _brutalized(from), _brutalized(to), originalBalance - amount - ); - assertEq(erc20.balanceOf(from), amount); - - assertEq( - SafeTransferLib.safeTransferAllFrom(address(erc20), _brutalized(from), _brutalized(to)), - amount - ); - - assertEq(erc20.balanceOf(address(this)), 0); - assertEq(erc20.balanceOf(to), originalBalance); - } - - function testTransferWithMissingReturn(address to, uint256 amount) public { - verifySafeTransfer(address(missingReturn), to, amount, _SUCCESS); - } - - function testTransferWithStandardERC20(address to, uint256 amount) public { - verifySafeTransfer(address(erc20), to, amount, _SUCCESS); - } - - function testTransferWithReturnsTooMuch(address to, uint256 amount) public { - verifySafeTransfer(address(returnsTooMuch), to, amount, _SUCCESS); - } - - function testTransferWithNonGarbage(address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateNonGarbage()); - - verifySafeTransfer(address(returnsRawBytes), to, amount, _SUCCESS); - } - - function testTransferWithNonContractReverts(bytes32, address to, uint256 amount) public { - vm.expectRevert(SafeTransferLib.TransferFailed.selector); - this.safeTransfer(_randomHashedAddress(), to, amount); - } - - function safeTransfer(address token, address to, uint256 amount) public { - SafeTransferLib.safeTransfer(token, to, amount); - } - - function testTransferETHToContractWithoutFallbackReverts() public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferETH(address(this), 1e18); - } - - function testTransferAllETHToContractWithoutFallbackReverts() public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferAllETH(address(this)); - } - - function testTransferFromWithMissingReturn(address from, address to, uint256 amount) public { - verifySafeTransferFrom(address(missingReturn), from, to, amount, _SUCCESS); - } - - function testTransferFromWithStandardERC20(address from, address to, uint256 amount) public { - verifySafeTransferFrom(address(erc20), from, to, amount, _SUCCESS); - } - - function testTransferFromWithReturnsTooMuch(address from, address to, uint256 amount) public { - verifySafeTransferFrom(address(returnsTooMuch), from, to, amount, _SUCCESS); - } - - function testTransferFromWithNonGarbage(address from, address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateNonGarbage()); - - verifySafeTransferFrom(address(returnsRawBytes), from, to, amount, _SUCCESS); - } - - function testTransferFromWithNonContractReverts( - address nonContract, - address from, - address to, - uint256 amount - ) public { - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) { - return; - } - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - this.safeTransferFrom(nonContract, from, to, amount); - } - - function testApproveWithMissingReturn(address to, uint256 amount) public { - if (to == _PERMIT2) return; - verifySafeApprove(address(missingReturn), to, amount, _SUCCESS); - } - - function testApproveWithStandardERC20(address to, uint256 amount) public { - if (to == _PERMIT2) return; - verifySafeApprove(address(erc20), to, amount, _SUCCESS); - } - - function testApproveWithReturnsTooMuch(address to, uint256 amount) public { - if (to == _PERMIT2) return; - verifySafeApprove(address(returnsTooMuch), to, amount, _SUCCESS); - } - - function testApproveWithNonGarbage(address to, uint256 amount) public { - if (to == _PERMIT2) return; - returnsRawBytes.setRawBytes(_generateNonGarbage()); - - verifySafeApprove(address(returnsRawBytes), to, amount, _SUCCESS); - } - - function testApproveWithNonContractReverts(address nonContract, address to, uint256 amount) - public - { - if (to == _PERMIT2) return; - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) { - return; - } - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApprove(nonContract, to, amount); - } - - function testApproveWithRetryWithNonContractReverts( - address nonContract, - address to, - uint256 amount - ) public { - if (to == _PERMIT2) return; - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) { - return; - } - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApproveWithRetry(nonContract, to, amount); - } - - function testApproveWithRetry(address to, uint256 amount0, uint256 amount1) public { - if (to == _PERMIT2) return; - MockERC20LikeUSDT usdt = new MockERC20LikeUSDT(); - assertEq(usdt.allowance(address(this), to), 0); - SafeTransferLib.safeApproveWithRetry(address(usdt), _brutalized(to), amount0); - assertEq(usdt.allowance(address(this), to), amount0); - if (amount0 != 0 && amount1 != 0) { - verifySafeApprove(address(usdt), to, amount1, _REVERTS_WITH_SELECTOR); - } - SafeTransferLib.safeApproveWithRetry(address(usdt), _brutalized(to), amount1); - assertEq(usdt.allowance(address(this), to), amount1); - } - - function testApproveWithRetry() public { - testApproveWithRetry(address(1), 123, 456); - } - - function testTransferETH(bytes32, uint256 amount) public { - amount = _bound(amount, 0, address(this).balance); - SafeTransferLib.safeTransferETH(_randomHashedAddress(), amount); - } - - function testTransferAllETH(bytes32) public { - SafeTransferLib.safeTransferAllETH(_randomHashedAddress()); - } - - function testTransferWithReturnsFalseReverts(address to, uint256 amount) public { - verifySafeTransfer(address(returnsFalse), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithRevertingReverts(address to, uint256 amount) public { - verifySafeTransfer(address(reverting), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithReturnsTooLittleReverts(address to, uint256 amount) public { - verifySafeTransfer(address(returnsTooLittle), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithReturnsTwoReverts(address to, uint256 amount) public { - verifySafeTransfer(address(returnsTwo), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithGarbageReverts(address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateGarbage()); - - verifySafeTransfer(address(returnsRawBytes), to, amount, _REVERTS_WITH_ANY); - } - - function testTransferFromWithReturnsFalseReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(returnsFalse), from, to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithRevertingReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(reverting), from, to, amount, _REVERTS_WITH_ANY); - } - - function testTransferFromWithReturnsTooLittleReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(returnsTooLittle), from, to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithReturnsTwoReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(returnsTwo), from, to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithGarbageReverts(address from, address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateGarbage()); - - verifySafeTransferFrom(address(returnsRawBytes), from, to, amount, _REVERTS_WITH_ANY); - } - - function testApproveWithReturnsFalseReverts(address to, uint256 amount) public { - verifySafeApprove(address(returnsFalse), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithRevertingReverts(address to, uint256 amount) public { - verifySafeApprove(address(reverting), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithReturnsTooLittleReverts(address to, uint256 amount) public { - verifySafeApprove(address(returnsTooLittle), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithReturnsTwoReverts(address to, uint256 amount) public { - verifySafeApprove(address(returnsTwo), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithGarbageReverts(address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateGarbage()); - - verifySafeApprove(address(returnsRawBytes), to, amount, _REVERTS_WITH_ANY); - } - - function testTransferETHToContractWithoutFallbackReverts(uint256 amount) public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferETH(address(this), amount); - } - - function testTransferAllETHToContractWithoutFallbackReverts(uint256) public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferAllETH(address(this)); - } - - function verifySafeTransfer(address token, address to, uint256 amount, uint256 mode) public { - if (mode == _REVERTS_WITH_SELECTOR) { - vm.expectRevert(SafeTransferLib.TransferFailed.selector); - } else if (mode == _REVERTS_WITH_ANY) { - (bool success,) = address(this).call( - abi.encodeWithSignature( - "verifySafeTransfer(address,address,uint256)", token, to, amount - ) - ); - assertFalse(success); - return; - } - this.verifySafeTransfer(token, to, amount); - } - - function verifySafeTransfer(address token, address to, uint256 amount) public brutalizeMemory { - uint256 preBal = ERC20(token).balanceOf(to); - if (amount == ERC20(token).balanceOf(address(this)) && _randomChance(2)) { - SafeTransferLib.safeTransferAll(address(token), _brutalized(to)); - } else { - SafeTransferLib.safeTransfer(address(token), _brutalized(to), amount); - } - - uint256 postBal = ERC20(token).balanceOf(to); - - if (to == address(this)) { - assertEq(preBal, postBal); - } else { - assertEq(postBal - preBal, amount); - } - } - - function verifySafeTransferFrom( - address token, - address from, - address to, - uint256 amount, - uint256 mode - ) public { - if (mode == _REVERTS_WITH_SELECTOR) { - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - } else if (mode == _REVERTS_WITH_ANY) { - (bool success,) = address(this).call( - abi.encodeWithSignature( - "verifySafeTransferFrom(address,address,address,uint256)", - token, - from, - to, - amount - ) - ); - assertFalse(success); - return; - } - this.verifySafeTransferFrom(token, from, to, amount); - } - - function verifySafeTransferFrom(address token, address from, address to, uint256 amount) - public - brutalizeMemory - { - forceApprove(token, from, address(this), amount); - - // We cast to MissingReturnToken here because it won't check - // that there was return data, which accommodates all tokens. - MissingReturnToken(token).transfer(from, amount); - - uint256 preBal = ERC20(token).balanceOf(to); - if (amount == ERC20(token).balanceOf(from) && _randomChance(2)) { - SafeTransferLib.safeTransferAllFrom(address(token), _brutalized(from), _brutalized(to)); - } else { - SafeTransferLib.safeTransferFrom(token, _brutalized(from), _brutalized(to), amount); - } - uint256 postBal = ERC20(token).balanceOf(to); - - if (from == to) { - assertEq(preBal, postBal); - } else { - assertEq(postBal - preBal, amount); - } - } - - function verifySafeApprove(address token, address to, uint256 amount, uint256 mode) public { - if (mode == _REVERTS_WITH_SELECTOR) { - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - } else if (mode == _REVERTS_WITH_ANY) { - (bool success,) = address(this).call( - abi.encodeWithSignature( - "verifySafeApprove(address,address,uint256)", token, to, amount - ) - ); - assertFalse(success); - return; - } - this.verifySafeApprove(token, to, amount); - } - - function verifySafeApprove(address token, address to, uint256 amount) public { - SafeTransferLib.safeApprove(_brutalized(address(token)), _brutalized(to), amount); - - assertEq(ERC20(token).allowance(address(this), to), amount); - } - - function forceApprove(address token, address from, address to, uint256 amount) public { - if (token == address(erc20)) { - bytes32 allowanceSlot; - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, to) - mstore(0x0c, 0x7f5e9f20) // `_ALLOWANCE_SLOT_SEED`. - mstore(0x00, from) - allowanceSlot := keccak256(0x0c, 0x34) - } - vm.store(token, allowanceSlot, bytes32(uint256(amount))); - } else { - vm.store( - token, - keccak256(abi.encode(to, keccak256(abi.encode(from, uint256(2))))), - bytes32(uint256(amount)) - ); - } - - assertEq(ERC20(token).allowance(from, to), amount, "wrong allowance"); - } - - function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) public { - SafeTransferLib.forceSafeTransferETH(to, amount, gasStipend); - } - - function forceSafeTransferETH(address to, uint256 amount) public { - SafeTransferLib.forceSafeTransferETH(to, amount); - } - - function safeTransferETH(address to, uint256 amount) public { - SafeTransferLib.safeTransferETH(to, amount); - } - - function safeTransferAllETH(address to) public { - SafeTransferLib.safeTransferAllETH(to); - } - - function _generateGarbage() internal returns (bytes memory result) { - uint256 r = _random(); - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - mstore(0x00, r) - result := mload(0x40) - let n := and(r, 0x7f) - mstore(result, n) - r := keccak256(0x00, 0x40) - mstore(add(result, 0x20), r) - mstore(0x40, add(result, 0x100)) - if and(or(lt(n, 0x20), iszero(eq(r, 1))), gt(n, 0)) { break } - } - } - } - - function _generateNonGarbage() internal returns (bytes memory result) { - uint256 r = _random(); - /// @solidity memory-safe-assembly - assembly { - if iszero(and(r, 1)) { - result := mload(0x40) - mstore(result, 0x20) - mstore(add(result, 0x20), 1) - mstore(0x40, add(result, 0x40)) - } - } - } - - struct _TestTemps { - address signer; - uint256 privateKey; - uint8 v; - bytes32 r; - bytes32 s; - uint256 amount; - address from; - address spender; - address to; - uint256 nonce; - bytes32 hash; - address token; - uint256 deadline; - uint48 expiration; - uint256 retrievedAmount; - uint256 retrievedExpiration; - IPermit2.PermitSingle permit; - } - - function testPermit2() public { - _TestTemps memory t; - t.token = address(erc20); - t.deadline = block.timestamp; - (t.signer, t.privateKey) = _randomSigner(); - t.spender = _randomNonZeroAddress(); - t.amount = _bound(_random(), 0, type(uint160).max); - t.nonce = erc20.nonces(t.signer); - t.hash = keccak256( - abi.encode(_PERMIT_TYPEHASH, t.signer, t.spender, t.amount, t.nonce, t.deadline) - ); - t.hash = keccak256(abi.encodePacked("\x19\x01", erc20.DOMAIN_SEPARATOR(), t.hash)); - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.hash); - this.permit2(t); - } - - function testPermit2OnDAI() public { - _TestTemps memory t; - t.token = _DAI; - t.deadline = block.timestamp; - (t.signer, t.privateKey) = _randomSigner(); - t.spender = _randomNonZeroAddress(); - t.amount = _bound(_random(), 1, type(uint160).max); - t.nonce = ERC20(_DAI).nonces(t.signer); - t.hash = keccak256( - abi.encode(_DAI_PERMIT_TYPEHASH, t.signer, t.spender, t.nonce, t.deadline, true) - ); - t.hash = - keccak256(abi.encodePacked("\x19\x01", SafeTransferLib.DAI_DOMAIN_SEPARATOR, t.hash)); - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.hash); - this.permit2(t); - - t.amount = 0; - t.nonce = ERC20(_DAI).nonces(t.signer); - t.hash = keccak256( - abi.encode(_DAI_PERMIT_TYPEHASH, t.signer, t.spender, t.nonce, t.deadline, false) - ); - t.hash = - keccak256(abi.encodePacked("\x19\x01", SafeTransferLib.DAI_DOMAIN_SEPARATOR, t.hash)); - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.hash); - this.permit2(t); - - t.hash = keccak256( - abi.encode(_DAI_PERMIT_TYPEHASH, t.signer, t.spender, t.nonce, t.deadline, true) - ); - t.hash = - keccak256(abi.encodePacked("\x19\x01", SafeTransferLib.DAI_DOMAIN_SEPARATOR, t.hash)); - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.hash); - vm.expectRevert(SafeTransferLib.Permit2Failed.selector); - this.permit2(t); - } - - function testSimplePermit2AndPermit2TransferFrom() public { - for (uint256 t; t < 10; ++t) { - _testSimplePermit2AndPermit2TransferFrom(); - } - } - - function _testSimplePermit2AndPermit2TransferFrom() internal { - _TestTemps memory t; - t.token = address(erc20); - t.deadline = block.timestamp; - (t.signer, t.privateKey) = _randomSigner(); - t.spender = _randomNonZeroAddress(); - t.amount = _bound(_random(), 0, type(uint160).max); - erc20.transfer(t.signer, t.amount); - - vm.prank(t.signer); - erc20.approve(_PERMIT2, type(uint256).max); - - t.permit.details.token = address(erc20); - t.permit.details.amount = t.amount; - t.permit.details.expiration = type(uint48).max; - (,, t.permit.details.nonce) = - IPermit2(_PERMIT2).allowance(t.signer, address(erc20), t.spender); - t.permit.spender = t.spender; - t.permit.sigDeadline = t.deadline; - - _generatePermitSignatureRaw(t); - this.simplePermit2(t); - t.to = _randomNonZeroAddress(); - - uint256 balanceBefore = erc20.balanceOf(t.to); - vm.startPrank(t.spender); - if (_randomChance(2)) { - SafeTransferLib.permit2TransferFrom(address(erc20), t.signer, t.to, t.amount); - } else { - SafeTransferLib.safeTransferFrom2(address(erc20), t.signer, t.to, t.amount); - } - vm.stopPrank(); - if (t.signer != t.to) { - assertEq(erc20.balanceOf(t.to), balanceBefore + t.amount); - } - } - - function testSimplePermit2AndPermit2TransferFromGas() public { - _TestTemps memory t; - t.token = address(erc20); - t.deadline = block.timestamp; - (t.signer, t.privateKey) = _randomSigner(); - t.spender = _randomNonZeroAddress(); - t.amount = type(uint160).max; - erc20.transfer(t.signer, t.amount); - - vm.prank(t.signer); - erc20.approve(_PERMIT2, type(uint256).max); - - t.permit.details.token = address(erc20); - t.permit.details.amount = uint160(t.amount); - t.permit.details.expiration = type(uint48).max; - (,, t.permit.details.nonce) = - IPermit2(_PERMIT2).allowance(t.signer, address(erc20), t.spender); - t.permit.spender = t.spender; - t.permit.sigDeadline = t.deadline; - - _generatePermitSignatureRaw(t); - this.simplePermit2(t); - t.to = _randomNonZeroAddress(); - - vm.startPrank(t.spender); - SafeTransferLib.permit2TransferFrom(address(erc20), t.signer, t.to, t.amount); - vm.stopPrank(); - } - - function testPermit2AnythingWithNonContractReverts() public { - _TestTemps memory t; - t.token = _randomHashedAddress(); - t.deadline = block.timestamp; - (t.signer, t.privateKey) = _randomSigner(); - t.spender = _randomNonZeroAddress(); - t.amount = type(uint160).max; - - t.permit.details.token = address(t.token); - t.permit.details.amount = uint160(t.amount); - t.permit.details.expiration = type(uint48).max; - (,, t.permit.details.nonce) = - IPermit2(_PERMIT2).allowance(t.signer, address(t.token), t.spender); - t.permit.spender = t.spender; - t.permit.sigDeadline = t.deadline; - - _generatePermitSignatureRaw(t); - vm.expectRevert(SafeTransferLib.Permit2Failed.selector); - this.simplePermit2(t); - vm.expectRevert(SafeTransferLib.Permit2Failed.selector); - this.permit2(t); - t.to = _randomNonZeroAddress(); - - vm.startPrank(t.spender); - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - this.permit2TransferFrom(address(t.token), t.signer, t.to, t.amount); - vm.stopPrank(); - } - - function testPermit2TransferFromInvalidAmount(uint256) public { - _TestTemps memory t; - t.token = address(erc20); - t.deadline = block.timestamp; - (t.signer, t.privateKey) = _randomSigner(); - t.spender = _randomNonZeroAddress(); - t.amount = _bound(_random(), 0, type(uint160).max); - erc20.transfer(t.signer, t.amount); - - vm.prank(t.signer); - erc20.approve(_PERMIT2, type(uint256).max); - - t.permit.details.token = address(erc20); - t.permit.details.amount = uint160(t.amount); - t.permit.details.expiration = type(uint48).max; - (,, t.permit.details.nonce) = - IPermit2(_PERMIT2).allowance(t.signer, address(erc20), t.spender); - t.permit.spender = t.spender; - t.permit.sigDeadline = t.deadline; - - _generatePermitSignatureRaw(t); - this.simplePermit2(t); - t.to = _randomNonZeroAddress(); - - uint256 overflowedAmount = _bound(_random(), 2 ** 160, type(uint256).max); - vm.expectRevert(SafeTransferLib.Permit2AmountOverflow.selector); - this.permit2TransferFrom(address(erc20), t.signer, t.to, overflowedAmount); - } - - function testPermit2InvalidAmount(uint256) public { - _TestTemps memory t; - t.token = address(erc20); - t.deadline = block.timestamp; - (t.signer, t.privateKey) = _randomSigner(); - t.spender = _randomNonZeroAddress(); - t.amount = _bound(_random(), 2 ** 160, type(uint256).max); - erc20.transfer(t.signer, t.amount); - - vm.prank(t.signer); - erc20.approve(_PERMIT2, type(uint256).max); - - t.permit.details.token = address(erc20); - t.permit.details.amount = t.amount; - t.permit.details.expiration = type(uint48).max; - (,, t.permit.details.nonce) = - IPermit2(_PERMIT2).allowance(t.signer, address(erc20), t.spender); - t.permit.spender = t.spender; - t.permit.sigDeadline = t.deadline; - - _generatePermitSignatureRaw(t); - vm.expectRevert(SafeTransferLib.Permit2AmountOverflow.selector); - this.simplePermit2(t); - } - - function testPermit2ApproveAndLockdown(bytes32) public { - _TestTemps memory t; - t.token = _randomHashedAddress(); - t.spender = _randomHashedAddress(); - t.amount = _bound(_random(), 0, type(uint160).max); - (t.retrievedAmount, t.retrievedExpiration,) = - IPermit2(_PERMIT2).allowance(address(this), t.token, t.spender); - assertEq(t.retrievedAmount, 0); - assertEq(t.retrievedExpiration, 0); - - t.expiration = uint48(_bound(t.expiration, block.timestamp, type(uint48).max)); - - SafeTransferLib.permit2Approve(t.token, t.spender, uint160(t.amount), t.expiration); - - (t.retrievedAmount, t.retrievedExpiration,) = - IPermit2(_PERMIT2).allowance(address(this), t.token, t.spender); - assertEq(t.retrievedAmount, t.amount); - assertEq(t.retrievedExpiration, t.expiration); - - SafeTransferLib.permit2Lockdown(t.token, t.spender); - - (t.retrievedAmount, t.retrievedExpiration,) = - IPermit2(_PERMIT2).allowance(address(this), t.token, t.spender); - assertEq(t.retrievedAmount, 0); - assertEq(t.retrievedExpiration, t.expiration); // Expiration stays the same. - } - - function _generatePermitSignatureRaw(_TestTemps memory t) internal view { - bytes32 domainSeparator = ERC20(_PERMIT2).DOMAIN_SEPARATOR(); - t.hash = keccak256(abi.encode(_PERMIT_DETAILS_TYPEHASH, t.permit.details)); - t.hash = keccak256( - abi.encode(_PERMIT_SINGLE_TYPEHASH, t.hash, t.permit.spender, t.permit.sigDeadline) - ); - t.hash = keccak256(abi.encodePacked("\x19\x01", domainSeparator, t.hash)); - (t.v, t.r, t.s) = vm.sign(t.privateKey, t.hash); - } - - function permit2TransferFrom(address token, address from, address to, uint256 amount) public { - SafeTransferLib.permit2TransferFrom( - _brutalized(token), _brutalized(from), _brutalized(to), amount - ); - } - - function safeTransferFrom2(address token, address from, address to, uint256 amount) public { - SafeTransferLib.safeTransferFrom2( - _brutalized(token), _brutalized(from), _brutalized(to), amount - ); - } - - function permit2(_TestTemps calldata t) public { - SafeTransferLib.permit2( - _brutalized(t.token), - _brutalized(t.signer), - _brutalized(t.spender), - t.amount, - t.deadline, - t.v, - t.r, - t.s - ); - } - - function simplePermit2(_TestTemps calldata t) public { - SafeTransferLib.simplePermit2( - _brutalized(t.token), - _brutalized(t.signer), - _brutalized(t.spender), - t.amount, - t.deadline, - t.v, - t.r, - t.s - ); - } - - function testTotalSupplyQuery() public { - uint256 totalSupplyBefore = this.totalSupplyQuery(address(erc20)); - erc20.burn(address(this), 123); - assertEq(this.totalSupplyQuery(address(erc20)), totalSupplyBefore - 123); - vm.expectRevert(SafeTransferLib.TotalSupplyQueryFailed.selector); - this.totalSupplyQuery(address(0)); - } - - function totalSupplyQuery(address token) public view returns (uint256) { - return SafeTransferLib.totalSupply(token); - } - - function testSaveMoveETHViaVault(bytes32) public { - address to = _randomUniqueHashedAddress(); - assertEq(to.balance, 0); - - uint256 amount0 = _bound(_random(), 0, 2 ** 128 - 1); - uint256 amount1 = _bound(_random(), 0, 2 ** 128 - 1); - vm.deal(address(this), 2 ** 160 - 1); - address vault = this.safeMoveETH(to, amount0); - assertEq(vault.balance, amount0); - assertEq(this.safeMoveETH(to, amount1), vault); - assertEq(vault.balance, amount0 + amount1); - - address pranker = _randomUniqueHashedAddress(); - vm.prank(pranker); - (bool success,) = vault.call(""); - require(success); - assertEq(vault.balance, amount0 + amount1); - assertEq(to.balance, 0); - - vm.prank(to); - (success,) = vault.call(""); - require(success); - assertEq(vault.balance, 0); - assertEq(to.balance, amount0 + amount1); - } - - function testSafeMoveETHViaMover(bytes32) public { - _deployETHMover(); - - address to = _randomHashedAddress(); - assertEq(to.balance, 0); - - uint256 amount0 = _bound(_random(), 0, 2 ** 128 - 1); - uint256 amount1 = _bound(_random(), 0, 2 ** 128 - 1); - vm.deal(address(this), 2 ** 160 - 1); - uint256 selfBalanceBefore = address(this).balance; - assertEq(SafeTransferLib.safeMoveETH(to, amount0), address(0)); - - assertEq(to.balance, amount0); - assertEq(address(this).balance, selfBalanceBefore - amount0); - - if (_randomChance(2)) { - vm.etch(SafeTransferLib.ETH_MOVER, ""); - } - - if (SafeTransferLib.ETH_MOVER.code.length == 0) { - address vault = this.safeMoveETH(to, amount1); - assertEq(vault.balance, amount1); - assertEq(to.balance, amount0); - assertEq(address(this).balance, selfBalanceBefore - amount0 - amount1); - } else { - assertEq(this.safeMoveETH(to, amount1), address(0)); - assertEq(to.balance, amount0 + amount1); - assertEq(address(this).balance, selfBalanceBefore - amount0 - amount1); - } - } - - function testSaveMoveETHToSelfIsNoOp(bytes32) public { - if (_randomChance(2)) _deployETHMover(); - address to = address(this); - uint256 amount = _bound(_random(), 0, 2 ** 128 - 1); - vm.deal(address(this), 2 ** 160 - 1); - uint256 selfBalanceBefore = address(this).balance; - assertEq(this.safeMoveETH(to, amount), address(0)); - assertEq(address(this).balance, selfBalanceBefore); - } - - function testSaveMoveETHToMoverReverts(bytes32) public { - if (_randomChance(2)) _deployETHMover(); - address to = SafeTransferLib.ETH_MOVER; - - uint256 amount = _bound(_random(), 0, 2 ** 128 - 1); - vm.deal(address(this), 2 ** 160 - 1); - - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeMoveETH(to, amount); - } - - function testSaveMoveETHInsufficientBalanceReverts(bytes32) public { - if (_randomChance(2)) _deployETHMover(); - address to = _randomHashedAddress(); - - uint256 amount = _bound(_random(), 0, 2 ** 128 - 1); - vm.deal(address(this), 2 ** 128 - 1); - - if (address(this).balance < amount) { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeMoveETH(to, amount); - } else { - this.safeMoveETH(to, amount); - } - } - - function safeMoveETH(address to, uint256 amount) public returns (address) { - if (_randomChance(2)) _misalignFreeMemoryPointer(); - if (_randomChance(2)) _brutalizeMemory(); - return SafeTransferLib.safeMoveETH(_brutalized(to), amount); - } - - function _deployETHMover() internal { - bytes memory initCode = hex"623d35ff3d526003601df3"; - bytes32 salt = 0x000000000000000000000000000000000000000063d76c4f57ebf10084429e18; - address mover = _nicksCreate2(0, salt, initCode); - assertEq(mover.code, hex"3d35ff"); - assertEq(mover, SafeTransferLib.ETH_MOVER); - } -} diff --git a/grouperBot/lib/solady/test/SemVerLib.t.sol b/grouperBot/lib/solady/test/SemVerLib.t.sol deleted file mode 100644 index 8baeb6e..0000000 --- a/grouperBot/lib/solady/test/SemVerLib.t.sol +++ /dev/null @@ -1,270 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {SemVerLib} from "../src/utils/SemVerLib.sol"; -import {LibString} from "../src/utils/LibString.sol"; - -contract SemVerLibTest is SoladyTest { - function _checkEq(bytes32 a, bytes32 b) public { - assertEq(SemVerLib.cmp(a, b), 0); - assertEq(SemVerLib.cmp(_addMeta(a), b), 0); - assertEq(SemVerLib.cmp(a, _addMeta(b)), 0); - assertEq(SemVerLib.cmp(_addMeta(a), _addMeta(b)), 0); - } - - function _checkLt(bytes32 a, bytes32 b) public { - assertEq(SemVerLib.cmp(a, b), -1); - assertEq(SemVerLib.cmp(_addMeta(a), b), -1); - assertEq(SemVerLib.cmp(a, _addMeta(b)), -1); - assertEq(SemVerLib.cmp(_addMeta(a), _addMeta(b)), -1); - (a, b) = (b, a); - assertEq(SemVerLib.cmp(a, b), 1); - assertEq(SemVerLib.cmp(_addMeta(a), b), 1); - assertEq(SemVerLib.cmp(a, _addMeta(b)), 1); - assertEq(SemVerLib.cmp(_addMeta(a), _addMeta(b)), 1); - } - - function _addMeta(bytes32 a) internal returns (bytes32) { - bytes memory data = bytes(LibString.fromSmallString(a)); - if (data.length >= 20) return a; - data = abi.encodePacked(data, "+"); - if (_randomChance(2)) { - data = abi.encodePacked( - data, _truncateBytes(abi.encodePacked(_random()), _randomUniform() % 5) - ); - } - return LibString.toSmallString(string(data)); - } - - function _s(uint256 x) internal pure returns (bytes memory) { - return bytes(LibString.toString(x)); - } - - function _s(bytes memory x) internal pure returns (bytes32) { - return LibString.toSmallString(string(x)); - } - - function _s(bytes32 x) internal pure returns (bytes memory) { - return bytes(LibString.fromSmallString(x)); - } - - function _s(uint256[] memory x) internal pure returns (bytes32) { - bytes memory buffer; - for (uint256 i; i < x.length; ++i) { - if (i != 0) { - buffer = abi.encodePacked(buffer, ".", _s(x[i])); - } else { - buffer = abi.encodePacked(buffer, _s(x[i])); - } - } - return _s(buffer); - } - - function _maybePrependV(bytes32 x) internal returns (bytes32) { - if (_randomChance(2)) return x; - if (_randomChance(2)) return _s(abi.encodePacked("v", _s(x))); - return _s(abi.encodePacked("V", _s(x))); - } - - function testCmpMajorMinorPatch(bytes32) public { - uint256 n = _bound(_randomUniform(), 0, 5); - uint256[] memory a = new uint256[](n); - uint256[] memory b = new uint256[](n); - for (uint256 i; i < n; ++i) { - a[i] = _bound(_random(), 0, 10000); - b[i] = _bound(_random(), 0, 10000); - } - int256 expected = _cmpMajorMinorPatchOriginal(a, b); - if (expected == 0) { - _checkEq(_maybePrependV(_s(a)), _maybePrependV(_s(b))); - } else if (expected == 1) { - _checkLt(_maybePrependV(_s(b)), _maybePrependV(_s(a))); - } else if (expected == -1) { - _checkLt(_maybePrependV(_s(a)), _maybePrependV(_s(b))); - } else { - revert("Should never reach here."); - } - } - - function _cmpMajorMinorPatchOriginal(uint256[] memory a, uint256[] memory b) - internal - pure - returns (int256) - { - require(a.length == b.length, "Input arrays must have same lengths."); - for (uint256 i; i < a.length; ++i) { - if (a[i] > b[i]) return 1; - if (a[i] < b[i]) return -1; - } - return 0; - } - - struct _CmpPreReleaseTemps { - uint256 n; - uint256[] a; - uint256[] b; - bool aIsNum; - bool bIsNum; - uint256 aNum; - uint256 bNum; - bytes aBuffer; - bytes bBuffer; - bytes aPreReleaseBuffer; - bytes bPreReleaseBuffer; - int256 lexoCmpResult; - } - - function testCmpPreRelease(bytes32) public { - _CmpPreReleaseTemps memory t; - t.n = _bound(_randomUniform(), 1, 3); - t.a = new uint256[](t.n); - t.b = new uint256[](t.n); - for (uint256 i; i < t.n; ++i) { - t.a[i] = _bound(_random(), 0, 200); - t.b[i] = t.a[i]; - } - t.aBuffer = _s(_maybePrependV(_s(t.a))); - t.bBuffer = _s(_maybePrependV(_s(t.b))); - t.aIsNum = _randomChance(2); - t.bIsNum = _randomChance(2); - - if (t.aIsNum) { - t.aNum = _random() % (10 ** (32 - 1 - t.aBuffer.length)); - t.aBuffer = abi.encodePacked(t.aBuffer, "-", _s(t.aNum)); - } else { - t.aNum = _random() % (10 ** (32 - 2 - t.aBuffer.length)); - t.aPreReleaseBuffer = abi.encodePacked(_s(t.aNum), "h"); - t.aBuffer = abi.encodePacked(t.aBuffer, "-", t.aPreReleaseBuffer); - } - - if (t.bIsNum) { - t.bNum = _random() % (10 ** (32 - 1 - t.bBuffer.length)); - t.bBuffer = abi.encodePacked(t.bBuffer, "-", _s(t.bNum)); - } else { - t.bNum = _random() % (10 ** (32 - 2 - t.bBuffer.length)); - t.bPreReleaseBuffer = abi.encodePacked(_s(t.bNum), "h"); - t.bBuffer = abi.encodePacked(t.bBuffer, "-", t.bPreReleaseBuffer); - } - - if (t.aIsNum && t.bIsNum) { - if (t.aNum < t.bNum) { - _checkLt(_s(t.aBuffer), _s(t.bBuffer)); - } else if (t.aNum > t.bNum) { - _checkLt(_s(t.bBuffer), _s(t.aBuffer)); - } else { - _checkEq(_s(t.aBuffer), _s(t.bBuffer)); - } - } else if (t.aIsNum && !t.bIsNum) { - _checkLt(_s(t.aBuffer), _s(t.bBuffer)); - } else if (!t.aIsNum && t.bIsNum) { - _checkLt(_s(t.bBuffer), _s(t.aBuffer)); - } else if (!t.aIsNum && !t.bIsNum) { - t.lexoCmpResult = _lexoCmp(t.aPreReleaseBuffer, t.bPreReleaseBuffer); - if (t.lexoCmpResult == -1) { - _checkLt(_s(t.aBuffer), _s(t.bBuffer)); - } else if (t.lexoCmpResult == 1) { - _checkLt(_s(t.bBuffer), _s(t.aBuffer)); - } else { - _checkEq(_s(t.aBuffer), _s(t.bBuffer)); - } - } - } - - function _lexoCmp(bytes memory a, bytes memory b) internal pure returns (int256) { - unchecked { - uint256 len = a.length < b.length ? a.length : b.length; - for (uint256 i; i < len; ++i) { - uint8 ac = uint8(a[i]); - uint8 bc = uint8(b[i]); - if (ac < bc) return -1; - if (ac > bc) return 1; - } - if (a.length < b.length) return -1; - if (a.length > b.length) return 1; - return 0; - } - } - - function testCmpCompliant() public { - this._checkEq("1.0.0", "1.0.0"); - this._checkLt("1.0.0", "1.0.1"); - this._checkLt("1.0.0", "1.1.0"); - this._checkLt("1.0.0", "1.1.1"); - this._checkLt("1.0.0", "2.0.1"); - this._checkLt("1.0.0", "2.1.0"); - this._checkLt("1.0.0", "2.1.1"); - this._checkLt("1.2.0", "2.1.1"); - this._checkLt("1.2.999999", "2.1.1"); - this._checkLt("1.9.999", "2.0.0"); - } - - function testCmpForgiving() public { - this._checkLt("a", "1"); - this._checkLt("a1", "1"); - this._checkLt("!", "1"); - this._checkEq("1", "1"); - this._checkLt("1", "2"); - this._checkLt("1a", "2"); - this._checkLt("1a", "2a"); - this._checkLt("1", "2a"); - this._checkLt("", "2a"); - this._checkEq("", ""); - - this._checkEq("v1.2.3", "1.2.3"); - this._checkLt("v1.2.2", "1.2.3"); - this._checkLt("v1.2", "1.2.3"); - this._checkEq("v1.2", "1.2.0"); - this._checkEq("1.2.3", "v1.2.3"); - this._checkLt("1.2.2", "v1.2.3"); - this._checkLt("1.2", "v1.2.3"); - this._checkEq("1.2", "v1.2.0"); - - this._checkEq("1.2", "1.2.0"); - this._checkLt("1.2.3-alpha", "1.2.3"); - this._checkLt("1.2-alpha", "1.2.3"); - this._checkEq("1.2.3-alpha", "1.2.3-alpha"); - this._checkLt("1.2.3-alpha", "1.2.3-alpha.123"); - this._checkLt("1.2.3-alpha.123", "1.2.3-alpha.124"); - this._checkLt("1.2.3-alpha.123.z", "1.2.3-alpha.124"); - this._checkLt("1.2.3-alpha.123.", "1.2.3-alpha.124"); - this._checkLt("1.2.3-alpha.124", "1.2.3-alpha.124a"); - this._checkLt("1.2.3-alpha.124", "1.2.3-alpha.12a"); - this._checkLt("1.2.3-thequickbrownfoxjumpsover", "1.2.3-thequickbrownfoxjumpsover1"); - this._checkLt("1.2.3-thequickbrownfoxjumpsover", "1.2.3-thequickbrownfoxjumpsover0"); - this._checkEq("1.2.3-thequickbrownfoxjumpsover0", "1.2.3-thequickbrownfoxjumpsover0"); - this._checkLt("1.2.3-99999999999999999999999999", "1.2.3-thequickbrownfoxjumpsover0"); - this._checkLt("1.2.3-99999999999999999999999999", "1.2.3-t"); - this._checkLt("1.2.3-alpha", "1.2.3-alpha.0"); - this._checkLt("1.2-alpha", "1.2.3-alpha"); - - this._checkLt("1.2.3-1", "1.2.3-a"); - this._checkLt("1.2.3-1", "1.2.3-alpha"); - this._checkLt("1.2.3-1.0", "1.2.3-1.a"); - - this._checkLt("1.2.3-alpha", "1.2.3-alpha.0"); - this._checkLt("1.2.3-alpha.1", "1.2.3-alpha.1.1"); - this._checkLt("1.2.3-alpha.1.a", "1.2.3-alpha.1.a.0"); - - this._checkEq("1.2.3-alpha+build", "1.2.3-alpha"); - this._checkEq("1.2.3+build", "1.2.3"); - this._checkLt("1.2.3-alpha", "1.2.3+build"); - - this._checkLt("1..3", "1.1.3"); - this._checkLt("1..4", "1.1.3"); // `1.0.4` < `1.1.3`. - this._checkEq("1.2.3a", "1.2.3a"); - this._checkLt("1.2.3a", "1.2.4"); - - this._checkEq("1..4", "1.0.4"); // confirm parsing is consistent - this._checkLt("1..4", "1.0.5"); // `1.0.4` < `1.0.5` - this._checkLt("1..4", "1.1"); // `1.0.4` < `1.1.0` - this._checkLt("1..", "1.0.1"); // `1.0.0` < `1.0.1` if final component is missing - this._checkEq("1.0.", "1.0.0"); // forgiving trailing dot - - this._checkEq("01.002.0003", "1.2.3"); - this._checkEq("v01.2.03", "1.2.3"); - - this._checkLt("", "1.0.0"); - this._checkEq("", "0.0.0"); - } -} diff --git a/grouperBot/lib/solady/test/SignatureCheckerLib.t.sol b/grouperBot/lib/solady/test/SignatureCheckerLib.t.sol deleted file mode 100644 index 1023252..0000000 --- a/grouperBot/lib/solady/test/SignatureCheckerLib.t.sol +++ /dev/null @@ -1,718 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {SignatureCheckerLib} from "../src/utils/SignatureCheckerLib.sol"; -import {ECDSA} from "../src/utils/ECDSA.sol"; -import {MockERC1271Wallet} from "./utils/mocks/MockERC1271Wallet.sol"; -import {MockERC1271Malicious} from "./utils/mocks/MockERC1271Malicious.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; - -contract SignatureCheckerLibTest is SoladyTest { - bytes32 constant TEST_MESSAGE = - 0x7dbaf558b0a1a5dc7a67202117ab143c1d8605a983e4a743bc06fcc03162dc0d; - - bytes32 constant WRONG_MESSAGE = - 0x2d0828dd7c97cff316356da3c16c68ba2316886a0e05ebafb8291939310d51a3; - - address constant SIGNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; - - address constant OTHER = address(uint160(1)); - - bytes32 constant TEST_SIGNED_MESSAGE_HASH = - 0x7d768af957ef8cbf6219a37e743d5546d911dae3e46449d8a5810522db2ef65e; - - bytes32 constant WRONG_SIGNED_MESSAGE_HASH = - 0x8cd3e659093d21364c6330514aff328218aa29c2693c5b0e96602df075561952; - - bytes constant SIGNATURE = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - - bytes constant INVALID_SIGNATURE = - hex"7688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - - MockERC1271Wallet mockERC1271Wallet; - - MockERC1271Malicious mockERC1271Malicious; - - function setUp() public { - mockERC1271Wallet = new MockERC1271Wallet(SIGNER); - mockERC1271Malicious = new MockERC1271Malicious(); - } - - function testSignatureCheckerOnEOAWithMatchingSignerAndSignature() public { - _checkSignature(SIGNER, TEST_SIGNED_MESSAGE_HASH, SIGNATURE, true); - } - - function testSignatureCheckerOnEOAWithInvalidSigner() public { - _checkSignature(OTHER, TEST_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnEOAWithWrongSignedMessageHash() public { - _checkSignature(SIGNER, WRONG_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnEOAWithInvalidSignature() public { - _checkSignature(SIGNER, TEST_SIGNED_MESSAGE_HASH, INVALID_SIGNATURE, false); - } - - function testSignatureCheckerOnWalletWithMatchingSignerAndSignature() public { - address signer = address(mockERC1271Wallet); - bytes32 hash = TEST_SIGNED_MESSAGE_HASH; - bytes memory signature = SIGNATURE; - _checkSignature(true, signer, hash, signature, true); - _checkSignature(false, signer, hash, signature, true); - vm.etch(signer, ""); - _checkSignature(false, signer, hash, signature, false); - } - - function testSignatureCheckerOnWalletWithInvalidSigner() public { - _checkSignatureBothModes(address(this), TEST_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnWalletWithZeroAddressSigner() public { - _checkSignatureBothModes(address(0), TEST_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnWalletWithWrongSignedMessageHash() public { - _checkSignatureBothModes( - address(mockERC1271Wallet), WRONG_SIGNED_MESSAGE_HASH, SIGNATURE, false - ); - } - - function testSignatureCheckerOnWalletWithInvalidSignature() public { - _checkSignatureBothModes( - address(mockERC1271Wallet), TEST_SIGNED_MESSAGE_HASH, INVALID_SIGNATURE, false - ); - } - - function testSignatureCheckerOnMaliciousWallet() public { - _checkSignatureBothModes( - address(mockERC1271Malicious), WRONG_SIGNED_MESSAGE_HASH, SIGNATURE, false - ); - } - - function testSignatureChecker(bytes32 digest) public { - (address signer, uint256 privateKey) = _randomSigner(); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - _checkSignature(signer, digest, abi.encodePacked(r, s, v), true); - - if (_randomChance(8)) { - assertEq( - this.isValidSignatureNowCalldata(signer, digest, abi.encodePacked(r, s, v)), true - ); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encodePacked(r, s, v)), - true - ); - assertEq( - SignatureCheckerLib.isValidSignatureNow( - signer, digest, abi.encodePacked(r, s, v + 1) - ), - false - ); - assertEq( - SignatureCheckerLib.isValidSignatureNow( - signer, digest, abi.encodePacked(r, s, v - 1) - ), - false - ); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, v, r, s), true); - } - - if (_randomChance(8)) { - bytes32 vs; - /// @solidity memory-safe-assembly - assembly { - vs := or(shl(255, sub(v, 27)), s) - } - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, r, vs), true); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encode(r, vs)), true - ); - assertEq(this.isValidSignatureNowCalldata(signer, digest, abi.encode(r, vs)), true); - } - - if (_randomChance(8)) { - bytes32 vsc; // Corrupted `vs`. - /// @solidity memory-safe-assembly - assembly { - vsc := or(shl(255, xor(1, sub(v, 27))), s) - } - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, r, vsc), false); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encode(r, vsc)), false - ); - assertEq(this.isValidSignatureNowCalldata(signer, digest, abi.encode(r, vsc)), false); - } - - if (_randomChance(8) && r != bytes32(0) && s != bytes32(0)) { - bytes32 rc = bytes32(uint256(r) - (_random() & 1)); // Corrupted `r`. - bytes32 sc = bytes32(uint256(s) - (_random() & 1)); // Corrupted `s`. - bool anyCorrupted = rc != r || sc != s; - _checkSignature(signer, digest, abi.encodePacked(rc, sc, v), !anyCorrupted); - } - - if (_randomChance(8)) { - uint8 vc = uint8(_random()); // Corrupted `v`. - while (vc == 28 || vc == 27) vc = uint8(_random()); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, vc, r, s), false); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encodePacked(r, s, vc)), - false - ); - assertEq( - this.isValidSignatureNowCalldata(signer, digest, abi.encodePacked(r, s, vc)), false - ); - } - } - - function _checkSignatureBothModes( - address signer, - bytes32 hash, - bytes memory signature, - bool expectedResult - ) internal { - _checkSignature(false, signer, hash, signature, expectedResult); - _checkSignature(true, signer, hash, signature, expectedResult); - } - - function _checkSignature( - address signer, - bytes32 hash, - bytes memory signature, - bool expectedResult - ) internal { - _checkSignature(false, signer, hash, signature, expectedResult); - } - - function _checkSignature( - bool onlyERC1271, - address signer, - bytes32 hash, - bytes memory signature, - bool expectedResult - ) internal { - bool callResult; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - - // `bytes4(keccak256("isValidSignatureNow(address,bytes32,bytes)"))`. - mstore(m, shl(224, 0x6ccea652)) - if onlyERC1271 { - // `bytes4(keccak256("isValidERC1271SignatureNow(address,bytes32,bytes)"))`. - mstore(m, shl(224, 0x3ae5d83c)) - } - // We'll still clean the upper 96 bits of signer, - // so that it will pass the implicit calldata check added by Solidity. - mstore(add(m, 0x04), shr(96, shl(96, signer))) - mstore(add(m, 0x24), hash) - mstore(add(m, 0x44), 0x60) // Offset of signature in calldata. - mstore(add(m, 0x64), mload(signature)) - mstore(add(m, 0x84), mload(add(signature, 0x20))) - mstore(add(m, 0xa4), mload(add(signature, 0x40))) - mstore(add(m, 0xc4), mload(add(signature, 0x60))) - // Brutalize the bytes following the 8-bit `v`. All ones will do. - mstore(add(m, 0xc5), not(0)) - - // We have to do the call in assembly to ensure that Solidity does not - // clean up the brutalized bits. - callResult := - and( - and( - // Whether the returndata is equal to 1. - eq(mload(0x00), 1), - // Whether the returndata is exactly 0x20 bytes (1 word) long . - eq(returndatasize(), 0x20) - ), - // Whether the staticcall does not revert. - // This must be placed at the end of the `and` clause, - // as the arguments are evaluated from right to left. - staticcall( - gas(), // Remaining gas. - address(), // The current contract's address. - m, // Offset of calldata in memory. - 0xe4, // Length of calldata in memory. - 0x00, // Offset of returndata. - 0x20 // Length of returndata to write. - ) - ) - } - assertEq(callResult, expectedResult); - - uint8 v; - bytes32 r; - bytes32 s; - bytes32 vs; - /// @solidity memory-safe-assembly - assembly { - // Contaminate the upper 96 bits. - signer := or(shl(160, 1), signer) - // Extract `r`, `s`, `v`. - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := byte(0, mload(add(signature, 0x60))) - // Pack `vs`. - vs := or(shl(255, sub(v, 27)), s) - - // Brutalize the memory. Just all ones will do. - let m := mload(0x40) - for { let i := 0 } lt(i, 30) { i := add(i, 1) } { mstore(add(m, shl(5, i)), not(0)) } - } - - if (onlyERC1271) { - assertEq( - SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, r, vs), expectedResult - ); - assertEq( - SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, v, r, s), - expectedResult - ); - } else { - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, r, vs), expectedResult); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, v, r, s), expectedResult); - } - } - - function isValidSignatureNow(address signer, bytes32 hash, bytes calldata signature) - external - returns (bool result) - { - bool signatureIsBrutalized; - /// @solidity memory-safe-assembly - assembly { - // Contaminate the upper 96 bits. - signer := or(shl(160, 1), signer) - // Ensure that the bytes right after the signature is brutalized. - signatureIsBrutalized := calldataload(add(signature.offset, signature.length)) - } - if (!signatureIsBrutalized) revert("Signature is not brutalized."); - - result = SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, signature), result); - } - - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes calldata signature) - external - returns (bool result) - { - bool signatureIsBrutalized; - /// @solidity memory-safe-assembly - assembly { - // Contaminate the upper 96 bits. - signer := or(shl(160, 1), signer) - // Ensure that the bytes right after the signature is brutalized. - signatureIsBrutalized := calldataload(add(signature.offset, signature.length)) - } - if (!signatureIsBrutalized) revert("Signature is not brutalized."); - - result = SignatureCheckerLib.isValidERC1271SignatureNowCalldata(signer, hash, signature); - assertEq(SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, signature), result); - } - - function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) - external - view - returns (bool result) - { - result = SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature); - } - - function isValidERC1271SignatureNowCalldata( - address signer, - bytes32 hash, - bytes calldata signature - ) external view returns (bool result) { - result = SignatureCheckerLib.isValidERC1271SignatureNowCalldata(signer, hash, signature); - } - - function testEmptyCalldataHelpers() public { - assertFalse( - SignatureCheckerLib.isValidSignatureNow( - address(1), bytes32(0), SignatureCheckerLib.emptySignature() - ) - ); - } - - function testToEthSignedMessageHashDifferential(bytes32 hash) public { - assertEq( - SignatureCheckerLib.toEthSignedMessageHash(hash), ECDSA.toEthSignedMessageHash(hash) - ); - } - - function testToEthSignedMessageHashDifferential(bytes memory s) public { - assertEq(SignatureCheckerLib.toEthSignedMessageHash(s), ECDSA.toEthSignedMessageHash(s)); - } - - function testSignatureCheckerPassthrough(bytes calldata signature) public { - bytes32 hash = keccak256(signature); - mockERC1271Wallet.setUseSignaturePassthrough(true); - if (_randomChance(8)) { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - address signer = address(mockERC1271Wallet); - assertEq(SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature), true); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, signature), true); - - hash = bytes32(uint256(hash) ^ 1); - assertEq(SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature), false); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, signature), false); - } - - bytes32 private constant _ERC6492_DETECTION_SUFFIX = - 0x6492649264926492649264926492649264926492649264926492649264926492; - - struct _ERC6492TestTemps { - bytes initcode; - bytes factoryCalldata; - bytes setSignerCalldata; - address eoa; - bytes32 salt; - uint256 privateKey; - address factory; - address smartAccount; - bytes32 digest; - bytes innerSignature; - bytes signature; - bool result; - address revertingVerifier; - } - - function _erc6492TestTemps() internal returns (_ERC6492TestTemps memory t) { - t.factory = _NICKS_FACTORY; - assertGt(t.factory.code.length, 0); - (t.eoa, t.privateKey) = _randomSigner(); - t.initcode = abi.encodePacked(type(MockERC1271Wallet).creationCode, uint256(uint160(t.eoa))); - t.salt = bytes32(_random()); - t.factoryCalldata = abi.encodePacked(t.salt, t.initcode); - t.smartAccount = - LibClone.predictDeterministicAddress(keccak256(t.initcode), t.salt, t.factory); - assertEq(t.smartAccount.code.length, 0); - - t.digest = keccak256(abi.encodePacked("Hehe", _random())); - { - (uint8 v, bytes32 r, bytes32 s) = vm.sign(t.privateKey, t.digest); - t.innerSignature = abi.encodePacked(r, s, v); - } - if (_randomChance(2)) { - t.innerSignature = _makeShortSignature(t.innerSignature); - } - t.signature = abi.encode(t.factory, t.factoryCalldata, t.innerSignature); - t.signature = abi.encodePacked(t.signature, _ERC6492_DETECTION_SUFFIX); - } - - function _makeNewEOA(_ERC6492TestTemps memory t) internal { - while (true) { - (address newEOA, uint256 newPrivateKey) = _randomSigner(); - if (newEOA == t.eoa) continue; - t.eoa = newEOA; - t.privateKey = newPrivateKey; - t.digest = keccak256(abi.encodePacked("Haha", _random())); - { - (uint8 v, bytes32 r, bytes32 s) = vm.sign(t.privateKey, t.digest); - t.innerSignature = abi.encodePacked(r, s, v); - } - t.setSignerCalldata = abi.encodeWithSignature("setSigner(address)", t.eoa); - t.signature = abi.encode(t.smartAccount, t.setSignerCalldata, t.innerSignature); - t.signature = abi.encodePacked(t.signature, _ERC6492_DETECTION_SUFFIX); - break; - } - } - - function testERC6492OnEOA() public { - this.testERC6492OnEOA(bytes32(0)); - } - - function testERC6492AllowSideEffectsOnEOA() public { - this.testERC6492AllowSideEffectsOnEOA(bytes32(0)); - } - - function testERC6492OnEOA(bytes32) public { - _ERC6492TestTemps memory t; - t.digest = keccak256("hehe"); - (t.eoa, t.privateKey) = _randomSigner(); - { - (uint8 v, bytes32 r, bytes32 s) = vm.sign(t.privateKey, t.digest); - t.signature = abi.encodePacked(r, s, v); - } - if (_randomChance(2)) { - t.signature = _makeShortSignature(t.signature); - } - bool result = SignatureCheckerLib.isValidERC6492SignatureNow(t.eoa, t.digest, t.signature); - assertTrue(result); - result = SignatureCheckerLib.isValidERC6492SignatureNow( - t.eoa, t.digest, abi.encodePacked(t.signature, " ") - ); - assertFalse(result); - vm.etch(t.eoa, hex"00"); - result = SignatureCheckerLib.isValidERC6492SignatureNow(t.eoa, t.digest, t.signature); - assertFalse(result); - } - - function testERC6492AllowSideEffectsOnEOA(bytes32) public { - _ERC6492TestTemps memory t; - t.digest = keccak256("hehe"); - (t.eoa, t.privateKey) = _randomSigner(); - { - (uint8 v, bytes32 r, bytes32 s) = vm.sign(t.privateKey, t.digest); - t.signature = abi.encodePacked(r, s, v); - } - if (_randomChance(2)) { - t.signature = _makeShortSignature(t.signature); - } - bool result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.eoa, t.digest, t.signature - ); - assertTrue(result); - result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.eoa, t.digest, abi.encodePacked(t.signature, " ") - ); - assertFalse(result); - vm.etch(t.eoa, hex"00"); - result = SignatureCheckerLib.isValidERC6492SignatureNow(t.eoa, t.digest, t.signature); - assertFalse(result); - } - - function testERC6492AllowSideEffectsPostDeploy() public { - _etchERC6492Verifier(); - _ERC6492TestTemps memory t = _erc6492TestTemps(); - (bool success,) = t.factory.call(t.factoryCalldata); - require(success); - assertGt(t.smartAccount.code.length, 0); - t.result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.smartAccount, t.digest, t.innerSignature - ); - assertTrue(t.result); - - _makeNewEOA(t); - t.result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.smartAccount, t.digest, t.signature - ); - assertTrue(t.result); - assertEq(MockERC1271Wallet(t.smartAccount).signer(), t.eoa); - } - - function testERC6492AllowSideEffectsPreDeploy() public { - _etchERC6492Verifier(); - _ERC6492TestTemps memory t = _erc6492TestTemps(); - t.result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.smartAccount, t.digest, t.innerSignature - ); - assertFalse(t.result); - // This should return true now, as the function does have an ECDSA fallback. - t.result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.eoa, t.digest, t.innerSignature - ); - assertTrue(t.result); - assertEq(t.smartAccount.code.length, 0); - t.result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.smartAccount, t.digest, t.signature - ); - assertTrue(t.result); - assertGt(t.smartAccount.code.length, 0); - t.result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.smartAccount, t.digest, t.signature - ); - assertTrue(t.result); - assertGt(t.smartAccount.code.length, 0); - assertEq(MockERC1271Wallet(t.smartAccount).signer(), t.eoa); - - _makeNewEOA(t); - t.result = SignatureCheckerLib.isValidERC6492SignatureNowAllowSideEffects( - t.smartAccount, t.digest, t.signature - ); - assertTrue(t.result); - assertEq(MockERC1271Wallet(t.smartAccount).signer(), t.eoa); - } - - function _etchERC6492Verifier() internal returns (address verifier) { - _ERC6492TestTemps memory t; - t.initcode = - hex"6040600b3d3960403df3fe36383d373d3d6020515160208051013d3d515af160203851516084018038385101606037303452813582523838523490601c34355afa34513060e01b141634f3"; - t.factory = _NICKS_FACTORY; - t.salt = 0x0000000000000000000000000000000000000000ebfa269e1c28e801a0dc87e2; - verifier = LibClone.predictDeterministicAddress(keccak256(t.initcode), t.salt, t.factory); - assertEq(_nicksCreate2(0, t.salt, t.initcode), verifier); - assertGt(verifier.code.length, 0); - emit LogBytes32(keccak256(t.initcode)); - emit LogBytes(verifier.code); - } - - function _etchERC6492RevertingVerifier() internal returns (address revertingVerifier) { - _ERC6492TestTemps memory t; - t.initcode = - hex"6040600b3d3960403df3fe36383d373d3d6020515160208051013d3d515af160203851516084018038385101606037303452813582523838523490601c34355afa34513060e01b141634fd"; - t.factory = _NICKS_FACTORY; - t.salt = 0x000000000000000000000000000000000000000068f35e1510740001fd13984a; - revertingVerifier = - LibClone.predictDeterministicAddress(keccak256(t.initcode), t.salt, t.factory); - assertEq(_nicksCreate2(0, t.salt, t.initcode), revertingVerifier); - assertGt(revertingVerifier.code.length, 0); - emit LogBytes32(keccak256(t.initcode)); - emit LogBytes(revertingVerifier.code); - } - - function testEtchERC6492RevertingVerifier() public { - _etchERC6492RevertingVerifier(); - } - - function testERC6492PostDeploy() public { - _ERC6492TestTemps memory t = _erc6492TestTemps(); - t.revertingVerifier = _etchERC6492RevertingVerifier(); - (bool success,) = t.factory.call(t.factoryCalldata); - require(success); - - assertGt(t.smartAccount.code.length, 0); - t.result = SignatureCheckerLib.isValidERC6492SignatureNow( - t.smartAccount, t.digest, t.innerSignature - ); - assertTrue(t.result); - - address oldEOA = t.eoa; - _makeNewEOA(t); - t.result = - SignatureCheckerLib.isValidERC6492SignatureNow(t.smartAccount, t.digest, t.signature); - assertTrue(t.result); - assertEq(MockERC1271Wallet(t.smartAccount).signer(), oldEOA); - } - - function testERC6492PreDeploy() public { - _ERC6492TestTemps memory t = _erc6492TestTemps(); - t.revertingVerifier = _etchERC6492RevertingVerifier(); - - t.result = SignatureCheckerLib.isValidERC6492SignatureNow( - t.smartAccount, t.digest, t.innerSignature - ); - assertFalse(t.result); - // This should return true now, as the function does have an ECDSA fallback. - t.result = SignatureCheckerLib.isValidERC6492SignatureNow(t.eoa, t.digest, t.innerSignature); - assertTrue(t.result); - assertEq(t.smartAccount.code.length, 0); - t.result = - SignatureCheckerLib.isValidERC6492SignatureNow(t.smartAccount, t.digest, t.signature); - assertTrue(t.result); - assertEq(t.smartAccount.code.length, 0); - t.result = - SignatureCheckerLib.isValidERC6492SignatureNow(t.smartAccount, t.digest, t.signature); - assertTrue(t.result); - assertEq(t.smartAccount.code.length, 0); - - t.result = SignatureCheckerLib.isValidERC6492SignatureNow( - t.smartAccount, keccak256(""), t.signature - ); - assertFalse(t.result); - assertEq(t.smartAccount.code.length, 0); - } - - function testERC6492WithoutRevertingVerifier() public { - _ERC6492TestTemps memory t = _erc6492TestTemps(); - - t.result = SignatureCheckerLib.isValidERC6492SignatureNow( - t.smartAccount, t.digest, t.innerSignature - ); - assertFalse(t.result); - - t.result = SignatureCheckerLib.isValidERC6492SignatureNow( - t.smartAccount, t.digest, t.innerSignature - ); - assertFalse(t.result); - // This should return true now, as the function does have an ECDSA fallback. - t.result = SignatureCheckerLib.isValidERC6492SignatureNow(t.eoa, t.digest, t.innerSignature); - assertTrue(t.result); - assertEq(t.smartAccount.code.length, 0); - // Without the reverting verifier, the function will simply return false. - t.result = - SignatureCheckerLib.isValidERC6492SignatureNow(t.smartAccount, t.digest, t.signature); - assertFalse(t.result); - assertEq(t.smartAccount.code.length, 0); - t.result = - SignatureCheckerLib.isValidERC6492SignatureNow(t.smartAccount, t.digest, t.signature); - assertFalse(t.result); - assertEq(t.smartAccount.code.length, 0); - } - - function check_EcrecoverTrickEquivalence(bool success, uint256 signer, uint256 recovered) - public - pure - { - uint256 rds = success ? 0x20 : 0x00; - bool expected = rds == 0x20 && address(uint160(signer)) == address(uint160(recovered)); - bool optimized; - /// @solidity memory-safe-assembly - assembly { - optimized := gt(rds, shl(96, xor(signer, recovered))) - } - assert(optimized == expected); - } - - function testEcrecoverTrickEquivalence(bool success, uint256 signer, uint256 recovered) - public - pure - { - check_EcrecoverTrickEquivalence(success, signer, recovered); - } - - function check_EcrecoverLoopTrick(uint256 n) public pure { - bool isValid; - bool memoryIsSafe; - /// @solidity memory-safe-assembly - assembly { - let r := and(0x100, n) - n := and(0xff, n) - let signature := mload(0x40) - mstore(signature, n) - mstore(0x40, add(n, add(0x20, signature))) - if iszero(n) { if r { signature := 0x60 } } - for { let m := mload(0x40) } 1 {} { - switch mload(signature) - case 64 { - mstore(0x40, not(0)) - mstore(0x60, not(0)) - } - case 65 { - mstore(0x40, not(0)) - mstore(0x60, not(0)) - } - default { break } - isValid := 1 - mstore(0x40, m) - mstore(0x60, 0) - break - } - memoryIsSafe := and(iszero(mload(0x60)), lt(mload(0x40), 0xffffffff)) - } - assert(memoryIsSafe); - assert(isValid == (n == 64 || n == 65)); - } - - function testEcrecoverLoopTrick(uint256 n) public pure { - check_EcrecoverLoopTrick(n); - } - - function _makeShortSignature(bytes memory signature) - internal - pure - returns (bytes memory result) - { - require(signature.length == 65); - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let r := mload(add(signature, 0x20)) - let s := mload(add(signature, 0x40)) - let v := byte(0, mload(add(signature, 0x60))) - let vs := 0 - switch v - case 27 { vs := shr(1, shl(1, s)) } - case 28 { vs := or(shl(255, 1), shr(1, shl(1, s))) } - default { invalid() } - mstore(result, 0x40) // Length. - mstore(add(result, 0x20), r) - mstore(add(result, 0x40), vs) - mstore(0x40, add(result, 0x60)) // Allocate memory. - } - } -} diff --git a/grouperBot/lib/solady/test/TestPlus.t.sol b/grouperBot/lib/solady/test/TestPlus.t.sol deleted file mode 100644 index 30c47af..0000000 --- a/grouperBot/lib/solady/test/TestPlus.t.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; - -contract TestPlusrTest is SoladyTest { - function testRandomUnique(bytes32 groupIdA, bytes32 groupIdB) public { - uint256 r0A = _randomUnique(groupIdA); - uint256 r1A = _randomUnique(groupIdA); - assertNotEq(r0A, r1A); - uint256 r0B = _randomUnique(groupIdB); - uint256 r1B = _randomUnique(groupIdB); - assertNotEq(r0B, r1B); - if (groupIdA == groupIdB) { - assertNotEq(r0A, r1B); - assertNotEq(r0A, r0B); - assertNotEq(r1A, r1B); - assertNotEq(r1A, r0B); - } - } - - function testRandomUniqueAddress(bytes32 groupIdA, bytes32 groupIdB) public { - address r0A = _randomUniqueAddress(groupIdA); - address r1A = _randomUniqueAddress(groupIdA); - assertNotEq(r0A, r1A); - address r0B = _randomUniqueAddress(groupIdB); - address r1B = _randomUniqueAddress(groupIdB); - assertNotEq(r0B, r1B); - if (groupIdA == groupIdB) { - assertNotEq(r0A, r1B); - assertNotEq(r0A, r0B); - assertNotEq(r1A, r1B); - assertNotEq(r1A, r0B); - } - } -} diff --git a/grouperBot/lib/solady/test/TimedRoles.t.sol b/grouperBot/lib/solady/test/TimedRoles.t.sol deleted file mode 100644 index c108e31..0000000 --- a/grouperBot/lib/solady/test/TimedRoles.t.sol +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {LibSort} from "../src/utils/LibSort.sol"; -import {DynamicArrayLib} from "../src/utils/DynamicArrayLib.sol"; -import "./utils/SoladyTest.sol"; -import "./utils/mocks/MockTimedRoles.sol"; - -contract TimedRolesTest is SoladyTest { - using DynamicArrayLib for *; - - event TimedRoleSet( - address indexed holder, uint256 indexed timedRole, uint40 start, uint40 expires - ); - - MockTimedRoles mockTimedRoles; - - function setUp() public { - mockTimedRoles = new MockTimedRoles(); - mockTimedRoles.setMaxTimedRole(type(uint256).max); - mockTimedRoles.setOwner(address(this)); - } - - struct TimedRoleConfig { - address holder; - uint256 role; - uint40 start; - uint40 expires; - } - - function _sampleTimedRoleConfig() internal returns (TimedRoleConfig memory c) { - uint256 m = 0xf00000000000000000000000000000000000000000000000000000000000000f; - c.holder = _randomNonZeroAddress(); - c.role = _randomUniform() & m; - (c.start, c.expires) = _sampleValidActiveTimeRange(); - } - - function _hasDuplicateKeys(TimedRoleConfig[] memory a) internal pure returns (bool) { - bytes32[] memory hashes = new bytes32[](a.length); - for (uint256 i; i != a.length; ++i) { - hashes[i] = keccak256(abi.encode(a[i].holder, a[i].role)); - } - LibSort.insertionSort(hashes); - LibSort.uniquifySorted(hashes); - return hashes.length != a.length; - } - - function _sampleTimedRoleConfigs() internal returns (TimedRoleConfig[] memory a) { - a = new TimedRoleConfig[](_randomUniform() & 3); - for (uint256 i; i != a.length; ++i) { - a[i] = _sampleTimedRoleConfig(); - } - } - - function _sampleActiveTimeRange() internal returns (uint40 start, uint40 expires) { - if (_randomChance(2)) { - start = uint40(_random()); - expires = uint40(_random()); - } else { - start = uint8(_random()); - expires = uint8(_random()); - } - } - - function _sampleValidActiveTimeRange() internal returns (uint40 start, uint40 expires) { - do { - (start, expires) = _sampleActiveTimeRange(); - } while (expires < start); - } - - function _sampleInvalidActiveTimeRange() internal returns (uint40 start, uint40 expires) { - do { - (start, expires) = _sampleActiveTimeRange(); - } while (!(expires < start)); - } - - function testSetAndGetTimedRoles(bytes32) public { - TimedRoleConfig[] memory a = _sampleTimedRoleConfigs(); - - uint256 targetTimestamp = _bound(_random(), 0, _randomChance(2) ? 0xff : 2 ** 41 - 1); - vm.warp(targetTimestamp); - - for (uint256 i; i != a.length; ++i) { - TimedRoleConfig memory c = a[i]; - vm.expectEmit(true, true, true, true); - emit TimedRoleSet(c.holder, c.role, c.start, c.expires); - mockTimedRoles.setTimedRole(c.holder, c.role, c.start, c.expires); - (bool isActive, uint40 start, uint40 expires) = - mockTimedRoles.timedRoleActive(c.holder, c.role); - assertEq(start, c.start); - assertEq(expires, c.expires); - assertEq(isActive, start <= targetTimestamp && targetTimestamp <= expires); - } - if (!_hasDuplicateKeys(a)) { - for (uint256 i; i != a.length; ++i) { - TimedRoleConfig memory c = a[i]; - (bool isActive, uint40 start, uint40 expires) = - mockTimedRoles.timedRoleActive(c.holder, c.role); - assertEq(start, c.start); - assertEq(expires, c.expires); - assertEq(isActive, start <= targetTimestamp && targetTimestamp <= expires); - } - } - if (_randomChance(16)) { - TimedRoleConfig memory c = _sampleTimedRoleConfig(); - (c.start, c.expires) = _sampleInvalidActiveTimeRange(); - vm.expectRevert(TimedRoles.InvalidTimedRoleRange.selector); - mockTimedRoles.setTimedRole(c.holder, c.role, c.start, c.expires); - } - if (_randomChance(16)) { - TimedRoleConfig memory c = _sampleTimedRoleConfig(); - mockTimedRoles.setOwner(_randomUniqueHashedAddress()); - vm.expectRevert(TimedRoles.TimedRolesUnauthorized.selector); - mockTimedRoles.setTimedRole(c.holder, c.role, c.start, c.expires); - mockTimedRoles.setOwner(address(this)); - if (_randomChance(16)) { - c.holder = address(0); - vm.expectRevert(TimedRoles.TimedRoleHolderIsZeroAddress.selector); - } - mockTimedRoles.setTimedRole(c.holder, c.role, c.start, c.expires); - } - if (_randomChance(16)) { - uint256 maxTimedRole = _random(); - mockTimedRoles.setMaxTimedRole(maxTimedRole); - TimedRoleConfig memory c = _sampleTimedRoleConfig(); - if (c.role > maxTimedRole) { - vm.expectRevert(TimedRoles.InvalidTimedRole.selector); - } - mockTimedRoles.setTimedRole(c.holder, c.role, c.start, c.expires); - } - } - - function testTimedRolesModifiers(bytes32) public { - TimedRoleConfig memory c = _sampleTimedRoleConfig(); - c.start = 0; - c.expires = 0xffffffffff; - mockTimedRoles.setTimedRole(c.holder, c.role, c.start, c.expires); - uint256[] memory allowedTimeRoles = _sampleRoles(3); - mockTimedRoles.setAllowedTimedRole(allowedTimeRoles[0]); - vm.warp(_bound(_randomUniform(), c.start, c.expires)); - - if (allowedTimeRoles[0] == c.role) { - vm.prank(c.holder); - mockTimedRoles.guardedByOnlyOwnerOrTimedRole(); - } else { - vm.prank(c.holder); - vm.expectRevert(TimedRoles.TimedRolesUnauthorized.selector); - mockTimedRoles.guardedByOnlyOwnerOrTimedRole(); - } - - mockTimedRoles.setAllowedTimedRolesEncoded(abi.encodePacked(allowedTimeRoles)); - - if (allowedTimeRoles.contains(c.role)) { - vm.prank(c.holder); - mockTimedRoles.guardedByOnlyOwnerOrTimedRoles(); - } else { - vm.prank(c.holder); - vm.expectRevert(TimedRoles.TimedRolesUnauthorized.selector); - mockTimedRoles.guardedByOnlyOwnerOrTimedRoles(); - } - - if (_randomChance(128)) { - mockTimedRoles.guardedByOnlyOwnerOrTimedRole(); - mockTimedRoles.guardedByOnlyOwnerOrTimedRoles(); - } - } - - function _sampleRoles(uint256 n) internal returns (uint256[] memory roles) { - unchecked { - uint256 m = 0xf00000000000000000000000000000000000000000000000000000000000000f; - roles = DynamicArrayLib.malloc(n); - for (uint256 i; i != n; ++i) { - roles.set(i, _randomUniform() & m); - } - } - } -} diff --git a/grouperBot/lib/solady/test/Timelock.t.sol b/grouperBot/lib/solady/test/Timelock.t.sol deleted file mode 100644 index 5949532..0000000 --- a/grouperBot/lib/solady/test/Timelock.t.sol +++ /dev/null @@ -1,422 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {Timelock} from "../src/accounts/Timelock.sol"; -import {EnumerableRoles} from "../src/auth/EnumerableRoles.sol"; - -contract TimelockTest is SoladyTest { - struct Call { - address target; - int256 value; - bytes data; - } - - event Proposed(bytes32 indexed id, bytes32 mode, bytes executionData, uint256 readyTimestamp); - event Executed(bytes32 indexed id, bytes32 mode, bytes executionData); - event Cancelled(bytes32 indexed id); - event MinDelaySet(uint256 newMinDelay); - - Timelock timelock; - - uint256 internal constant _DEFAULT_MIN_DELAY = 1000; - address internal constant _ALICE = address(111); - address internal constant _BOB = address(222); - address internal constant _CHARLIE = address(333); - address internal constant _ADMIN = address(777); - bytes32 internal constant _SUPPORTED_MODE = bytes10(0x01000000000078210001); - - uint256 internal constant _MAX_DELAY = 2 ** 254 - 1; - - function setUp() public { - timelock = new Timelock(); - _initializeTimelock(); - } - - function _initializeTimelock() internal { - address[] memory a = new address[](2); - - a[0] = address(this); - a[1] = _ALICE; - - timelock.initialize(_DEFAULT_MIN_DELAY, _ADMIN, a, a, a); - } - - function testInitialize() public { - assertEq(timelock.hasRole(_ALICE, timelock.EXECUTOR_ROLE()), true); - address[] memory a; - vm.expectRevert(Timelock.TimelockAlreadyInitialized.selector); - timelock.initialize(_MAX_DELAY, _ADMIN, a, a, a); - vm.expectRevert(Timelock.TimelockDelayOverflow.selector); - timelock.initialize(_MAX_DELAY + 1, _ADMIN, a, a, a); - } - - struct _PredecessorTestTemps { - Call[] calls0; - Call[] calls1; - bytes executionData0; - bytes executionData1; - bytes32 id0; - bytes32 id1; - uint256 delay; - uint256 minDelay; - uint256 readyTimestamp; - } - - function testPredecessor() public { - uint256 executorRole = timelock.EXECUTOR_ROLE(); - - _PredecessorTestTemps memory t; - t.calls0 = new Call[](1); - t.calls0[0].target = address(timelock); - t.calls0[0].data = - abi.encodeWithSignature("setRole(address,uint256,bool)", _BOB, executorRole, true); - t.executionData0 = abi.encode(t.calls0); - t.id0 = _id(t.executionData0); - - t.calls1 = new Call[](1); - t.calls1[0].target = address(timelock); - t.calls1[0].data = - abi.encodeWithSignature("setRole(address,uint256,bool)", _CHARLIE, executorRole, true); - t.executionData1 = abi.encode(t.calls1, abi.encodePacked(t.id0)); - t.id1 = _id(t.executionData1); - - // Must revert if try to execute on an empty id. - vm.expectRevert( - abi.encodeWithSignature( - "TimelockInvalidOperation(bytes32,uint256)", - t.id0, - _os(Timelock.OperationState.Ready) - ) - ); - timelock.execute(_SUPPORTED_MODE, t.executionData0); - - assertEq(timelock.propose(_SUPPORTED_MODE, t.executionData0, _DEFAULT_MIN_DELAY), t.id0); - assertEq(timelock.propose(_SUPPORTED_MODE, t.executionData1, _DEFAULT_MIN_DELAY), t.id1); - - t.readyTimestamp = block.timestamp + _DEFAULT_MIN_DELAY; - vm.warp(t.readyTimestamp); - vm.expectRevert(abi.encodeWithSignature("TimelockUnexecutedPredecessor(bytes32)", t.id0)); - timelock.execute(_SUPPORTED_MODE, t.executionData1); - - vm.prank(_BOB); - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - timelock.execute(_SUPPORTED_MODE, t.executionData0); - - timelock.execute(_SUPPORTED_MODE, t.executionData0); - assertEq(timelock.roleHolderCount(executorRole), 3); - - vm.prank(_BOB); - timelock.execute(_SUPPORTED_MODE, t.executionData1); - assertEq(timelock.roleHolderCount(executorRole), 4); - - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - timelock.setRole(_CHARLIE, executorRole, false); - } - - function testOpenRoleHolder() public { - uint256 executorRole = timelock.EXECUTOR_ROLE(); - - _PredecessorTestTemps memory t; - t.calls0 = new Call[](1); - t.calls0[0].target = address(timelock); - t.calls0[0].data = abi.encodeWithSignature( - "setRole(address,uint256,bool)", timelock.OPEN_ROLE_HOLDER(), executorRole, true - ); - t.executionData0 = abi.encode(t.calls0); - t.id0 = _id(t.executionData0); - - t.calls1 = new Call[](1); - t.calls1[0].target = address(timelock); - t.calls1[0].data = - abi.encodeWithSignature("setRole(address,uint256,bool)", _CHARLIE, executorRole, true); - t.executionData1 = abi.encode(t.calls1, abi.encodePacked(t.id0)); - t.id1 = _id(t.executionData1); - - assertEq(timelock.propose(_SUPPORTED_MODE, t.executionData0, _DEFAULT_MIN_DELAY), t.id0); - assertEq(timelock.propose(_SUPPORTED_MODE, t.executionData1, _DEFAULT_MIN_DELAY), t.id1); - - t.readyTimestamp = block.timestamp + _DEFAULT_MIN_DELAY; - vm.warp(t.readyTimestamp); - vm.expectRevert(abi.encodeWithSignature("TimelockUnexecutedPredecessor(bytes32)", t.id0)); - timelock.execute(_SUPPORTED_MODE, t.executionData1); - - timelock.execute(_SUPPORTED_MODE, t.executionData0); - assertEq(timelock.roleHolderCount(executorRole), 3); - - vm.prank(_BOB); - timelock.execute(_SUPPORTED_MODE, t.executionData1); - assertEq(timelock.roleHolderCount(executorRole), 4); - - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - timelock.setRole(_CHARLIE, executorRole, false); - } - - function testAdminRole() public { - uint256 executorRole = timelock.EXECUTOR_ROLE(); - uint256 adminRole = timelock.ADMIN_ROLE(); - - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - timelock.setRole(_CHARLIE, executorRole, false); - - vm.prank(_ADMIN); - timelock.setRole(_CHARLIE, executorRole, true); - - vm.prank(_ADMIN); - timelock.setRole(_ADMIN, adminRole, false); - - vm.expectRevert(EnumerableRoles.EnumerableRolesUnauthorized.selector); - vm.prank(_ADMIN); - timelock.setRole(_ADMIN, adminRole, false); - } - - struct _TestTemps { - Call[] calls; - bytes executionData; - bytes32 id; - uint256 delay; - uint256 minDelay; - uint256 readyTimestamp; - } - - function testSetAndGetMinDelay(uint256 newMinDelay) public { - vm.warp(block.timestamp + _bound(_random(), 0, 0xffffffff)); - - newMinDelay = _bound(newMinDelay, 0, _MAX_DELAY); - _TestTemps memory t; - t.calls = new Call[](1); - t.calls[0].target = address(timelock); - t.calls[0].data = abi.encodeWithSignature("setMinDelay(uint256)", newMinDelay); - - t.executionData = abi.encode(t.calls); - t.id = _id(t.executionData); - - if (_randomChance(16)) { - t.delay = _random(); - t.minDelay = timelock.minDelay(); - if (t.delay < t.minDelay) { - vm.expectRevert( - abi.encodeWithSignature( - "TimelockInsufficientDelay(uint256,uint256)", t.delay, t.minDelay - ) - ); - timelock.propose(_SUPPORTED_MODE, t.executionData, t.delay); - return; - } else if (t.delay > _MAX_DELAY) { - vm.expectRevert(Timelock.TimelockDelayOverflow.selector); - timelock.propose(_SUPPORTED_MODE, t.executionData, t.delay); - return; - } - } - - assertEq(uint8(timelock.operationState(t.id)), uint8(Timelock.OperationState.Unset)); - assertEq(timelock.readyTimestamp(t.id), 0); - - if (_randomChance(64)) { - vm.expectRevert( - abi.encodeWithSignature( - "TimelockInvalidOperation(bytes32,uint256)", - t.id, - _os(Timelock.OperationState.Ready) | _os(Timelock.OperationState.Waiting) - ) - ); - timelock.cancel(t.id); - } - - t.readyTimestamp = block.timestamp + _DEFAULT_MIN_DELAY; - vm.expectEmit(true, true, true, true); - emit Proposed(t.id, _SUPPORTED_MODE, t.executionData, t.readyTimestamp); - assertEq(timelock.propose(_SUPPORTED_MODE, t.executionData, _DEFAULT_MIN_DELAY), t.id); - - assertEq(uint8(timelock.operationState(t.id)), uint8(Timelock.OperationState.Waiting)); - assertEq(timelock.readyTimestamp(t.id), t.readyTimestamp); - - if (_randomChance(16)) { - vm.warp(block.timestamp + _bound(_random(), 0, _DEFAULT_MIN_DELAY * 2)); - vm.expectEmit(true, true, true, true); - emit Cancelled(t.id); - timelock.cancel(t.id); - assertEq(uint8(timelock.operationState(t.id)), uint8(Timelock.OperationState.Unset)); - return; - } - - if (_randomChance(32)) { - vm.warp(t.readyTimestamp - 1); - vm.expectRevert( - abi.encodeWithSignature( - "TimelockInvalidOperation(bytes32,uint256)", - t.id, - _os(Timelock.OperationState.Ready) - ) - ); - timelock.execute(_SUPPORTED_MODE, t.executionData); - return; - } - - vm.warp(t.readyTimestamp); - assertEq(uint8(timelock.operationState(t.id)), uint8(Timelock.OperationState.Ready)); - vm.expectEmit(true, true, true, true); - emit MinDelaySet(newMinDelay); - vm.expectEmit(true, true, true, true); - emit Executed(t.id, _SUPPORTED_MODE, t.executionData); - timelock.execute(_SUPPORTED_MODE, t.executionData); - assertEq(timelock.minDelay(), newMinDelay); - assertEq(uint8(timelock.operationState(t.id)), uint8(Timelock.OperationState.Done)); - assertEq(timelock.readyTimestamp(t.id), t.readyTimestamp); - - if (_randomChance(8)) { - vm.expectRevert( - abi.encodeWithSignature( - "TimelockInvalidOperation(bytes32,uint256)", - t.id, - _os(Timelock.OperationState.Ready) - ) - ); - timelock.execute(_SUPPORTED_MODE, t.executionData); - } - } - - function _os(Timelock.OperationState s) internal pure returns (uint256) { - return 1 << uint256(uint8(s)); - } - - function testOperationStateDifferentialTrick(uint256 packed, uint256 blockTimestamp) - public - pure - { - check_OperationStateDifferentialTrick(packed, blockTimestamp); - } - - function check_OperationStateDifferentialTrick(uint256 packed, uint256 blockTimestamp) - public - pure - { - if (!_isOperationReadyOriginal(packed ^ 1, blockTimestamp)) { - if (_isOperationDoneOriginal(packed, blockTimestamp)) { - packed ^= 1; - assert(!_isOperationReadyOriginal(packed, blockTimestamp)); - } - } - assert( - _operationStateOptimized(packed, blockTimestamp) - == uint8(_operationStateOriginal(packed, blockTimestamp)) - ); - assert( - _isOperationDoneOptimized(packed, blockTimestamp) - == _isOperationDoneOriginal(packed, blockTimestamp) - ); - - assert( - _isOperationPendingOptimized(packed) - == _isOperationPendingOriginal(packed, blockTimestamp) - ); - assert( - _isOperationReadyOptimized(packed, blockTimestamp) - == _isOperationReadyOriginal(packed, blockTimestamp) - ); - } - - function _isOperationPendingOptimized(uint256 packed) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let p := packed - result := iszero(or(and(1, p), iszero(p))) - } - } - - function _isOperationDoneOptimized(uint256 packed, uint256) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - result := and(1, packed) - } - } - - function _isOperationReadyOptimized(uint256 packed, uint256 blockTimestamp) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let p := packed - result := iszero(or(or(and(1, p), iszero(p)), lt(blockTimestamp, shr(1, packed)))) - } - } - - function _operationStateOptimized(uint256 packed, uint256 blockTimestamp) - internal - pure - returns (uint256 result) - { - /// @solidity memory-safe-assembly - assembly { - let p := packed - let t := blockTimestamp - result := mul(iszero(iszero(p)), add(and(p, 1), sub(2, lt(t, shr(1, p))))) - } - } - - function _isOperationPendingOriginal(uint256 packed, uint256 blockTimestamp) - internal - pure - returns (bool) - { - return _operationStateOriginal(packed, blockTimestamp) == Timelock.OperationState.Waiting - || _operationStateOriginal(packed, blockTimestamp) == Timelock.OperationState.Ready; - } - - function _isOperationDoneOriginal(uint256 packed, uint256 blockTimestamp) - internal - pure - returns (bool) - { - return _operationStateOriginal(packed, blockTimestamp) == Timelock.OperationState.Done; - } - - function _isOperationReadyOriginal(uint256 packed, uint256 blockTimestamp) - internal - pure - returns (bool) - { - return _operationStateOriginal(packed, blockTimestamp) == Timelock.OperationState.Ready; - } - - function _operationStateOriginal(uint256 packed, uint256 blockTimestamp) - internal - pure - returns (Timelock.OperationState) - { - if (packed == uint256(0)) return Timelock.OperationState.Unset; - if (packed & 1 == 1) return Timelock.OperationState.Done; - if (packed >> 1 > blockTimestamp) return Timelock.OperationState.Waiting; - return Timelock.OperationState.Ready; - } - - function testDelayRestriction(uint256 minDelay, uint256 delay, uint256 blockTimestamp) - public - pure - { - check_DelayRestriction(minDelay, delay, blockTimestamp); - } - - function check_DelayRestriction(uint256 minDelay, uint256 delay, uint256 blockTimestamp) - public - pure - { - uint256 upper = 2 ** 254 - 1; - minDelay = minDelay & upper; - if (delay < minDelay) delay = minDelay; - else delay = delay & upper; - blockTimestamp = blockTimestamp & (2 ** 64 - 1); - uint256 readyTimestamp = delay + blockTimestamp; - assert(readyTimestamp <= 2 ** 255 - 1); - } - - function _id(bytes memory executionData) internal pure returns (bytes32) { - return keccak256(abi.encode(_SUPPORTED_MODE, keccak256(executionData))); - } -} diff --git a/grouperBot/lib/solady/test/UUPSUpgradeable.t.sol b/grouperBot/lib/solady/test/UUPSUpgradeable.t.sol deleted file mode 100644 index 9b8c44e..0000000 --- a/grouperBot/lib/solady/test/UUPSUpgradeable.t.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {CallContextChecker, UUPSUpgradeable} from "../src/utils/UUPSUpgradeable.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; -import {MockUUPSImplementation} from "../test/utils/mocks/MockUUPSImplementation.sol"; - -contract UUPSUpgradeableTest is SoladyTest { - MockUUPSImplementation impl1; - - address proxy; - - bytes32 internal constant _ERC1967_IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - event Upgraded(address indexed implementation); - - function setUp() public { - impl1 = new MockUUPSImplementation(); - proxy = LibClone.deployERC1967(address(impl1)); - MockUUPSImplementation(proxy).initialize(address(this)); - } - - function testUpgradeTo() public { - MockUUPSImplementation impl2 = new MockUUPSImplementation(); - vm.expectEmit(true, true, true, true); - emit Upgraded(address(impl2)); - MockUUPSImplementation(proxy).upgradeToAndCall(address(impl2), bytes("")); - bytes32 v = vm.load(proxy, _ERC1967_IMPLEMENTATION_SLOT); - assertEq(address(uint160(uint256(v))), address(impl2)); - } - - function testUpgradeToRevertWithUnauthorized() public { - vm.prank(address(0xBEEF)); - vm.expectRevert(MockUUPSImplementation.Unauthorized.selector); - MockUUPSImplementation(proxy).upgradeToAndCall(address(0xABCD), bytes("")); - } - - function testUpgradeToRevertWithUpgradeFailed() public { - vm.expectRevert(UUPSUpgradeable.UpgradeFailed.selector); - MockUUPSImplementation(proxy).upgradeToAndCall(address(0xABCD), bytes("")); - } - - function testUpgradeToAndCall() public { - MockUUPSImplementation impl2 = new MockUUPSImplementation(); - bytes memory data = abi.encodeWithSignature("setValue(uint256)", 5); - MockUUPSImplementation(proxy).upgradeToAndCall(address(impl2), data); - bytes32 v = vm.load(proxy, _ERC1967_IMPLEMENTATION_SLOT); - assertEq(address(uint160(uint256(v))), address(impl2)); - assertEq(MockUUPSImplementation(proxy).value(), 5); - } - - function testUpgradeToAndCallRevertWithUpgradeFailed() public { - vm.expectRevert(UUPSUpgradeable.UpgradeFailed.selector); - MockUUPSImplementation(proxy).upgradeToAndCall(address(0xABCD), ""); - } - - function testUpgradeToAndCallRevertWithCustomError() public { - MockUUPSImplementation impl2 = new MockUUPSImplementation(); - bytes memory data = abi.encodeWithSignature("revertWithError()"); - vm.expectRevert( - abi.encodeWithSelector(MockUUPSImplementation.CustomError.selector, address(this)) - ); - MockUUPSImplementation(proxy).upgradeToAndCall(address(impl2), data); - } - - function testUpgradeToAndCallRevertWithUnauthorized() public { - vm.prank(address(0xBEEF)); - vm.expectRevert(MockUUPSImplementation.Unauthorized.selector); - MockUUPSImplementation(proxy).upgradeToAndCall(address(0xABCD), ""); - } -} diff --git a/grouperBot/lib/solady/test/UpgradeableBeacon.t.sol b/grouperBot/lib/solady/test/UpgradeableBeacon.t.sol deleted file mode 100644 index 57bab0a..0000000 --- a/grouperBot/lib/solady/test/UpgradeableBeacon.t.sol +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {UpgradeableBeacon} from "../src/utils/UpgradeableBeacon.sol"; -import {MockImplementation} from "./utils/mocks/MockImplementation.sol"; -import {LibClone} from "../src/utils/LibClone.sol"; - -library UpgradeableBeaconTestLib { - function deploySolidityBeacon(address initialOwner, address initialImplementation) - internal - returns (address) - { - return address(new UpgradeableBeacon(initialOwner, initialImplementation)); - } - - function deployYulBeacon(address initialOwner, address initialImplementation) - internal - returns (address) - { - bytes memory creationCode = - hex"60406101c73d393d5160205180821760a01c3d3d3e803b1560875781684343a0dc92ed22dbfc558068911c5a209f08d5ec5e557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b3d38a23d7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e03d38a3610132806100953d393df35b636d3e283b3d526004601cfdfe3d3560e01c635c60da1b14610120573d3560e01c80638da5cb5b1461010e5780633659cfe61460021b8163f2fde38b1460011b179063715018a6141780153d3d3e684343a0dc92ed22dbfc805490813303610101573d9260068116610089575b508290557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e03d38a3005b925060048035938460a01c60243610173d3d3e146100ba5782156100ad573861005f565b637448fbae3d526004601cfd5b82803b156100f4578068911c5a209f08d5ec5e557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b3d38a2005b636d3e283b3d526004601cfd5b6382b429003d526004601cfd5b684343a0dc92ed22dbfc543d5260203df35b68911c5a209f08d5ec5e543d5260203df3"; - bytes memory initcode = - abi.encodePacked(creationCode, abi.encode(initialOwner, initialImplementation)); - address result; - /// @solidity memory-safe-assembly - assembly { - result := create(0, add(0x20, initcode), mload(initcode)) - } - return result; - } -} - -contract UpgradeableBeaconTest is SoladyTest { - event Upgraded(address indexed implementation); - event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); - - address implementation; - UpgradeableBeacon beacon; - - bytes32 internal constant _ERC1967_BEACON_SLOT = - 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; - - function setUp() public { - implementation = address(new MockImplementation()); - } - - function _deploySolidityBeacon(address initialOwner, address initialImplementation) internal { - beacon = UpgradeableBeacon( - UpgradeableBeaconTestLib.deploySolidityBeacon(initialOwner, initialImplementation) - ); - } - - function _deploySolidityBeacon() internal { - _deploySolidityBeacon(address(this), implementation); - } - - function _deployYulBeacon(address initialOwner, address initialImplementation) internal { - beacon = UpgradeableBeacon( - UpgradeableBeaconTestLib.deployYulBeacon(initialOwner, initialImplementation) - ); - } - - function _deployYulBeacon() internal { - _deployYulBeacon(address(this), implementation); - } - - function _deployBeacon() internal { - if (_randomChance(2)) { - _deployYulBeacon(); - } else { - _deploySolidityBeacon(); - } - } - - function testInitializeUpgradeableSolidityBeacon() public { - address initialOwner = address(this); - vm.expectRevert(UpgradeableBeacon.NewImplementationHasNoCode.selector); - _deploySolidityBeacon(initialOwner, address(0)); - - vm.expectEmit(true, true, true, true); - emit Upgraded(address(implementation)); - emit OwnershipTransferred(address(0), initialOwner); - _deploySolidityBeacon(initialOwner, implementation); - } - - function testInitializeUpgradeableYulBeacon() public { - address initialOwner; - vm.expectRevert(UpgradeableBeacon.NewOwnerIsZeroAddress.selector); - _deployYulBeacon(initialOwner, implementation); - - initialOwner = address(this); - vm.expectRevert(UpgradeableBeacon.NewImplementationHasNoCode.selector); - _deployYulBeacon(initialOwner, address(0)); - - vm.expectEmit(true, true, true, true); - emit Upgraded(address(implementation)); - emit OwnershipTransferred(address(0), initialOwner); - _deployYulBeacon(initialOwner, implementation); - } - - function _testUpgradeableBeaconOnlyOwnerFunctions(address pranker, address newImplementation) - internal - { - vm.startPrank(pranker); - vm.expectRevert(UpgradeableBeacon.Unauthorized.selector); - beacon.transferOwnership(address(123)); - vm.expectRevert(UpgradeableBeacon.Unauthorized.selector); - beacon.renounceOwnership(); - vm.expectRevert(UpgradeableBeacon.Unauthorized.selector); - beacon.upgradeTo(newImplementation); - vm.stopPrank(); - } - - function _testUpgradeableBeaconOnlyOwnerFunctions() internal { - _testUpgradeableBeaconOnlyOwnerFunctions(_randomNonZeroAddress(), implementation); - } - - function testUpgradeableSolidityBeaconOnlyOwnerFunctions() public { - _deploySolidityBeacon(); - _testUpgradeableBeaconOnlyOwnerFunctions(); - } - - function testUpgradeableYulBeaconOnlyOwnerFunctions() public { - _deployYulBeacon(); - _testUpgradeableBeaconOnlyOwnerFunctions(); - } - - function testUpgradeableBeacon(uint256) public { - _deployBeacon(); - assertEq(beacon.owner(), address(this)); - - address newOwner = _randomNonZeroAddress(); - - if (_randomChance(32)) { - _testUpgradeableBeaconOnlyOwnerFunctions(); - } - - if (_randomChance(16)) { - vm.expectRevert(UpgradeableBeacon.NewOwnerIsZeroAddress.selector); - beacon.transferOwnership(address(0)); - } - - if (_randomChance(16)) { - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(address(this), address(0)); - beacon.renounceOwnership(); - assertEq(beacon.owner(), address(0)); - } - - if (beacon.owner() != address(0) && _randomChance(2)) { - emit OwnershipTransferred(address(this), newOwner); - beacon.transferOwnership(newOwner); - assertEq(beacon.owner(), newOwner); - - if (_randomChance(2)) { - _testUpgradeableBeaconOnlyOwnerFunctions(address(this), implementation); - } - - vm.prank(newOwner); - emit OwnershipTransferred(newOwner, address(this)); - beacon.transferOwnership(address(this)); - assertEq(beacon.owner(), address(this)); - } - - if (beacon.owner() != address(0) && _randomChance(2)) { - assertEq(beacon.implementation(), implementation); - - address newImplementation; - if (_randomChance(2)) { - newImplementation = LibClone.clone(implementation); - } - if (newImplementation == address(0)) { - vm.expectRevert(UpgradeableBeacon.NewImplementationHasNoCode.selector); - beacon.upgradeTo(newImplementation); - assertEq(beacon.implementation(), implementation); - } - if (newImplementation != address(0)) { - emit Upgraded(newImplementation); - beacon.upgradeTo(newImplementation); - assertEq(beacon.implementation(), newImplementation); - } - } - } - - function testUpgradeableYulBeaconOnlyFnSelectorNotRecognised() public { - _deployYulBeacon(); - vm.expectRevert(); - UpgradeableBeaconTest(address(beacon)).testUpgradeableYulBeaconOnlyFnSelectorNotRecognised(); - } - - function testUpgradeableSolidityBeaconOnlyFnSelectorNotRecognised() public { - _deploySolidityBeacon(); - vm.expectRevert(); - UpgradeableBeaconTest(address(beacon)).testUpgradeableYulBeaconOnlyFnSelectorNotRecognised(); - } -} diff --git a/grouperBot/lib/solady/test/WETH.t.sol b/grouperBot/lib/solady/test/WETH.t.sol deleted file mode 100644 index f88bc39..0000000 --- a/grouperBot/lib/solady/test/WETH.t.sol +++ /dev/null @@ -1,169 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import "./utils/InvariantTest.sol"; - -import {SafeTransferLib} from "../src/utils/SafeTransferLib.sol"; - -import {WETH} from "../src/tokens/WETH.sol"; - -contract ContractWithoutReceive {} - -contract WETHTest is SoladyTest { - WETH weth; - - function setUp() public { - weth = new WETH(); - } - - function testMetadata() public { - assertEq(weth.name(), "Wrapped Ether"); - assertEq(weth.symbol(), "WETH"); - assertEq(weth.decimals(), 18); - } - - function testFallbackDeposit() public { - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - SafeTransferLib.safeTransferETH(address(weth), 1 ether); - - assertEq(weth.balanceOf(address(this)), 1 ether); - assertEq(weth.totalSupply(), 1 ether); - } - - function testDeposit() public { - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - weth.deposit{value: 1 ether}(); - - assertEq(weth.balanceOf(address(this)), 1 ether); - assertEq(weth.totalSupply(), 1 ether); - } - - function testWithdraw() public { - uint256 startingBalance = address(this).balance; - - weth.deposit{value: 1 ether}(); - - weth.withdraw(1 ether); - - uint256 balanceAfterWithdraw = address(this).balance; - - assertEq(balanceAfterWithdraw, startingBalance); - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - } - - function testPartialWithdraw() public { - weth.deposit{value: 1 ether}(); - - uint256 balanceBeforeWithdraw = address(this).balance; - - weth.withdraw(0.5 ether); - - uint256 balanceAfterWithdraw = address(this).balance; - - assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + 0.5 ether); - assertEq(weth.balanceOf(address(this)), 0.5 ether); - assertEq(weth.totalSupply(), 0.5 ether); - } - - function testWithdrawToContractWithoutReceiveReverts() public { - address owner = address(new ContractWithoutReceive()); - - vm.deal(owner, 1 ether); - - vm.prank(owner); - weth.deposit{value: 1 ether}(); - - assertEq(weth.balanceOf(owner), 1 ether); - - vm.expectRevert(WETH.ETHTransferFailed.selector); - vm.prank(owner); - weth.withdraw(1 ether); - } - - function testFallbackDeposit(uint256 amount) public { - amount = _bound(amount, 0, address(this).balance); - - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - SafeTransferLib.safeTransferETH(address(weth), amount); - - assertEq(weth.balanceOf(address(this)), amount); - assertEq(weth.totalSupply(), amount); - } - - function testDeposit(uint256 amount) public { - amount = _bound(amount, 0, address(this).balance); - - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - weth.deposit{value: amount}(); - - assertEq(weth.balanceOf(address(this)), amount); - assertEq(weth.totalSupply(), amount); - } - - function testWithdraw(uint256 depositAmount, uint256 withdrawAmount) public { - depositAmount = _bound(depositAmount, 0, address(this).balance); - withdrawAmount = _bound(withdrawAmount, 0, depositAmount); - - weth.deposit{value: depositAmount}(); - - uint256 balanceBeforeWithdraw = address(this).balance; - - weth.withdraw(withdrawAmount); - - uint256 balanceAfterWithdraw = address(this).balance; - - assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + withdrawAmount); - assertEq(weth.balanceOf(address(this)), depositAmount - withdrawAmount); - assertEq(weth.totalSupply(), depositAmount - withdrawAmount); - } - - receive() external payable {} -} - -contract WETHInvariants is SoladyTest, InvariantTest { - WETHTester wethTester; - WETH weth; - - function setUp() public { - weth = new WETH(); - wethTester = new WETHTester{value: address(this).balance}(weth); - - _addTargetContract(address(wethTester)); - } - - function invariantTotalSupplyEqualsBalance() public { - assertEq(address(weth).balance, weth.totalSupply()); - } -} - -contract WETHTester { - WETH weth; - - constructor(WETH _weth) payable { - weth = _weth; - } - - function deposit(uint256 amount) public { - weth.deposit{value: amount}(); - } - - function fallbackDeposit(uint256 amount) public { - SafeTransferLib.safeTransferETH(address(weth), amount); - } - - function withdraw(uint256 amount) public { - weth.withdraw(amount); - } - - receive() external payable {} -} diff --git a/grouperBot/lib/solady/test/WebAuthn.t.sol b/grouperBot/lib/solady/test/WebAuthn.t.sol deleted file mode 100644 index 05042ba..0000000 --- a/grouperBot/lib/solady/test/WebAuthn.t.sol +++ /dev/null @@ -1,249 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./utils/SoladyTest.sol"; -import {P256VerifierEtcher} from "./P256.t.sol"; -import {LibString} from "../src/utils/LibString.sol"; -import {Base64} from "../src/utils/Base64.sol"; -import {WebAuthn} from "../src/utils/WebAuthn.sol"; - -contract WebAuthnTest is P256VerifierEtcher { - function verify( - bytes memory challenge, - bool requireUserVerification, - WebAuthn.WebAuthnAuth memory webAuthnAuth, - bytes32 x, - bytes32 y - ) public virtual returns (bool) { - return WebAuthn.verify(challenge, requireUserVerification, webAuthnAuth, x, y); - } - - struct _TestTemps { - bytes32 x; - bytes32 y; - bytes challenge; - } - - function _testTemps() internal virtual returns (_TestTemps memory t) { - t.x = 0x3f2be075ef57d6c8374ef412fe54fdd980050f70f4f3a00b5b1b32d2def7d28d; - t.y = 0x57095a365acc2590ade3583fabfe8fbd64a9ed3ec07520da00636fb21f0176c1; - t.challenge = abi.encode(0xf631058a3ba1116acce12396fad0a125b5041c43f8e15723709f81aa8d5f4ccf); - } - - function testSafari() public { - _etchRIPPrecompile(true); - _etchVerifier(true); - _TestTemps memory t = _testTemps(); - WebAuthn.WebAuthnAuth memory auth; - auth.authenticatorData = - hex"49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000101"; - auth.clientDataJSON = string( - abi.encodePacked( - '{"type":"webauthn.get","challenge":"', - Base64.encode(t.challenge, true, true), - '","origin":"http://localhost:3005"}' - ) - ); - auth.challengeIndex = 23; - auth.typeIndex = 1; - auth.r = 0x60946081650523acad13c8eff94996a409b1ed60e923c90f9e366aad619adffa; - auth.s = 0x3216a237b73765d01b839e0832d73474bc7e63f4c86ef05fbbbfbeb34b35602b; - assertTrue(WebAuthn.verify(t.challenge, false, auth, t.x, t.y)); - } - - function testChrome() public { - _etchRIPPrecompile(true); - _etchVerifier(true); - _TestTemps memory t = _testTemps(); - WebAuthn.WebAuthnAuth memory auth; - auth.authenticatorData = - hex"49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763050000010a"; - auth.clientDataJSON = string( - abi.encodePacked( - '{"type":"webauthn.get","challenge":"', - Base64.encode(t.challenge, true, true), - '","origin":"http://localhost:3005","crossOrigin":false}' - ) - ); - auth.challengeIndex = 23; - auth.typeIndex = 1; - auth.r = 0x41c01ca5ecdfeb23ef70d6cc216fd491ac3aa3d40c480751f3618a3a9ef67b41; - auth.s = 0x6595569abf76c2777e832a9252bae14efdb77febd0fa3b919aa16f6208469e86; - assertTrue(WebAuthn.verify(t.challenge, false, auth, t.x, t.y)); - } - - function testPassthroughDifferential(bytes32) public { - _etchVerifierPassthrough(true); - _etchRIPPrecompilePassthrough(true); - - bytes memory challenge = _sampleRandomUniformShortBytes(); - WebAuthn.WebAuthnAuth memory auth; - auth.authenticatorData = _sampleRandomUniformShortBytes(); - auth.clientDataJSON = _sampleClientDataJSON(challenge); - auth.challengeIndex = _sampleChallengeIndex(auth.clientDataJSON); - auth.typeIndex = _sampleTypeIndex(auth.clientDataJSON); - bool requireUserVerification = _randomChance(2); - assertEq( - WebAuthn.verify(challenge, requireUserVerification, auth, 0, 0), - _verifyPassthroughOriginal(challenge, requireUserVerification, auth) - ); - } - - bytes1 private constant _AUTH_DATA_FLAGS_UP = 0x01; - bytes1 private constant _AUTH_DATA_FLAGS_UV = 0x04; - bytes32 private constant _EXPECTED_TYPE_HASH = keccak256('"type":"webauthn.get"'); - - function _verifyPassthroughOriginal( - bytes memory challenge, - bool requireUserVerification, - WebAuthn.WebAuthnAuth memory webAuthnAuth - ) internal pure returns (bool) { - string memory t = LibString.slice( - webAuthnAuth.clientDataJSON, webAuthnAuth.typeIndex, webAuthnAuth.typeIndex + 21 - ); - if (keccak256(bytes(t)) != _EXPECTED_TYPE_HASH) { - return false; - } - bytes memory expectedChallenge = - abi.encodePacked('"challenge":"', Base64.encode(challenge, true, true), '"'); - string memory actualChallenge = LibString.slice( - webAuthnAuth.clientDataJSON, - webAuthnAuth.challengeIndex, - webAuthnAuth.challengeIndex + expectedChallenge.length - ); - if (keccak256(bytes(actualChallenge)) != keccak256(expectedChallenge)) { - return false; - } - - if (webAuthnAuth.authenticatorData.length <= 32) return false; - - if (webAuthnAuth.authenticatorData[32] & _AUTH_DATA_FLAGS_UP != _AUTH_DATA_FLAGS_UP) { - return false; - } - if ( - requireUserVerification - && (webAuthnAuth.authenticatorData[32] & _AUTH_DATA_FLAGS_UV) != _AUTH_DATA_FLAGS_UV - ) { - return false; - } - return true; - } - - function _sampleClientDataJSON(bytes memory challenge) internal returns (string memory) { - return string( - abi.encodePacked( - "{", - _sampleRandomUniformShortBytes(), - _maybeReturnEmpty('"type":"webauthn.get"'), - _sampleRandomUniformShortBytes(), - _maybeReturnEmpty(',"challenge":"'), - Base64.encode(challenge, true, true), - _maybeReturnEmpty(abi.encodePacked('"', _sampleRandomUniformShortBytes(), "}")) - ) - ); - } - - function _maybeReturnEmpty(bytes memory s) internal returns (bytes memory result) { - if (!_randomChance(4)) result = s; - } - - function _sampleChallengeIndex(string memory clientDataJSON) - internal - returns (uint256 result) - { - if (!_randomChance(4)) { - result = LibString.indexOf(clientDataJSON, '"challenge":"'); - if (result <= 0xffffffff) return result; - } - unchecked { - result = _bound(_randomUniform(), 0, bytes(clientDataJSON).length + 35); - } - } - - function _sampleTypeIndex(string memory clientDataJSON) internal returns (uint256 result) { - if (!_randomChance(4)) { - result = LibString.indexOf(clientDataJSON, '"type":"webauthn.get"'); - if (result <= 0xffffffff) return result; - } - unchecked { - result = _bound(_randomUniform(), 0, bytes(clientDataJSON).length + 35); - } - } - - function _sampleRandomUniformShortBytes() internal returns (bytes memory result) { - uint256 n = _randomUniform(); - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - switch and(0xf, byte(0, n)) - case 0 { n := and(n, 0x3f) } - default { n := and(n, 0x3) } - result := mload(0x40) - mstore(result, n) - mstore(add(0x20, result), r) - mstore(add(0x40, result), keccak256(result, 0x40)) - mstore(0x40, add(result, 0x80)) - } - } - - function testTryDecodeAuth(bytes32) public { - WebAuthn.WebAuthnAuth memory auth; - auth.authenticatorData = _sampleRandomUniformShortBytes(); - auth.clientDataJSON = string(_sampleRandomUniformShortBytes()); - auth.challengeIndex = _randomUniform(); - auth.typeIndex = _randomUniform(); - auth.r = bytes32(_randomUniform()); - auth.s = bytes32(_randomUniform()); - bytes memory encoded = abi.encode(auth); - WebAuthn.WebAuthnAuth memory decoded = WebAuthn.tryDecodeAuth(encoded); - assertEq(decoded.authenticatorData, auth.authenticatorData); - assertEq(decoded.clientDataJSON, auth.clientDataJSON); - assertEq(decoded.challengeIndex, auth.challengeIndex); - assertEq(decoded.typeIndex, auth.typeIndex); - assertEq(decoded.r, auth.r); - assertEq(decoded.s, auth.s); - } - - function testTryDecodeAuthCompact(bytes32) public { - WebAuthn.WebAuthnAuth memory auth; - auth.authenticatorData = _sampleRandomUniformShortBytes(); - auth.clientDataJSON = string(_sampleRandomUniformShortBytes()); - auth.challengeIndex = uint16(_randomUniform()); - auth.typeIndex = uint16(_randomUniform()); - auth.r = bytes32(_randomUniform()); - auth.s = bytes32(_randomUniform()); - bytes memory encoded = WebAuthn.tryEncodeAuthCompact(auth); - assertEq( - encoded, - abi.encodePacked( - uint16(auth.authenticatorData.length), - bytes(auth.authenticatorData), - bytes(auth.clientDataJSON), - uint16(auth.challengeIndex), - uint16(auth.typeIndex), - bytes32(auth.r), - bytes32(auth.s) - ) - ); - WebAuthn.WebAuthnAuth memory decoded; - if (_randomChance(2)) { - decoded = WebAuthn.tryDecodeAuthCompact(encoded); - } else { - decoded = this.tryDecodeAuthCompactCalldata(encoded); - } - assertEq(decoded.authenticatorData, auth.authenticatorData); - assertEq(decoded.clientDataJSON, auth.clientDataJSON); - assertEq(decoded.challengeIndex, auth.challengeIndex); - assertEq(decoded.typeIndex, auth.typeIndex); - assertEq(decoded.r, auth.r); - assertEq(decoded.s, auth.s); - } - - function tryDecodeAuthCompactCalldata(bytes calldata encoded) - public - pure - returns (WebAuthn.WebAuthnAuth memory) - { - return WebAuthn.tryDecodeAuthCompactCalldata(encoded); - } -} diff --git a/grouperBot/lib/solady/test/data/wycheproof.jsonl b/grouperBot/lib/solady/test/data/wycheproof.jsonl deleted file mode 100644 index eb6dd5b..0000000 --- a/grouperBot/lib/solady/test/data/wycheproof.jsonl +++ /dev/null @@ -1,778 +0,0 @@ -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #1: signature malleability"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #3: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #5: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #8: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #9: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #10: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #11: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #12: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #13: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #14: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #15: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #16: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #17: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #18: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #19: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #20: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #21: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #22: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #23: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #24: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #25: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #26: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #27: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #28: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #29: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #30: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #31: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #32: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #33: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #34: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #35: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #36: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #37: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #38: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #39: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #40: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #41: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #42: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #43: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #44: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #45: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #46: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #47: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #48: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #49: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #50: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #51: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #52: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #53: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #54: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #55: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #56: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #57: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"64a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e","s":"6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b","hash":"70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f807","valid":true,"msg":"3639383139","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #58: Edge case for Shamir multiplication"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"16aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266","s":"252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e9","hash":"00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a9","valid":true,"msg":"343236343739373234","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #59: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882","s":"093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c32","hash":"7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d91","valid":true,"msg":"37313338363834383931","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #60: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"73b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa43","s":"2f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c88634","hash":"ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe06045","valid":true,"msg":"3130333539333331363638","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #61: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3dd","s":"bdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b","hash":"67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0","valid":true,"msg":"33393439343031323135","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #62: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd","s":"51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b52","hash":"a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf","valid":true,"msg":"31333434323933303739","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #63: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa03","s":"99ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c7","hash":"3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65","valid":true,"msg":"33373036323131373132","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #64: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b","s":"8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d3610","hash":"9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c","valid":true,"msg":"333433363838373132","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #65: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831d","s":"b26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e9902","hash":"883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae0186","valid":true,"msg":"31333531353330333730","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #66: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b7","s":"20aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c","hash":"a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6","valid":true,"msg":"36353533323033313236","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #67: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db9","s":"3df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d21350","hash":"8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054","valid":true,"msg":"31353634333436363033","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #68: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675","s":"d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff2","hash":"660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305","valid":true,"msg":"34343239353339313137","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #69: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"3b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a8","s":"4c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d99258","hash":"d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c34","valid":true,"msg":"3130393533323631333531","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #70: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf","s":"47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed","hash":"bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f","valid":true,"msg":"35393837333530303431","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #71: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"38686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52","s":"067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d","hash":"33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a73","valid":true,"msg":"33343633303036383738","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #72: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"44a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf","s":"2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e86","hash":"b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf1","valid":true,"msg":"39383137333230323837","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #73: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e9","s":"7d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f9","hash":"01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a","valid":true,"msg":"33323232303431303436","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #74: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8f","s":"f6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c7","hash":"9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363","valid":true,"msg":"36363636333037313034","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #75: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6","s":"d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab244726","hash":"d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c","valid":true,"msg":"31303335393531383938","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #76: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d","s":"3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef","hash":"307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14","valid":true,"msg":"31383436353937313935","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #77: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7a","s":"c60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c5021","hash":"bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b8","valid":true,"msg":"33313336303436313839","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #78: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d","s":"9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f00","hash":"d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15e","valid":true,"msg":"32363633373834323534","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #79: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e","s":"7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a19878","hash":"79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e1","valid":true,"msg":"31363532313030353234","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #80: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c59","s":"2ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd","hash":"8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda","valid":true,"msg":"35373438303831363936","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #81: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c9466","s":"65d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc3","hash":"0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b21","valid":true,"msg":"36333433393133343638","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #82: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107","s":"cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf7592767","hash":"e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d","valid":true,"msg":"31353431313033353938","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #83: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"6554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728","s":"aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f929","hash":"9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de1","valid":true,"msg":"3130343738353830313238","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #84: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfc","s":"e99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d","hash":"62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15","valid":true,"msg":"3130353336323835353638","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #85: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf","s":"7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf919622","hash":"3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8","valid":true,"msg":"393533393034313035","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #86: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e","s":"0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa4","hash":"0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c800000000","valid":true,"msg":"393738383438303339","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #87: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba6","s":"5e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c65424339","hash":"ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289a","valid":true,"msg":"33363130363732343432","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #88: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88","s":"737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f","hash":"7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7","valid":true,"msg":"31303534323430373035","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #89: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa","s":"6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a","hash":"a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395","valid":true,"msg":"35313734343438313937","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #90: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad2","s":"42c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d693","hash":"641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0","valid":true,"msg":"31393637353631323531","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #91: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b2","s":"9d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e","hash":"958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b","valid":true,"msg":"33343437323533333433","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #92: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8","s":"e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c89","hash":"f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8","valid":true,"msg":"333638323634333138","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #93: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443","s":"e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a1939123","hash":"0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def","valid":true,"msg":"33323631313938363038","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #94: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad","s":"1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c6","hash":"60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589","valid":true,"msg":"39363738373831303934","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #95: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"4a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb","s":"3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc5981725782","hash":"c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e2","valid":true,"msg":"34393538383233383233","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #96: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"eacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e96","s":"7451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d1","hash":"de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68d","valid":true,"msg":"383234363337383337","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #97: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052","s":"ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c","hash":"6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff","valid":true,"msg":"3131303230383333373736","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #98: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b3300219","s":"79938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a","hash":"cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9","valid":true,"msg":"313333383731363438","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #99: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"81f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8","s":"cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f74300","hash":"2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb0484","valid":true,"msg":"333232313434313632","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #100: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808","s":"048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e7","hash":"ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411","valid":true,"msg":"3130363836363535353436","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #101: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a5762","s":"93320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c199345","hash":"4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610","valid":true,"msg":"3632313535323436","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #102: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883","s":"f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a8","hash":"422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75a","valid":true,"msg":"37303330383138373734","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #103: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f7","s":"6b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db55","hash":"7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018","valid":true,"msg":"35393234353233373434","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #104: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0","s":"918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b2443","hash":"3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95","valid":true,"msg":"31343935353836363231","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #105: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a3","s":"1dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f49584389772","hash":"de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b","valid":true,"msg":"34303035333134343036","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #106: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff11","s":"45b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d75","hash":"8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c","valid":true,"msg":"33303936343537353132","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #107: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06f","s":"b1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c20","hash":"6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca8","valid":true,"msg":"32373834303235363230","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #108: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32e","s":"db1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c","hash":"fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e","valid":true,"msg":"32363138373837343138","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #109: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a","s":"3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c","hash":"1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a","valid":true,"msg":"31363432363235323632","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #110: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5","s":"249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b","hash":"08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e","valid":true,"msg":"36383234313839343336","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #111: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348","s":"fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea","hash":"d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff","valid":true,"msg":"343834323435343235","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #112: special case hash"} -{"x":"0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103","y":"c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e","r":"000000000000000000000000000000004319055358e8617b0c46353d039cdaab","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #113: k*G has a large x-coordinate"} -{"x":"0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103","y":"c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e","r":"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #114: r too large"} -{"x":"ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c582204554","y":"19235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #115: r,s are large"} -{"x":"80984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c56","y":"11feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd4","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #116: r and s^-1 have a large Hamming weight"} -{"x":"4201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c05","y":"95c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #117: r and s^-1 have a large Hamming weight"} -{"x":"a71af64de5126a4a4e02b7922d66ce9415ce88a4c9d25514d91082c8725ac957","y":"5d47723c8fbe580bb369fec9c2665d8e30a435b9932645482e7c9f11e872296b","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #118: small r and s"} -{"x":"6627cec4f0731ea23fc2931f90ebe5b7572f597d20df08fc2b31ee8ef16b1572","y":"6170ed77d8d0a14fc5c9c3c4c9be7f0d3ee18f709bb275eaf2073e258fe694a5","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000003","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #120: small r and s"} -{"x":"5a7c8825e85691cce1f5e7544c54e73f14afc010cb731343262ca7ec5a77f5bf","y":"ef6edf62a4497c1bd7b147fb6c3d22af3c39bfce95f30e13a16d3d7b2812f813","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000005","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #122: small r and s"} -{"x":"cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c737","y":"70af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000006","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #124: small r and s"} -{"x":"cbe0c29132cd738364fedd603152990c048e5e2fff996d883fa6caca7978c737","y":"70af6a8ce44cb41224b2603606f4c04d188e80bff7cc31ad5189d4ab0d70e8c1","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632556","s":"0000000000000000000000000000000000000000000000000000000000000006","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #126: r is larger than n"} -{"x":"4be4178097002f0deab68f0d9a130e0ed33a6795d02a20796db83444b037e139","y":"20f13051e0eecdcfce4dacea0f50d1f247caa669f193c1b4075b51ae296d2d56","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc75fbd8","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #127: s is larger than n"} -{"x":"d0f73792203716afd4be4329faa48d269f15313ebbba379d7783c97bf3e890d9","y":"971f4a3206605bec21782bf5e275c714417e8f566549e6bc68690d2363c89cc1","r":"0000000000000000000000000000000000000000000000000000000000000100","s":"8f1e3c7862c58b16bb76eddbb76eddbb516af4f63f2d74d76e0d28c9bb75ea88","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #128: small r and s^-1"} -{"x":"4838b2be35a6276a80ef9e228140f9d9b96ce83b7a254f71ccdebbb8054ce05f","y":"fa9cbc123c919b19e00238198d04069043bd660a828814051fcb8aac738a6c6b","r":"000000000000000000000000000000000000000000000000002d9b4d347952d6","s":"ef3043e7329581dbb3974497710ab11505ee1c87ff907beebadd195a0ffe6d7a","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #129: smallish r and s^-1"} -{"x":"7393983ca30a520bbc4783dc9960746aab444ef520c0a8e771119aa4e74b0f64","y":"e9d7be1ab01a0bf626e709863e6a486dbaf32793afccf774e2c6cd27b1857526","r":"000000000000000000000000000000000000001033e67e37b32b445580bf4eff","s":"8b748b74000000008b748b748b748b7466e769ad4a16d3dcd87129b8e91d1b4d","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #130: 100-bit r and small s^-1"} -{"x":"5ac331a1103fe966697379f356a937f350588a05477e308851b8a502d5dfcdc5","y":"fe9993df4b57939b2b8da095bf6d794265204cfe03be995a02e65d408c871c0b","r":"0000000000000000000000000000000000000000000000000000000000000100","s":"ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #131: small r and 100 bit s^-1"} -{"x":"1d209be8de2de877095a399d3904c74cc458d926e27bb8e58e5eae5767c41509","y":"dd59e04c214f7b18dce351fc2a549893a6860e80163f38cc60a4f2c9d040d8c9","r":"00000000000000000000000000000000000000062522bbd3ecbe7c39e93e7c25","s":"ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #132: 100-bit r and s^-1"} -{"x":"083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99","y":"915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #133: r and s^-1 are close to n"} -{"x":"8aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e19373874","y":"05bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #134: s == 1"} -{"x":"8aeb368a7027a4d64abdea37390c0c1d6a26f399e2d9734de1eb3d0e19373874","y":"05bd13834715e1dbae9b875cf07bd55e1b6691c7f7536aef3b19bf7a4adf576d","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #135: s == 0"} -{"x":"b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f287","y":"1b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #136: point at infinity during verify"} -{"x":"f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86","y":"f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #137: edge case for signature malleability"} -{"x":"68ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d946","y":"97bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #138: edge case for signature malleability"} -{"x":"69da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b8","y":"66d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #139: u1 == 1"} -{"x":"d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff32","y":"33e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #140: u1 == n - 1"} -{"x":"3623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab785","y":"8db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #141: u2 == 1"} -{"x":"cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1","y":"e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #142: u2 == n - 1"} -{"x":"db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff77350","y":"4f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"e91e1ba60fdedb76a46bcb51dc0b8b4b7e019f0a28721885fa5d3a8196623397","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #143: edge case for u1"} -{"x":"dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f","y":"1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"fdea5843ffeb73af94313ba4831b53fe24f799e525b1e8e8c87b59b95b430ad9","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #144: edge case for u1"} -{"x":"d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9","y":"986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"03ffcabf2f1b4d2a65190db1680d62bb994e41c5251cd73b3c3dfc5e5bafc035","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #145: edge case for u1"} -{"x":"a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c32","y":"6337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"4dfbc401f971cd304b33dfdb17d0fed0fe4c1a88ae648e0d2847f74977534989","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #146: edge case for u1"} -{"x":"c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b7","y":"3877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bc4024761cd2ffd43dfdb17d0fed112b988977055cd3a8e54971eba9cda5ca71","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #147: edge case for u1"} -{"x":"5eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e","y":"5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"788048ed39a5ffa77bfb62fa1fda2257742bf35d128fb3459f2a0c909ee86f91","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #148: edge case for u1"} -{"x":"5caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47a","y":"deb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"476d9131fd381bd917d0fed112bc9e0a5924b5ed5b11167edd8b23582b3cb15e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #149: edge case for u1"} -{"x":"c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b098","y":"6237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"8374253e3e21bd154448d0a8f640fe46fafa8b19ce78d538f6cc0a19662d3601","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #150: edge case for u1"} -{"x":"3fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced","y":"03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"357cfd3be4d01d413c5b9ede36cba5452c11ee7fe14879e749ae6a2d897a52d6","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #151: edge case for u1"} -{"x":"9cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114","y":"b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"29798c5c0ee287d4a5e8e6b799fd86b8df5225298e6ffc807cd2f2bc27a0a6d8","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #152: edge case for u1"} -{"x":"a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a","y":"4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"0b70f22c781092452dca1a5711fa3a5a1f72add1bf52c2ff7cae4820b30078dd","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #153: edge case for u1"} -{"x":"f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88","y":"cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"16e1e458f021248a5b9434ae23f474b43ee55ba37ea585fef95c90416600f1ba","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #154: edge case for u1"} -{"x":"83a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8","y":"c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"2252d6856831b6cf895e4f0535eeaf0e5e5809753df848fe760ad86219016a97","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #155: edge case for u1"} -{"x":"dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7","y":"bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"81ffe55f178da695b28c86d8b406b15dab1a9e39661a3ae017fbe390ac0972c3","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #156: edge case for u1"} -{"x":"67e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460","y":"a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #157: edge case for u2"} -{"x":"2eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf","y":"805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"b62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #158: edge case for u2"} -{"x":"84db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f35","y":"6d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #159: edge case for u2"} -{"x":"91b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad663","y":"49aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #160: edge case for u2"} -{"x":"f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834d","y":"f97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #161: edge case for u2"} -{"x":"d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc88","y":"5ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #162: edge case for u2"} -{"x":"0a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cd","y":"e6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc8600","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #163: edge case for u2"} -{"x":"d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e8","y":"68612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #164: edge case for u2"} -{"x":"836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb276","y":"9ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #165: edge case for u2"} -{"x":"92f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8","y":"033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #166: edge case for u2"} -{"x":"d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09e","y":"ff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #167: edge case for u2"} -{"x":"8651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224","y":"e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #168: edge case for u2"} -{"x":"6d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6d","y":"ef6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #169: edge case for u2"} -{"x":"0ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e1542","y":"8911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #170: edge case for u2"} -{"x":"5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963","y":"838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #171: point duplication during verification"} -{"x":"5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963","y":"7c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #172: duplication bug"} -{"x":"6adda82b90261b0f319faa0d878665a6b6da497f09c903176222c34acfef72a6","y":"47e6f50dcc40ad5d9b59f7602bb222fad71a41bf5e1f9df4959a364c62e488d9","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #173: point with x-coordinate 0"} -{"x":"dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d250","y":"45d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #175: comparison with point at infinity "} -{"x":"4fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5","y":"d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #176: extreme value for k and edgecase s"} -{"x":"c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107","y":"bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #177: extreme value for k and s^-1"} -{"x":"851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956ef","y":"cee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #178: extreme value for k and s^-1"} -{"x":"f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f","y":"8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #179: extreme value for k and s^-1"} -{"x":"501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a0643","y":"8673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #180: extreme value for k and s^-1"} -{"x":"0d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb34","y":"3195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #181: extreme value for k"} -{"x":"5e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca21","y":"5de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #182: extreme value for k and edgecase s"} -{"x":"169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e","y":"7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #183: extreme value for k and s^-1"} -{"x":"271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b54898148754","y":"0a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #184: extreme value for k and s^-1"} -{"x":"3d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12","y":"e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #185: extreme value for k and s^-1"} -{"x":"a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b7","y":"2e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #186: extreme value for k and s^-1"} -{"x":"8d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c","y":"4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #187: extreme value for k"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #188: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #189: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #190: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #191: testing point duplication"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a","s":"0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2","hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","valid":true,"msg":"","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #192: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"530bd6b0c9af2d69ba897f6b5fb59695cfbf33afe66dbadcf5b8d2a2a6538e23","s":"d85e489cb7a161fd55ededcedbf4cc0c0987e3e3f0f242cae934c72caa3f43e9","hash":"dc1921946f4af96a2856e7be399007c9e807bdf4c5332f19f59ec9dd1bb8c7b3","valid":true,"msg":"4d7367","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #193: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388","s":"f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b86","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #194: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb71","s":"3dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c","hash":"de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90","valid":true,"msg":"0000000000000000000000000000000000000000","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #195: pseudorandom signature"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f1","s":"9b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #196: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"0fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b","s":"500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df55737","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #197: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3","s":"541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb55677","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #198: x-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a","s":"59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #199: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"4cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b43","s":"9638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #200: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04","s":"a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b55","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #201: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"1158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830","s":"228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f285519","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #202: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d","s":"3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a1251336","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #203: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86","s":"ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #204: y-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b4","s":"3dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd139929","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #205: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"5eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af78","s":"2c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb5","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #206: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"96843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28","s":"f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #207: x-coordinate of the public key has many trailing 1's"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6","s":"402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #208: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9","s":"edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dba","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #209: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84","s":"feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #210: x-coordinate of the public key is large"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7","s":"b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #211: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"6b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f7","s":"5939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #212: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361","s":"f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #213: x-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"31230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb07","s":"0f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beff","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #214: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743","s":"cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #215: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"7e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed800185945","s":"9450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aa","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #216: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b356","s":"89c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #217: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b34","s":"72b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #218: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"70bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67","s":"aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_p1363_test.json EcdsaP1363Verify SHA-256 #219: y-coordinate of the public key is large"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #1: signature malleability"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #2: Legacy:ASN encoding of s misses leading 0"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #3: valid"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"29a3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #118: modify first byte of integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e98","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #120: modify last byte of integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b491568475b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #121: modify last byte of integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #124: truncated integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #133: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #134: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #137: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f47aa2bbd0a4c384ee1493b1f518ada018ef05465583885980861905228a","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #139: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #143: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #177: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #178: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #179: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #180: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #181: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #187: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #188: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #189: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #190: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #191: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #197: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #198: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #199: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #200: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #201: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #207: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #208: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #209: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #210: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #211: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #217: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #218: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #219: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #220: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #221: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"64a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e","s":"6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b","hash":"70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f807","valid":true,"msg":"3639383139","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #230: Edge case for Shamir multiplication"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"16aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266","s":"252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e9","hash":"00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a9","valid":true,"msg":"343236343739373234","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #231: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882","s":"093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c32","hash":"7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d91","valid":true,"msg":"37313338363834383931","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #232: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"73b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa43","s":"2f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c88634","hash":"ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe06045","valid":true,"msg":"3130333539333331363638","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #233: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3dd","s":"bdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b","hash":"67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0","valid":true,"msg":"33393439343031323135","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #234: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd","s":"51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b52","hash":"a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf","valid":true,"msg":"31333434323933303739","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #235: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa03","s":"99ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c7","hash":"3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65","valid":true,"msg":"33373036323131373132","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #236: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b","s":"8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d3610","hash":"9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c","valid":true,"msg":"333433363838373132","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #237: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831d","s":"b26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e9902","hash":"883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae0186","valid":true,"msg":"31333531353330333730","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #238: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b7","s":"20aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c","hash":"a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6","valid":true,"msg":"36353533323033313236","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #239: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db9","s":"3df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d21350","hash":"8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054","valid":true,"msg":"31353634333436363033","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #240: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675","s":"d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff2","hash":"660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305","valid":true,"msg":"34343239353339313137","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #241: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"3b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a8","s":"4c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d99258","hash":"d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c34","valid":true,"msg":"3130393533323631333531","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #242: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf","s":"47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed","hash":"bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f","valid":true,"msg":"35393837333530303431","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #243: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"38686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52","s":"067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d","hash":"33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a73","valid":true,"msg":"33343633303036383738","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #244: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"44a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf","s":"2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e86","hash":"b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf1","valid":true,"msg":"39383137333230323837","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #245: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e9","s":"7d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f9","hash":"01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a","valid":true,"msg":"33323232303431303436","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #246: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8f","s":"f6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c7","hash":"9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363","valid":true,"msg":"36363636333037313034","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #247: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6","s":"d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab244726","hash":"d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c","valid":true,"msg":"31303335393531383938","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #248: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d","s":"3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef","hash":"307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14","valid":true,"msg":"31383436353937313935","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #249: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7a","s":"c60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c5021","hash":"bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b8","valid":true,"msg":"33313336303436313839","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #250: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d","s":"9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f00","hash":"d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15e","valid":true,"msg":"32363633373834323534","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #251: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e","s":"7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a19878","hash":"79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e1","valid":true,"msg":"31363532313030353234","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #252: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c59","s":"2ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd","hash":"8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda","valid":true,"msg":"35373438303831363936","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #253: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c9466","s":"65d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc3","hash":"0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b21","valid":true,"msg":"36333433393133343638","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #254: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107","s":"cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf7592767","hash":"e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d","valid":true,"msg":"31353431313033353938","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #255: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"6554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728","s":"aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f929","hash":"9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de1","valid":true,"msg":"3130343738353830313238","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #256: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfc","s":"e99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d","hash":"62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15","valid":true,"msg":"3130353336323835353638","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #257: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf","s":"7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf919622","hash":"3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8","valid":true,"msg":"393533393034313035","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #258: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e","s":"0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa4","hash":"0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c800000000","valid":true,"msg":"393738383438303339","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #259: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba6","s":"5e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c65424339","hash":"ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289a","valid":true,"msg":"33363130363732343432","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #260: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88","s":"737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f","hash":"7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7","valid":true,"msg":"31303534323430373035","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #261: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa","s":"6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a","hash":"a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395","valid":true,"msg":"35313734343438313937","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #262: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad2","s":"42c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d693","hash":"641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0","valid":true,"msg":"31393637353631323531","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #263: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b2","s":"9d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e","hash":"958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b","valid":true,"msg":"33343437323533333433","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #264: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8","s":"e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c89","hash":"f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8","valid":true,"msg":"333638323634333138","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #265: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443","s":"e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a1939123","hash":"0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def","valid":true,"msg":"33323631313938363038","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #266: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad","s":"1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c6","hash":"60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589","valid":true,"msg":"39363738373831303934","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #267: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"4a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb","s":"3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc5981725782","hash":"c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e2","valid":true,"msg":"34393538383233383233","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #268: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"eacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e96","s":"7451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d1","hash":"de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68d","valid":true,"msg":"383234363337383337","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #269: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052","s":"ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c","hash":"6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff","valid":true,"msg":"3131303230383333373736","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #270: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b3300219","s":"79938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a","hash":"cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9","valid":true,"msg":"313333383731363438","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #271: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"81f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8","s":"cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f74300","hash":"2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb0484","valid":true,"msg":"333232313434313632","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #272: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808","s":"048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e7","hash":"ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411","valid":true,"msg":"3130363836363535353436","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #273: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a5762","s":"93320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c199345","hash":"4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610","valid":true,"msg":"3632313535323436","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #274: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883","s":"f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a8","hash":"422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75a","valid":true,"msg":"37303330383138373734","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #275: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f7","s":"6b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db55","hash":"7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018","valid":true,"msg":"35393234353233373434","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #276: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0","s":"918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b2443","hash":"3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95","valid":true,"msg":"31343935353836363231","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #277: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a3","s":"1dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f49584389772","hash":"de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b","valid":true,"msg":"34303035333134343036","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #278: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff11","s":"45b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d75","hash":"8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c","valid":true,"msg":"33303936343537353132","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #279: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06f","s":"b1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c20","hash":"6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca8","valid":true,"msg":"32373834303235363230","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #280: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32e","s":"db1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c","hash":"fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e","valid":true,"msg":"32363138373837343138","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #281: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a","s":"3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c","hash":"1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a","valid":true,"msg":"31363432363235323632","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #282: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5","s":"249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b","hash":"08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e","valid":true,"msg":"36383234313839343336","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #283: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348","s":"fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea","hash":"d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff","valid":true,"msg":"343834323435343235","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #284: special case hash"} -{"x":"0ad99500288d466940031d72a9f5445a4d43784640855bf0a69874d2de5fe103","y":"c5011e6ef2c42dcd50d5d3d29f99ae6eba2c80c9244f4c5422f0979ff0c3ba5e","r":"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #286: r too large"} -{"x":"ab05fd9d0de26b9ce6f4819652d9fc69193d0aa398f0fba8013e09c582204554","y":"19235271228c786759095d12b75af0692dd4103f19f6a8c32f49435a1e9b8d45","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #287: r,s are large"} -{"x":"80984f39a1ff38a86a68aa4201b6be5dfbfecf876219710b07badf6fdd4c6c56","y":"11feb97390d9826e7a06dfb41871c940d74415ed3cac2089f1445019bb55ed95","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd4","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #288: r and s^-1 have a large Hamming weight"} -{"x":"4201b4272944201c3294f5baa9a3232b6dd687495fcc19a70a95bc602b4f7c05","y":"95c37eba9ee8171c1bb5ac6feaf753bc36f463e3aef16629572c0c0a8fb0800e","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #289: r and s^-1 have a large Hamming weight"} -{"x":"083539fbee44625e3acaafa2fcb41349392cef0633a1b8fabecee0c133b10e99","y":"915c1ebe7bf00df8535196770a58047ae2a402f26326bb7d41d4d7616337911e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #301: r and s^-1 are close to n"} -{"x":"b533d4695dd5b8c5e07757e55e6e516f7e2c88fa0239e23f60e8ec07dd70f287","y":"1b134ee58cc583278456863f33c3a85d881f7d4a39850143e29d4eaf009afe47","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #304: point at infinity during verify"} -{"x":"f50d371b91bfb1d7d14e1323523bc3aa8cbf2c57f9e284de628c8b4536787b86","y":"f94ad887ac94d527247cd2e7d0c8b1291c553c9730405380b14cbb209f5fa2dd","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #305: edge case for signature malleability"} -{"x":"68ec6e298eafe16539156ce57a14b04a7047c221bafc3a582eaeb0d857c4d946","y":"97bed1af17850117fdb39b2324f220a5698ed16c426a27335bb385ac8ca6fb30","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #306: edge case for signature malleability"} -{"x":"69da0364734d2e530fece94019265fefb781a0f1b08f6c8897bdf6557927c8b8","y":"66d2d3c7dcd518b23d726960f069ad71a933d86ef8abbcce8b20f71e2a847002","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #307: u1 == 1"} -{"x":"d8adc00023a8edc02576e2b63e3e30621a471e2b2320620187bf067a1ac1ff32","y":"33e2b50ec09807accb36131fff95ed12a09a86b4ea9690aa32861576ba2362e1","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #308: u1 == n - 1"} -{"x":"3623ac973ced0a56fa6d882f03a7d5c7edca02cfc7b2401fab3690dbe75ab785","y":"8db06908e64b28613da7257e737f39793da8e713ba0643b92e9bb3252be7f8fe","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #309: u2 == 1"} -{"x":"cf04ea77e9622523d894b93ff52dc3027b31959503b6fa3890e5e04263f922f1","y":"e8528fb7c006b3983c8b8400e57b4ed71740c2f3975438821199bedeaecab2e9","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #310: u2 == n - 1"} -{"x":"db7a2c8a1ab573e5929dc24077b508d7e683d49227996bda3e9f78dbeff77350","y":"4f417f3bc9a88075c2e0aadd5a13311730cf7cc76a82f11a36eaf08a6c99a206","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"e91e1ba60fdedb76a46bcb51dc0b8b4b7e019f0a28721885fa5d3a8196623397","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #311: edge case for u1"} -{"x":"dead11c7a5b396862f21974dc4752fadeff994efe9bbd05ab413765ea80b6e1f","y":"1de3f0640e8ac6edcf89cff53c40e265bb94078a343736df07aa0318fc7fe1ff","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"fdea5843ffeb73af94313ba4831b53fe24f799e525b1e8e8c87b59b95b430ad9","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #312: edge case for u1"} -{"x":"d0bc472e0d7c81ebaed3a6ef96c18613bb1fea6f994326fbe80e00dfde67c7e9","y":"986c723ea4843d48389b946f64ad56c83ad70ff17ba85335667d1bb9fa619efd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"03ffcabf2f1b4d2a65190db1680d62bb994e41c5251cd73b3c3dfc5e5bafc035","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #313: edge case for u1"} -{"x":"a0a44ca947d66a2acb736008b9c08d1ab2ad03776e02640f78495d458dd51c32","y":"6337fe5cf8c4604b1f1c409dc2d872d4294a4762420df43a30a2392e40426add","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"4dfbc401f971cd304b33dfdb17d0fed0fe4c1a88ae648e0d2847f74977534989","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #314: edge case for u1"} -{"x":"c9c2115290d008b45fb65fad0f602389298c25420b775019d42b62c3ce8a96b7","y":"3877d25a8080dc02d987ca730f0405c2c9dbefac46f9e601cc3f06e9713973fd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bc4024761cd2ffd43dfdb17d0fed112b988977055cd3a8e54971eba9cda5ca71","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #315: edge case for u1"} -{"x":"5eca1ef4c287dddc66b8bccf1b88e8a24c0018962f3c5e7efa83bc1a5ff6033e","y":"5e79c4cb2c245b8c45abdce8a8e4da758d92a607c32cd407ecaef22f1c934a71","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"788048ed39a5ffa77bfb62fa1fda2257742bf35d128fb3459f2a0c909ee86f91","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #316: edge case for u1"} -{"x":"5caaa030e7fdf0e4936bc7ab5a96353e0a01e4130c3f8bf22d473e317029a47a","y":"deb6adc462f7058f2a20d371e9702254e9b201642005b3ceda926b42b178bef9","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"476d9131fd381bd917d0fed112bc9e0a5924b5ed5b11167edd8b23582b3cb15e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #317: edge case for u1"} -{"x":"c2fd20bac06e555bb8ac0ce69eb1ea20f83a1fc3501c8a66469b1a31f619b098","y":"6237050779f52b615bd7b8d76a25fc95ca2ed32525c75f27ffc87ac397e6cbaf","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"8374253e3e21bd154448d0a8f640fe46fafa8b19ce78d538f6cc0a19662d3601","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #318: edge case for u1"} -{"x":"3fd6a1ca7f77fb3b0bbe726c372010068426e11ea6ae78ce17bedae4bba86ced","y":"03ce5516406bf8cfaab8745eac1cd69018ad6f50b5461872ddfc56e0db3c8ff4","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"357cfd3be4d01d413c5b9ede36cba5452c11ee7fe14879e749ae6a2d897a52d6","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #319: edge case for u1"} -{"x":"9cb8e51e27a5ae3b624a60d6dc32734e4989db20e9bca3ede1edf7b086911114","y":"b4c104ab3c677e4b36d6556e8ad5f523410a19f2e277aa895fc57322b4427544","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"29798c5c0ee287d4a5e8e6b799fd86b8df5225298e6ffc807cd2f2bc27a0a6d8","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #320: edge case for u1"} -{"x":"a3e52c156dcaf10502620b7955bc2b40bc78ef3d569e1223c262512d8f49602a","y":"4a2039f31c1097024ad3cc86e57321de032355463486164cf192944977df147f","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"0b70f22c781092452dca1a5711fa3a5a1f72add1bf52c2ff7cae4820b30078dd","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #321: edge case for u1"} -{"x":"f19b78928720d5bee8e670fb90010fb15c37bf91b58a5157c3f3c059b2655e88","y":"cf701ec962fb4a11dcf273f5dc357e58468560c7cfeb942d074abd4329260509","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"16e1e458f021248a5b9434ae23f474b43ee55ba37ea585fef95c90416600f1ba","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #322: edge case for u1"} -{"x":"83a744459ecdfb01a5cf52b27a05bb7337482d242f235d7b4cb89345545c90a8","y":"c05d49337b9649813287de9ffe90355fd905df5f3c32945828121f37cc50de6e","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"2252d6856831b6cf895e4f0535eeaf0e5e5809753df848fe760ad86219016a97","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #323: edge case for u1"} -{"x":"dd13c6b34c56982ddae124f039dfd23f4b19bbe88cee8e528ae51e5d6f3a21d7","y":"bfad4c2e6f263fe5eb59ca974d039fc0e4c3345692fb5320bdae4bd3b42a45ff","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"81ffe55f178da695b28c86d8b406b15dab1a9e39661a3ae017fbe390ac0972c3","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #324: edge case for u1"} -{"x":"67e6f659cdde869a2f65f094e94e5b4dfad636bbf95192feeed01b0f3deb7460","y":"a37e0a51f258b7aeb51dfe592f5cfd5685bbe58712c8d9233c62886437c38ba0","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #325: edge case for u2"} -{"x":"2eb6412505aec05c6545f029932087e490d05511e8ec1f599617bb367f9ecaaf","y":"805f51efcc4803403f9b1ae0124890f06a43fedcddb31830f6669af292895cb0","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"b62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #326: edge case for u2"} -{"x":"84db645868eab35e3a9fd80e056e2e855435e3a6b68d75a50a854625fe0d7f35","y":"6d2589ac655edc9a11ef3e075eddda9abf92e72171570ef7bf43a2ee39338cfe","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #327: edge case for u2"} -{"x":"91b9e47c56278662d75c0983b22ca8ea6aa5059b7a2ff7637eb2975e386ad663","y":"49aa8ff283d0f77c18d6d11dc062165fd13c3c0310679c1408302a16854ecfbd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #328: edge case for u2"} -{"x":"f3ec2f13caf04d0192b47fb4c5311fb6d4dc6b0a9e802e5327f7ec5ee8e4834d","y":"f97e3e468b7d0db867d6ecfe81e2b0f9531df87efdb47c1338ac321fefe5a432","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #329: edge case for u2"} -{"x":"d92b200aefcab6ac7dafd9acaf2fa10b3180235b8f46b4503e4693c670fccc88","y":"5ef2f3aebf5b317475336256768f7c19efb7352d27e4cccadc85b6b8ab922c72","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #330: edge case for u2"} -{"x":"0a88361eb92ecca2625b38e5f98bbabb96bf179b3d76fc48140a3bcd881523cd","y":"e6bdf56033f84a5054035597375d90866aa2c96b86a41ccf6edebf47298ad489","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc8600","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #331: edge case for u2"} -{"x":"d0fb17ccd8fafe827e0c1afc5d8d80366e2b20e7f14a563a2ba50469d84375e8","y":"68612569d39e2bb9f554355564646de99ac602cc6349cf8c1e236a7de7637d93","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #332: edge case for u2"} -{"x":"836f33bbc1dc0d3d3abbcef0d91f11e2ac4181076c9af0a22b1e4309d3edb276","y":"9ab443ff6f901e30c773867582997c2bec2b0cb8120d760236f3a95bbe881f75","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #333: edge case for u2"} -{"x":"92f99fbe973ed4a299719baee4b432741237034dec8d72ba5103cb33e55feeb8","y":"033dd0e91134c734174889f3ebcf1b7a1ac05767289280ee7a794cebd6e69697","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #334: edge case for u2"} -{"x":"d35ba58da30197d378e618ec0fa7e2e2d12cffd73ebbb2049d130bba434af09e","y":"ff83986e6875e41ea432b7585a49b3a6c77cbb3c47919f8e82874c794635c1d2","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #335: edge case for u2"} -{"x":"8651ce490f1b46d73f3ff475149be29136697334a519d7ddab0725c8d0793224","y":"e11c65bd8ca92dc8bc9ae82911f0b52751ce21dd9003ae60900bd825f590cc28","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #336: edge case for u2"} -{"x":"6d8e1b12c831a0da8795650ff95f101ed921d9e2f72b15b1cdaca9826b9cfc6d","y":"ef6d63e2bc5c089570394a4bc9f892d5e6c7a6a637b20469a58c106ad486bf37","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #337: edge case for u2"} -{"x":"0ae580bae933b4ef2997cbdbb0922328ca9a410f627a0f7dff24cb4d920e1542","y":"8911e7f8cc365a8a88eb81421a361ccc2b99e309d8dcd9a98ba83c3949d893e3","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #338: edge case for u2"} -{"x":"5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963","y":"838a40f2a36092e9004e92d8d940cf5638550ce672ce8b8d4e15eba5499249e9","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #339: point duplication during verification"} -{"x":"5b812fd521aafa69835a849cce6fbdeb6983b442d2444fe70e134c027fc46963","y":"7c75bf0c5c9f6d17ffb16d2726bf30a9c7aaf31a8d317472b1ea145ab66db616","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"bb726660235793aa9957a61e76e00c2c435109cf9a15dd624d53f4301047856b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #340: duplication bug"} -{"x":"dd86d3b5f4a13e8511083b78002081c53ff467f11ebd98a51a633db76665d250","y":"45d5c8200c89f2fa10d849349226d21d8dfaed6ff8d5cb3e1b7e17474ebc18f7","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #343: comparison with point at infinity "} -{"x":"4fea55b32cb32aca0c12c4cd0abfb4e64b0f5a516e578c016591a93f5a0fbcc5","y":"d7d3fd10b2be668c547b212f6bb14c88f0fecd38a8a4b2c785ed3be62ce4b280","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #344: extreme value for k and edgecase s"} -{"x":"c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107","y":"bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #345: extreme value for k and s^-1"} -{"x":"851c2bbad08e54ec7a9af99f49f03644d6ec6d59b207fec98de85a7d15b956ef","y":"cee9960283045075684b410be8d0f7494b91aa2379f60727319f10ddeb0fe9d6","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #346: extreme value for k and s^-1"} -{"x":"f6417c8a670584e388676949e53da7fc55911ff68318d1bf3061205acb19c48f","y":"8f2b743df34ad0f72674acb7505929784779cd9ac916c3669ead43026ab6d43f","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #347: extreme value for k and s^-1"} -{"x":"501421277be45a5eefec6c639930d636032565af420cf3373f557faa7f8a0643","y":"8673d6cb6076e1cfcdc7dfe7384c8e5cac08d74501f2ae6e89cad195d0aa1371","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #348: extreme value for k and s^-1"} -{"x":"0d935bf9ffc115a527735f729ca8a4ca23ee01a4894adf0e3415ac84e808bb34","y":"3195a3762fea29ed38912bd9ea6c4fde70c3050893a4375850ce61d82eba33c5","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #349: extreme value for k"} -{"x":"5e59f50708646be8a589355014308e60b668fb670196206c41e748e64e4dca21","y":"5de37fee5c97bcaf7144d5b459982f52eeeafbdf03aacbafef38e213624a01de","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #350: extreme value for k and edgecase s"} -{"x":"169fb797325843faff2f7a5b5445da9e2fd6226f7ef90ef0bfe924104b02db8e","y":"7bbb8de662c7b9b1cf9b22f7a2e582bd46d581d68878efb2b861b131d8a1d667","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #351: extreme value for k and s^-1"} -{"x":"271cd89c000143096b62d4e9e4ca885aef2f7023d18affdaf8b7b54898148754","y":"0a1c6e954e32108435b55fa385b0f76481a609b9149ccb4b02b2ca47fe8e4da5","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #352: extreme value for k and s^-1"} -{"x":"3d0bc7ed8f09d2cb7ddb46ebc1ed799ab1563a9ab84bf524587a220afe499c12","y":"e22dc3b3c103824a4f378d96adb0a408abf19ce7d68aa6244f78cb216fa3f8df","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #353: extreme value for k and s^-1"} -{"x":"a6c885ade1a4c566f9bb010d066974abb281797fa701288c721bcbd23663a9b7","y":"2e424b690957168d193a6096fc77a2b004a9c7d467e007e1f2058458f98af316","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #354: extreme value for k and s^-1"} -{"x":"8d3c2c2c3b765ba8289e6ac3812572a25bf75df62d87ab7330c3bdbad9ebfa5c","y":"4c6845442d66935b238578d43aec54f7caa1621d1af241d4632e0b780c423f5d","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #355: extreme value for k"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #356: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #357: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #358: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"44a5ad0ad0636d9f12bc9e0a6bdd5e1cbcb012ea7bf091fcec15b0c43202d52e","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #359: testing point duplication"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a","s":"0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2","hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","valid":true,"msg":"","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #360: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"530bd6b0c9af2d69ba897f6b5fb59695cfbf33afe66dbadcf5b8d2a2a6538e23","s":"d85e489cb7a161fd55ededcedbf4cc0c0987e3e3f0f242cae934c72caa3f43e9","hash":"dc1921946f4af96a2856e7be399007c9e807bdf4c5332f19f59ec9dd1bb8c7b3","valid":true,"msg":"4d7367","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #361: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388","s":"f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b86","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #362: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb71","s":"3dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c","hash":"de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90","valid":true,"msg":"0000000000000000000000000000000000000000","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #363: pseudorandom signature"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f1","s":"9b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #364: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"0fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b","s":"500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df55737","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #365: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3","s":"541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb55677","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #366: x-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a","s":"59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #367: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"4cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b43","s":"9638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #368: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04","s":"a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b55","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #369: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"1158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830","s":"228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f285519","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #370: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d","s":"3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a1251336","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #371: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86","s":"ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #372: y-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b4","s":"3dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd139929","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #373: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"5eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af78","s":"2c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb5","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #374: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"96843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28","s":"f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #375: x-coordinate of the public key has many trailing 1's"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6","s":"402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #376: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9","s":"edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dba","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #377: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84","s":"feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #378: x-coordinate of the public key is large"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7","s":"b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #379: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"6b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f7","s":"5939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #380: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361","s":"f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #381: x-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"31230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb07","s":"0f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beff","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #382: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743","s":"cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #383: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"7e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed800185945","s":"9450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aa","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #384: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b356","s":"89c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #385: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b34","s":"72b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #386: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"70bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67","s":"aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_secp256r1_sha256_test.json EcdsaVerify SHA-256 #387: y-coordinate of the public key is large"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1: signature malleability"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #2: Legacy:ASN encoding of s misses leading 0"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #3: valid"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"29a3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #118: modify first byte of integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e98","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #120: modify last byte of integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b491568475b","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #121: modify last byte of integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #124: truncated integer"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #133: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #134: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #137: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"b329f47aa2bbd0a4c384ee1493b1f518ada018ef05465583885980861905228a","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #139: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #143: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #177: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #178: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #179: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #180: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #181: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #187: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #188: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #189: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #190: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #191: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #197: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #198: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #199: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #200: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #201: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #207: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #208: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #209: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #210: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #211: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #217: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #218: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #219: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #220: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #221: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"64a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e","s":"6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b","hash":"70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f807","valid":true,"msg":"3639383139","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #230: Edge case for Shamir multiplication"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"16aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266","s":"252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e9","hash":"00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a9","valid":true,"msg":"343236343739373234","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #231: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882","s":"093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c32","hash":"7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d91","valid":true,"msg":"37313338363834383931","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #232: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"73b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa43","s":"2f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c88634","hash":"ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe06045","valid":true,"msg":"3130333539333331363638","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #233: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3dd","s":"bdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b","hash":"67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0","valid":true,"msg":"33393439343031323135","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #234: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd","s":"51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b52","hash":"a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf","valid":true,"msg":"31333434323933303739","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #235: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa03","s":"99ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c7","hash":"3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65","valid":true,"msg":"33373036323131373132","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #236: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b","s":"8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d3610","hash":"9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c","valid":true,"msg":"333433363838373132","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #237: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831d","s":"b26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e9902","hash":"883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae0186","valid":true,"msg":"31333531353330333730","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #238: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b7","s":"20aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c","hash":"a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6","valid":true,"msg":"36353533323033313236","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #239: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db9","s":"3df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d21350","hash":"8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054","valid":true,"msg":"31353634333436363033","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #240: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675","s":"d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff2","hash":"660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305","valid":true,"msg":"34343239353339313137","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #241: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"3b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a8","s":"4c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d99258","hash":"d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c34","valid":true,"msg":"3130393533323631333531","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #242: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf","s":"47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed","hash":"bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f","valid":true,"msg":"35393837333530303431","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #243: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"38686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52","s":"067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d","hash":"33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a73","valid":true,"msg":"33343633303036383738","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #244: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"44a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf","s":"2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e86","hash":"b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf1","valid":true,"msg":"39383137333230323837","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #245: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e9","s":"7d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f9","hash":"01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a","valid":true,"msg":"33323232303431303436","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #246: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8f","s":"f6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c7","hash":"9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363","valid":true,"msg":"36363636333037313034","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #247: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6","s":"d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab244726","hash":"d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c","valid":true,"msg":"31303335393531383938","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #248: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d","s":"3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef","hash":"307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14","valid":true,"msg":"31383436353937313935","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #249: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7a","s":"c60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c5021","hash":"bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b8","valid":true,"msg":"33313336303436313839","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #250: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d","s":"9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f00","hash":"d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15e","valid":true,"msg":"32363633373834323534","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #251: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e","s":"7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a19878","hash":"79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e1","valid":true,"msg":"31363532313030353234","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #252: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c59","s":"2ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd","hash":"8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda","valid":true,"msg":"35373438303831363936","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #253: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c9466","s":"65d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc3","hash":"0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b21","valid":true,"msg":"36333433393133343638","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #254: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107","s":"cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf7592767","hash":"e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d","valid":true,"msg":"31353431313033353938","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #255: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"6554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728","s":"aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f929","hash":"9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de1","valid":true,"msg":"3130343738353830313238","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #256: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfc","s":"e99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d","hash":"62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15","valid":true,"msg":"3130353336323835353638","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #257: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf","s":"7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf919622","hash":"3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8","valid":true,"msg":"393533393034313035","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #258: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e","s":"0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa4","hash":"0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c800000000","valid":true,"msg":"393738383438303339","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #259: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba6","s":"5e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c65424339","hash":"ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289a","valid":true,"msg":"33363130363732343432","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #260: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88","s":"737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f","hash":"7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7","valid":true,"msg":"31303534323430373035","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #261: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa","s":"6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a","hash":"a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395","valid":true,"msg":"35313734343438313937","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #262: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad2","s":"42c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d693","hash":"641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0","valid":true,"msg":"31393637353631323531","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #263: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b2","s":"9d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e","hash":"958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b","valid":true,"msg":"33343437323533333433","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #264: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8","s":"e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c89","hash":"f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8","valid":true,"msg":"333638323634333138","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #265: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443","s":"e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a1939123","hash":"0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def","valid":true,"msg":"33323631313938363038","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #266: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad","s":"1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c6","hash":"60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589","valid":true,"msg":"39363738373831303934","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #267: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"4a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb","s":"3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc5981725782","hash":"c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e2","valid":true,"msg":"34393538383233383233","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #268: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"eacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e96","s":"7451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d1","hash":"de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68d","valid":true,"msg":"383234363337383337","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #269: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052","s":"ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c","hash":"6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff","valid":true,"msg":"3131303230383333373736","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #270: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b3300219","s":"79938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a","hash":"cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9","valid":true,"msg":"313333383731363438","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #271: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"81f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8","s":"cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f74300","hash":"2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb0484","valid":true,"msg":"333232313434313632","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #272: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808","s":"048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e7","hash":"ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411","valid":true,"msg":"3130363836363535353436","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #273: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a5762","s":"93320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c199345","hash":"4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610","valid":true,"msg":"3632313535323436","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #274: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883","s":"f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a8","hash":"422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75a","valid":true,"msg":"37303330383138373734","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #275: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f7","s":"6b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db55","hash":"7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018","valid":true,"msg":"35393234353233373434","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #276: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0","s":"918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b2443","hash":"3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95","valid":true,"msg":"31343935353836363231","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #277: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a3","s":"1dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f49584389772","hash":"de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b","valid":true,"msg":"34303035333134343036","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #278: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff11","s":"45b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d75","hash":"8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c","valid":true,"msg":"33303936343537353132","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #279: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06f","s":"b1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c20","hash":"6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca8","valid":true,"msg":"32373834303235363230","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #280: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32e","s":"db1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c","hash":"fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e","valid":true,"msg":"32363138373837343138","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #281: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a","s":"3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c","hash":"1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a","valid":true,"msg":"31363432363235323632","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #282: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5","s":"249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b","hash":"08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e","valid":true,"msg":"36383234313839343336","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #283: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348","s":"fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea","hash":"d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff","valid":true,"msg":"343834323435343235","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #284: special case hash"} -{"x":"d705d16f80987e2d9b1a6957d29ce22febf7d10fa515153182415c8361baaca4","y":"b1fc105ee5ce80d514ec1238beae2037a6f83625593620d460819e8682160926","r":"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #636: r too large"} -{"x":"3cd8d2f81d6953b0844c09d7b560d527cd2ef67056893eadafa52c8501387d59","y":"ee41fdb4d10402ce7a0c5e3b747adfa3a490b62a6b7719068903485c0bb6dc2d","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #637: r,s are large"} -{"x":"8240cd81edd91cb6936133508c3915100e81f332c4545d41189b481196851378","y":"e05b06e72d4a1bff80ea5db514aa2f93ea6dd6d9c0ae27b7837dc432f9ce89d9","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #638: r and s^-1 have a large Hamming weight"} -{"x":"b062947356748b0fc17f1704c65aa1dca6e1bfe6779756fa616d91eaad13df2c","y":"0b38c17f3d0672e7409cfc5992a99fff12b84a4f8432293b431113f1b2fb579d","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #639: r and s^-1 have a large Hamming weight"} -{"x":"7a736d8e326a9ca62bbe25a34ea4e3633b499a96afa7aaa3fcf3fd88f8e07ede","y":"b3e45879d8622b93e818443a686e869eeda7bf9ae46aa3eafcc48a5934864627","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #651: r and s^-1 are close to n"} -{"x":"0203736fcb198b15d8d7a0c80f66dddd15259240aa78d08aae67c467de045034","y":"34383438d5041ea9a387ee8e4d4e84b4471b160c6bcf2568b072f8f20e87a996","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #654: point at infinity during verify"} -{"x":"78d844dc7f16b73b1f2a39730da5d8cd99fe2e70a18482384e37dcd2bfea02e1","y":"ed6572e01eb7a8d113d02c666c45ef22d3b9a6a6dea99aa43a8183c26e75d336","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #655: edge case for signature malleability"} -{"x":"dec6c8257dde94110eacc8c09d2e5789cc5beb81a958b02b4d62da9599a74014","y":"66fae1614174be63970b83f6524421067b06dd6f4e9c56baca4e344fdd690f1d","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #656: edge case for signature malleability"} -{"x":"a17f5b75a35ed64623ca5cbf1f91951292db0c23f0c2ea24c3d0cad0988cabc0","y":"83a7a618625c228940730b4fa3ee64faecbb2fc20fdde7c58b3a3f6300424dc6","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #657: u1 == 1"} -{"x":"04ba0cba291a37db13f33bf90dab628c04ec8393a0200419e9eaa1ebcc9fb5c3","y":"1f3a0a0e6823a49b625ad57b12a32d4047970fc3428f0f0049ecf4265dc12f62","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #658: u1 == n - 1"} -{"x":"692b6c828e0feed63d8aeaa2b7322f9ccbe8723a1ed39f229f204a434b8900ef","y":"a1f6f6abcb38ea3b8fde38b98c7c271f274af56a8c5628dc3329069ae4dd5716","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #659: u2 == 1"} -{"x":"00cefd9162d13e64cb93687a9cd8f9755ebb5a3ef7632f800f84871874ccef09","y":"543ecbeaf7e8044ef721be2fb5f549e4b8480d2587404ebf7dbbef2c54bc0cb1","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #660: u2 == n - 1"} -{"x":"b975183b42551cf52f291d5c1921fd5e12f50c8c85a4beb9de03efa3f0f24486","y":"2243018e6866df922dc313612020311ff21e242ce3fb15bc78c406b25ab43091","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"710f8e3edc7c2d5a3fd23de844002bb949d9f794f6d5405f6d97c1bb03dd2bd2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #661: edge case for u1"} -{"x":"c25f1d166f3e211cdf042a26f8abf6094d48b8d17191d74ed717149274466999","y":"65d06dd6a88abfa49e8b4c5da6bb922851969adf9604b5accfb52a114e77ccdb","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"edffbc270f722c243069a7e5f40335a61a58525c7b4db2e7a8e269274ffe4e1b","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #662: edge case for u1"} -{"x":"8fe5e88243a76e41a004236218a3c3a2d6eee398a23c3a0b008d7f0164cbc0ca","y":"98a20d1bdcf573513c7cfd9b83c63e3a82d40127c897697c86b8cb387af7f240","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"a25adcae105ed7ff4f95d2344e24ee523314c3e178525d007904b68919ba4d53","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #663: edge case for u1"} -{"x":"02148256b530fbc470c7b341970b38243ecee6d5a840a37beca2efb37e8dff2c","y":"c0adbea0882482a7489ca703a399864ba987eeb6ddb738af53a83573473cb30d","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"2e4348c645707dce6760d773de3f3e87346924b2f64bd3dd0297e766b5805ebb","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #664: edge case for u1"} -{"x":"a34db012ce6eda1e9c7375c5fcf3e54ed698e19615124273b3a621d021c76f8e","y":"777458d6f55a364c221e39e1205d5510bb4fbb7ddf08d8d8fdde13d1d6df7f14","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"348c673b07dce3920d773de3f3e87408869e916dbcf797d8f9684fb67753d1dc","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #665: edge case for u1"} -{"x":"b97af3fe78be15f2912b6271dd8a43badb6dd2a1b315b2ce7ae37b4e7778041d","y":"930d71ee1992d2466495c42102d08e81154c305307d1dcd52d0fa4c479b278e7","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"6918ce760fb9c7241aee7bc7e7d0e8110d3d22db79ef2fb1f2d09f6ceea7a3b8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #666: edge case for u1"} -{"x":"81e7198a3c3f23901cedc7a1d6eff6e9bf81108e6c35cd8559139af3135dbcbb","y":"9ef1568530291a8061b90c9f4285eefcba990d4570a4e3b7b737525b5d580034","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"73b3c694391d8eadde3f3e874089464715ac20e4c126bbf6d864d648969f5b5a","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #667: edge case for u1"} -{"x":"ab4d792ca121d1dba39cb9de645149c2ab573e8becc6ddff3cc9960f188ddf73","y":"7f90ba23664153e93262ff73355415195858d7be1315a69456386de68285a3c8","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bb07ac7a86948c2c2989a16db1930ef1b89ce112595197656877e53c41457f28","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #668: edge case for u1"} -{"x":"518412b69af43aae084476a68d59bbde51fbfa9e5be80563f587c9c2652f88ef","y":"2d3b90d25baa6bdb7b0c55e5240a3a98fbc24afed8523edec1c70503fc10f233","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"27e4d82cb6c061dd9337c69bf9332ed3d198662d6f2299443f62c861187db648","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #669: edge case for u1"} -{"x":"a08f14a644b9a935dffea4761ebaf592d1f66fe6cd373aa7f5d370af34f8352d","y":"a54b5bc4025cf335900a914c2934ec2fec7a396d0a7affcad732a5741c7aaaf5","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"e7c5cf3aac2e88923b77850515fff6a12d13b356dfe9ec275c3dd81ae94609a4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #670: edge case for u1"} -{"x":"ccf2296a6a89b62b90739d38af4ae3a20e9f45715b90044639241061e33f8f8c","y":"aace0046491eeaa1c6e9a472b96d88f4af83e7ff1bb84438c7e058034412ae08","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"c77838df91c1e953e016e10bddffea2317f9fee32bacfe553cede9e57a748f68","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #671: edge case for u1"} -{"x":"94b0fc1525bcabf82b1f34895e5819a06c02b23e04002276e165f962c86e3927","y":"be7c2ab4d0b25303204fb32a1f8292902792225e16a6d2dbfb29fbc89a9c3376","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"8ef071c02383d2a6c02dc217bbffd446730d0318b0425e2586220907f885f97f","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #672: edge case for u1"} -{"x":"5351f37e1de0c88c508527d89882d183ccdcf2efca407edb0627cadfd16de6ec","y":"44b4b57cdf960d32ebcc4c97847eed218425853b5b675eb781b766a1a1300349","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"5668aaa0b545bbf9a044a32399ffbe69ce20074e34d7bdf5cf56282a76976396","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #673: edge case for u1"} -{"x":"748bbafc320e6735cb64019710a269c6c2b5d147bdc831325cb2fb276ac971a6","y":"9d655e9a755bc9d800ad21ee3fd4d980d93a7a49a8c5ccd37005177578f51163","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"d12d6e56882f6c0027cae91a27127728f7fddf478fb4fdc2b65f40a60b0eb952","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #674: edge case for u1"} -{"x":"14b3bbd75c5e1c0c36535a934d4ab85112410b3b90fa97a31c33038964fd85cc","y":"112f7d837f8f9c36b460d636c965a5f818f2b50c5d00fb3f9705561dd6631883","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #675: edge case for u2"} -{"x":"d823533c04cd8edc6d6f950a8e08ade04a9bafa2f14a590356935671ae9305bf","y":"43178d1f88b6a57a96924c265f0ddb75b58312907b195acb59d7797303123775","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"b62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #676: edge case for u2"} -{"x":"db2b3408b3167d91030624c6328e8ce3ec108c105575c2f3d209b92e654bab69","y":"c34318139c50b0802c6e612f0fd3189d800df7c996d5d7b7c3d6be82836fa258","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #677: edge case for u2"} -{"x":"09179ce7c59225392216453b2ac1e9d178c24837dfae26bc1dd7ab6063852742","y":"5556b42e330289f3b826b2db7a86d19d45c2860a59f2be1ddcc3b691f95a9255","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #678: edge case for u2"} -{"x":"01959fb8deda56e5467b7e4b214ea4c2d0c2fb29d70ff19b6b1eccebd6568d7e","y":"d9dbd77a918297fd970bff01e1343f6925167db5a14d098a211c39cc3a413398","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #679: edge case for u2"} -{"x":"567f1fdc387e5350c852b4e8f8ba9d6d947e1c5dd7ccc61a5938245dd6bcab3a","y":"9960bebaf919514f9535c22eaaf0b5812857970e26662267b1f3eb1011130a11","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #680: edge case for u2"} -{"x":"3499f974ff4ca6bbb2f51682fd5f51762f9dd6dd2855262660b36d46d3e4bec2","y":"f498fae2487807e220119152f0122476c64d4fa46ddce85c4546630f0d5c5e81","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc8600","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #681: edge case for u2"} -{"x":"2c5c01662cf00c1929596257db13b26ecf30d0f3ec4b9f0351b0f27094473426","y":"e986a086060d086eee822ddd2fc744247a0154b57f7a69c51d9fdafa484e4ac7","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #682: edge case for u2"} -{"x":"91d4cba813a04d86dbae94c23be6f52c15774183be7ba5b2d9f3cf010b160501","y":"900b8adfea6491019a9ac080d516025a541bf4b952b0ad7be4b1874b02fd544a","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #683: edge case for u2"} -{"x":"ef7fd0a3a36386638330ecad41e1a3b302af36960831d0210c614b948e8aa124","y":"ef0d6d800e4047d6d3c1be0fdeaf11fcd8cab5ab59c730eb34116e35a8c7d098","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #684: edge case for u2"} -{"x":"a521dab13cc9152d8ca77035a607fea06c55cc3ca5dbeb868cea92eafe93df2a","y":"7bfb9b28531996635e6a5ccaa2826a406ce1111bdb9c2e0ca36500418a2f43de","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #685: edge case for u2"} -{"x":"474d58a4eec16e0d565f2187fe11d4e8e7a2683a12f38b4fc01d1237a81a1097","y":"6e55f73bb7cdda46bdb67ef77f6fd2969df2b67920fb5945fde3a517a6ded4cd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #686: edge case for u2"} -{"x":"692da5cd4309d9a6e5cb525c37da8fa0879f7b57208cdabbf47d223a5b23a621","y":"40e0daa78cfdd207a7389aaed61738b17fc5fc3e6a5ed3397d2902e9125e6ab4","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #687: edge case for u2"} -{"x":"85689b3e0775c7718a90279f14a8082cfcd4d1f1679274f4e9b8805c570a0670","y":"167fcc5ca734552e09afa3640f4a034e15b9b7ca661ec7ff70d3f240ebe705b1","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #688: edge case for u2"} -{"x":"0158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237e","y":"2a964fc00d377a8592b8b61aafa7a4aaa7c7b9fd2b41d6e0e17bd1ba5677edcd","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #689: point duplication during verification"} -{"x":"0158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237e","y":"d569b03ef2c8857b6d4749e550585b5558384603d4be291f1e842e45a9881232","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #690: duplication bug"} -{"x":"664ce273320d918d8bdb2e61201b4549b36b7cdc54e33b84adb6f2c10aac831e","y":"49e68831f18bda2973ac3d76bfbc8c5ee1cceed2dd862e2dc7c915c736cef1f4","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #693: comparison with point at infinity "} -{"x":"961691a5e960d07a301dbbad4d86247ec27d7089faeb3ddd1add395efff1e0fe","y":"7254622cc371866cdf990d2c5377790e37d1f1519817f09a231bd260a9e78aeb","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #694: extreme value for k and edgecase s"} -{"x":"5d283e13ce8ca60da868e3b0fb33e6b4f1074793274e2928250e71e2aca63e9c","y":"214dc74fa25371fb4d9e506d418ed9a1bfd6d0c8bb6591d3e0f44505a84886ce","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #695: extreme value for k and s^-1"} -{"x":"0fc351da038ae0803bd1d86514ae0462f9f8216551d9315aa9d297f792eef6a3","y":"41c74eed786f2d33da35360ca7aa925e753f00d6077a1e9e5fc339d634019c73","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #696: extreme value for k and s^-1"} -{"x":"a1e34c8f16d138673fee55c080547c2bfd4de7550065f638322bba9430ce4b60","y":"662be9bb512663aa4d7df8ab3f3b4181c5d44a7bdf42436620b7d8a6b81ac936","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #697: extreme value for k and s^-1"} -{"x":"7e1a8a8338d7fd8cf41d322a302d2078a87a23c7186150ed7cda6e52817c1bdf","y":"d0a9135a89d21ce821e29014b2898349254d748272b2d4eb8d59ee34c615377f","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #698: extreme value for k and s^-1"} -{"x":"5c19fe227a61abc65c61ee7a018cc9571b2c6f663ea33583f76a686f64be078b","y":"7b4a0d734940f613d52bc48673b457c2cf78492490a5cc5606c0541d17b24ddb","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #699: extreme value for k"} -{"x":"db02d1f3421d600e9d9ef9e47419dba3208eed08c2d4189a5db63abeb2739666","y":"e0ed26967b9ada9ed7ffe480827f90a0d210d5fd8ec628e31715e6b24125512a","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #700: extreme value for k and edgecase s"} -{"x":"6222d1962655501893c29e441395b6c05711bd3ed5a0ef72cfab338b88229c4b","y":"aaae079cb44a1af070362aaa520ee24cac2626423b0bf81af1c54311d8e2fd23","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #701: extreme value for k and s^-1"} -{"x":"4ccfa24c67f3def7fa81bc99c70bb0419c0952ba599f4c03361da184b04cdca5","y":"db76b797f7f41d9c729a2219478a7e629728df870800be8cf6ca7a0a82153bfa","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #702: extreme value for k and s^-1"} -{"x":"ea1c72c91034036bac71402b6e9ecc4af3dbde7a99dc574061e99fefff9d84da","y":"b7dd057e75b78ac6f56e34eb048f0a9d29d5d055408c90d02bc2ea918c18cb63","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #703: extreme value for k and s^-1"} -{"x":"c2879a66d86cb20b820b7795da2da62b38924f7817d1cd350d936988e90e79bc","y":"5431a7268ff6931c7a759de024eff90bcb0177216db6fd1f3aaaa11fa3b6a083","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #704: extreme value for k and s^-1"} -{"x":"ab1c0f273f74abc2b848c75006f2ef3c54c26df27711b06558f455079aee0ba3","y":"df510f2ecef6d9a05997c776f14ad6456c179f0a13af1771e4d6c37fa48b47f2","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #705: extreme value for k"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #706: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #707: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #708: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #709: testing point duplication"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388","s":"f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b86","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1210: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"30e782f964b2e2ff065a051bc7adc20615d8c43a1365713c88268822c253bcce","s":"5b16df652aa1ecb2dc8b46c515f9604e2e84cacfa7c6eec30428d2d3f4e08ed5","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1211: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a","s":"0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2","hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","valid":true,"msg":"","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1212: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb71","s":"3dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c","hash":"de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90","valid":true,"msg":"0000000000000000000000000000000000000000","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1213: pseudorandom signature"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f1","s":"9b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1303: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"0fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b","s":"500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df55737","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1304: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3","s":"541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb55677","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1305: x-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a","s":"59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1306: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"4cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b43","s":"9638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1307: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04","s":"a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b55","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1308: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"1158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830","s":"228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f285519","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1309: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d","s":"3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a1251336","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1310: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86","s":"ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1311: y-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b4","s":"3dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd139929","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1312: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"5eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af78","s":"2c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb5","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1313: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"96843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28","s":"f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1314: x-coordinate of the public key has many trailing 1's"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6","s":"402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1315: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9","s":"edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dba","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1316: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84","s":"feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1317: x-coordinate of the public key is large"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7","s":"b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1318: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"6b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f7","s":"5939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1319: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361","s":"f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1320: x-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"31230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb07","s":"0f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beff","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1321: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743","s":"cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1322: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"7e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed800185945","s":"9450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aa","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1323: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b356","s":"89c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1324: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b34","s":"72b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1325: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"70bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67","s":"aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_test.json EcdsaVerify SHA-256 #1326: y-coordinate of the public key is large"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #1: signature malleability"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #3: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8","s":"b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #5: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18","s":"4cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #8: Modified r or s, e.g. by adding or subtracting the order of the group"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #9: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #10: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #11: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #12: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #13: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #14: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000000","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #15: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #16: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #17: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #18: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #19: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #20: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #21: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #22: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #23: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #24: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #25: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #26: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #27: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #28: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #29: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #30: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #31: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #32: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #33: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #34: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #35: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #36: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #37: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #38: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #39: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #40: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #41: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #42: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #43: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #44: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #45: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #46: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #47: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #48: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #49: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #50: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #51: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #52: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #53: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #54: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #55: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #56: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffffffff00000001000000000000000000000001000000000000000000000000","s":"ffffffff00000001000000000000000000000001000000000000000000000000","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":false,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #57: Signature with special case values for r and s"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"64a1aab5000d0e804f3e2fc02bdee9be8ff312334e2ba16d11547c97711c898e","s":"6af015971cc30be6d1a206d4e013e0997772a2f91d73286ffd683b9bb2cf4f1b","hash":"70239dd877f7c944c422f44dea4ed1a52f2627416faf2f072fa50c772ed6f807","valid":true,"msg":"3639383139","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #58: Edge case for Shamir multiplication"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"16aea964a2f6506d6f78c81c91fc7e8bded7d397738448de1e19a0ec580bf266","s":"252cd762130c6667cfe8b7bc47d27d78391e8e80c578d1cd38c3ff033be928e9","hash":"00000000690ed426ccf17803ebe2bd0884bcd58a1bb5e7477ead3645f356e7a9","valid":true,"msg":"343236343739373234","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #59: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9cc98be2347d469bf476dfc26b9b733df2d26d6ef524af917c665baccb23c882","s":"093496459effe2d8d70727b82462f61d0ec1b7847929d10ea631dacb16b56c32","hash":"7300000000213f2a525c6035725235c2f696ad3ebb5ee47f140697ad25770d91","valid":true,"msg":"37313338363834383931","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #60: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"73b3c90ecd390028058164524dde892703dce3dea0d53fa8093999f07ab8aa43","s":"2f67b0b8e20636695bb7d8bf0a651c802ed25a395387b5f4188c0c4075c88634","hash":"ddf2000000005e0be0635b245f0b97978afd25daadeb3edb4a0161c27fe06045","valid":true,"msg":"3130333539333331363638","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #61: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bfab3098252847b328fadf2f89b95c851a7f0eb390763378f37e90119d5ba3dd","s":"bdd64e234e832b1067c2d058ccb44d978195ccebb65c2aaf1e2da9b8b4987e3b","hash":"67ab1900000000784769c4ecb9e164d6642b8499588b89855be1ec355d0841a0","valid":true,"msg":"33393439343031323135","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #62: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"204a9784074b246d8bf8bf04a4ceb1c1f1c9aaab168b1596d17093c5cd21d2cd","s":"51cce41670636783dc06a759c8847868a406c2506fe17975582fe648d1d88b52","hash":"a2bf09460000000076d7dbeffe125eaf02095dff252ee905e296b6350fc311cf","valid":true,"msg":"31333434323933303739","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #63: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ed66dc34f551ac82f63d4aa4f81fe2cb0031a91d1314f835027bca0f1ceeaa03","s":"99ca123aa09b13cd194a422e18d5fda167623c3f6e5d4d6abb8953d67c0c48c7","hash":"3554e827c700000000e1e75e624a06b3a0a353171160858129e15c544e4f0e65","valid":true,"msg":"33373036323131373132","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #64: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"060b700bef665c68899d44f2356a578d126b062023ccc3c056bf0f60a237012b","s":"8d186c027832965f4fcc78a3366ca95dedbb410cbef3f26d6be5d581c11d3610","hash":"9b6cd3b812610000000026941a0f0bb53255ea4c9fd0cb3426e3a54b9fc6965c","valid":true,"msg":"333433363838373132","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #65: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9f6adfe8d5eb5b2c24d7aa7934b6cf29c93ea76cd313c9132bb0c8e38c96831d","s":"b26a9c9e40e55ee0890c944cf271756c906a33e66b5bd15e051593883b5e9902","hash":"883ae39f50bf0100000000e7561c26fc82a52baa51c71ca877162f93c4ae0186","valid":true,"msg":"31333531353330333730","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #66: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a1af03ca91677b673ad2f33615e56174a1abf6da168cebfa8868f4ba273f16b7","s":"20aa73ffe48afa6435cd258b173d0c2377d69022e7d098d75caf24c8c5e06b1c","hash":"a1ce5d6e5ecaf28b0000000000fa7cd010540f420fb4ff7401fe9fce011d0ba6","valid":true,"msg":"36353533323033313236","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #67: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"fdc70602766f8eed11a6c99a71c973d5659355507b843da6e327a28c11893db9","s":"3df5349688a085b137b1eacf456a9e9e0f6d15ec0078ca60a7f83f2b10d21350","hash":"8ea5f645f373f580930000000038345397330012a8ee836c5494cdffd5ee8054","valid":true,"msg":"31353634333436363033","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #68: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"b516a314f2fce530d6537f6a6c49966c23456f63c643cf8e0dc738f7b876e675","s":"d39ffd033c92b6d717dd536fbc5efdf1967c4bd80954479ba66b0120cd16fff2","hash":"660570d323e9f75fa734000000008792d65ce93eabb7d60d8d9c1bbdcb5ef305","valid":true,"msg":"34343239353339313137","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #69: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"3b2cbf046eac45842ecb7984d475831582717bebb6492fd0a485c101e29ff0a8","s":"4c9b7b47a98b0f82de512bc9313aaf51701099cac5f76e68c8595fc1c1d99258","hash":"d0462673154cce587dde8800000000e98d35f1f45cf9c3bf46ada2de4c568c34","valid":true,"msg":"3130393533323631333531","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #70: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"30c87d35e636f540841f14af54e2f9edd79d0312cfa1ab656c3fb15bfde48dcf","s":"47c15a5a82d24b75c85a692bd6ecafeb71409ede23efd08e0db9abf6340677ed","hash":"bd90640269a7822680cedfef000000000caef15a6171059ab83e7b4418d7278f","valid":true,"msg":"35393837333530303431","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #71: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"38686ff0fda2cef6bc43b58cfe6647b9e2e8176d168dec3c68ff262113760f52","s":"067ec3b651f422669601662167fa8717e976e2db5e6a4cf7c2ddabb3fde9d67d","hash":"33239a52d72f1311512e41222a00000000d2dcceb301c54b4beae8e284788a73","valid":true,"msg":"33343633303036383738","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #72: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"44a3e23bf314f2b344fc25c7f2de8b6af3e17d27f5ee844b225985ab6e2775cf","s":"2d48e223205e98041ddc87be532abed584f0411f5729500493c9cc3f4dd15e86","hash":"b8d64fbcd4a1c10f1365d4e6d95c000000007ee4a21a1cbe1dc84c2d941ffaf1","valid":true,"msg":"39383137333230323837","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #73: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ded5b7ec8e90e7bf11f967a3d95110c41b99db3b5aa8d330eb9d638781688e9","s":"7d5792c53628155e1bfc46fb1a67e3088de049c328ae1f44ec69238a009808f9","hash":"01603d3982bf77d7a3fef3183ed092000000003a227420db4088b20fe0e9d84a","valid":true,"msg":"33323232303431303436","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #74: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bdae7bcb580bf335efd3bc3d31870f923eaccafcd40ec2f605976f15137d8b8f","s":"f6dfa12f19e525270b0106eecfe257499f373a4fb318994f24838122ce7ec3c7","hash":"9ea6994f1e0384c8599aa02e6cf66d9c000000004d89ef50b7e9eb0cfbff7363","valid":true,"msg":"36363636333037313034","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #75: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"50f9c4f0cd6940e162720957ffff513799209b78596956d21ece251c2401f1c6","s":"d7033a0a787d338e889defaaabb106b95a4355e411a59c32aa5167dfab244726","hash":"d03215a8401bcf16693979371a01068a4700000000e2fa5bf692bc670905b18c","valid":true,"msg":"31303335393531383938","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #76: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"f612820687604fa01906066a378d67540982e29575d019aabe90924ead5c860d","s":"3f9367702dd7dd4f75ea98afd20e328a1a99f4857b316525328230ce294b0fef","hash":"307bfaaffb650c889c84bf83f0300e5dc87e000000008408fd5f64b582e3bb14","valid":true,"msg":"31383436353937313935","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #77: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"9505e407657d6e8bc93db5da7aa6f5081f61980c1949f56b0f2f507da5782a7a","s":"c60d31904e3669738ffbeccab6c3656c08e0ed5cb92b3cfa5e7f71784f9c5021","hash":"bab5c4f4df540d7b33324d36bb0c157551527c00000000e4af574bb4d54ea6b8","valid":true,"msg":"33313336303436313839","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #78: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bbd16fbbb656b6d0d83e6a7787cd691b08735aed371732723e1c68a40404517d","s":"9d8e35dba96028b7787d91315be675877d2d097be5e8ee34560e3e7fd25c0f00","hash":"d4ba47f6ae28f274e4f58d8036f9c36ec2456f5b00000000c3b869197ef5e15e","valid":true,"msg":"32363633373834323534","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #79: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2ec9760122db98fd06ea76848d35a6da442d2ceef7559a30cf57c61e92df327e","s":"7ab271da90859479701fccf86e462ee3393fb6814c27b760c4963625c0a19878","hash":"79fd19c7235ea212f29f1fa00984342afe0f10aafd00000000801e47f8c184e1","valid":true,"msg":"31363532313030353234","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #80: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"54e76b7683b6650baa6a7fc49b1c51eed9ba9dd463221f7a4f1005a89fe00c59","s":"2ea076886c773eb937ec1cc8374b7915cfd11b1c1ae1166152f2f7806a31c8fd","hash":"8c291e8eeaa45adbaf9aba5c0583462d79cbeb7ac97300000000a37ea6700cda","valid":true,"msg":"35373438303831363936","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #81: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5291deaf24659ffbbce6e3c26f6021097a74abdbb69be4fb10419c0c496c9466","s":"65d6fcf336d27cc7cdb982bb4e4ecef5827f84742f29f10abf83469270a03dc3","hash":"0eaae8641084fa979803efbfb8140732f4cdcf66c3f78a000000003c278a6b21","valid":true,"msg":"36333433393133343638","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #82: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"207a3241812d75d947419dc58efb05e8003b33fc17eb50f9d15166a88479f107","s":"cdee749f2e492b213ce80b32d0574f62f1c5d70793cf55e382d5caadf7592767","hash":"e02716d01fb23a5a0068399bf01bab42ef17c6d96e13846c00000000afc0f89d","valid":true,"msg":"31353431313033353938","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #83: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"6554e49f82a855204328ac94913bf01bbe84437a355a0a37c0dee3cf81aa7728","s":"aea00de2507ddaf5c94e1e126980d3df16250a2eaebc8be486effe7f22b4f929","hash":"9eb0bf583a1a6b9a194e9a16bc7dab2a9061768af89d00659a00000000fc7de1","valid":true,"msg":"3130343738353830313238","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #84: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a54c5062648339d2bff06f71c88216c26c6e19b4d80a8c602990ac82707efdfc","s":"e99bbe7fcfafae3e69fd016777517aa01056317f467ad09aff09be73c9731b0d","hash":"62aac98818b3b84a2c214f0d5e72ef286e1030cb53d9a82b690e00000000cd15","valid":true,"msg":"3130353336323835353638","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #85: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"975bd7157a8d363b309f1f444012b1a1d23096593133e71b4ca8b059cff37eaf","s":"7faa7a28b1c822baa241793f2abc930bd4c69840fe090f2aacc46786bf919622","hash":"3760a7f37cf96218f29ae43732e513efd2b6f552ea4b6895464b9300000000c8","valid":true,"msg":"393533393034313035","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #86: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5694a6f84b8f875c276afd2ebcfe4d61de9ec90305afb1357b95b3e0da43885e","s":"0dffad9ffd0b757d8051dec02ebdf70d8ee2dc5c7870c0823b6ccc7c679cbaa4","hash":"0da0a1d2851d33023834f2098c0880096b4320bea836cd9cbb6ff6c800000000","valid":true,"msg":"393738383438303339","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #87: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"a0c30e8026fdb2b4b4968a27d16a6d08f7098f1a98d21620d7454ba9790f1ba6","s":"5e470453a8a399f15baf463f9deceb53acc5ca64459149688bd2760c65424339","hash":"ffffffff293886d3086fd567aafd598f0fe975f735887194a764a231e82d289a","valid":true,"msg":"33363130363732343432","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #88: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"614ea84acf736527dd73602cd4bb4eea1dfebebd5ad8aca52aa0228cf7b99a88","s":"737cc85f5f2d2f60d1b8183f3ed490e4de14368e96a9482c2a4dd193195c902f","hash":"7bffffffff2376d1e3c03445a072e24326acdc4ce127ec2e0e8d9ca99527e7b7","valid":true,"msg":"31303534323430373035","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #89: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"bead6734ebe44b810d3fb2ea00b1732945377338febfd439a8d74dfbd0f942fa","s":"6bb18eae36616a7d3cad35919fd21a8af4bbe7a10f73b3e036a46b103ef56e2a","hash":"a2b5ffffffffebb251b085377605a224bc80872602a6e467fd016807e97fa395","valid":true,"msg":"35313734343438313937","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #90: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"499625479e161dacd4db9d9ce64854c98d922cbf212703e9654fae182df9bad2","s":"42c177cf37b8193a0131108d97819edd9439936028864ac195b64fca76d9d693","hash":"641227ffffffff6f1b96fa5f097fcf3cc1a3c256870d45a67b83d0967d4b20c0","valid":true,"msg":"31393637353631323531","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #91: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"08f16b8093a8fb4d66a2c8065b541b3d31e3bfe694f6b89c50fb1aaa6ff6c9b2","s":"9d6455e2d5d1779748573b611cb95d4a21f967410399b39b535ba3e5af81ca2e","hash":"958415d8ffffffffabad03e2fc662dc3ba203521177502298df56f36600e0f8b","valid":true,"msg":"33343437323533333433","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #92: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"be26231b6191658a19dd72ddb99ed8f8c579b6938d19bce8eed8dc2b338cb5f8","s":"e1d9a32ee56cffed37f0f22b2dcb57d5c943c14f79694a03b9c5e96952575c89","hash":"f1d8de4858ffffffff1281093536f47fe13deb04e1fbe8fb954521b6975420f8","valid":true,"msg":"333638323634333138","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #93: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"15e76880898316b16204ac920a02d58045f36a229d4aa4f812638c455abe0443","s":"e74d357d3fcb5c8c5337bd6aba4178b455ca10e226e13f9638196506a1939123","hash":"0927895f2802ffffffff10782dd14a3b32dc5d47c05ef6f1876b95c81fc31def","valid":true,"msg":"33323631313938363038","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #94: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"352ecb53f8df2c503a45f9846fc28d1d31e6307d3ddbffc1132315cc07f16dad","s":"1348dfa9c482c558e1d05c5242ca1c39436726ecd28258b1899792887dd0a3c6","hash":"60907984aa7e8effffffff4f332862a10a57c3063fb5a30624cf6a0c3ac80589","valid":true,"msg":"39363738373831303934","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #95: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"4a40801a7e606ba78a0da9882ab23c7677b8642349ed3d652c5bfa5f2a9558fb","s":"3a49b64848d682ef7f605f2832f7384bdc24ed2925825bf8ea77dc5981725782","hash":"c6ff198484939170ffffffff0af42cda50f9a5f50636ea6942d6b9b8cd6ae1e2","valid":true,"msg":"34393538383233383233","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #96: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"eacc5e1a8304a74d2be412b078924b3bb3511bac855c05c9e5e9e44df3d61e96","s":"7451cd8e18d6ed1885dd827714847f96ec4bb0ed4c36ce9808db8f714204f6d1","hash":"de030419345ca15c75ffffffff8074799b9e0956cc43135d16dfbe4d27d7e68d","valid":true,"msg":"383234363337383337","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #97: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"2f7a5e9e5771d424f30f67fdab61e8ce4f8cd1214882adb65f7de94c31577052","s":"ac4e69808345809b44acb0b2bd889175fb75dd050c5a449ab9528f8f78daa10c","hash":"6f0e3eeaf42b28132b88fffffffff6c8665604d34acb19037e1ab78caaaac6ff","valid":true,"msg":"3131303230383333373736","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #98: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ffcda40f792ce4d93e7e0f0e95e1a2147dddd7f6487621c30a03d710b3300219","s":"79938b55f8a17f7ed7ba9ade8f2065a1fa77618f0b67add8d58c422c2453a49a","hash":"cdb549f773b3e62b3708d1ffffffffbe48f7c0591ddcae7d2cb222d1f8017ab9","valid":true,"msg":"313333383731363438","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #99: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"81f2359c4faba6b53d3e8c8c3fcc16a948350f7ab3a588b28c17603a431e39a8","s":"cd6f6a5cc3b55ead0ff695d06c6860b509e46d99fccefb9f7f9e101857f74300","hash":"2c3f26f96a3ac0051df4989bffffffff9fd64886c1dc4f9924d8fd6f0edb0484","valid":true,"msg":"333232313434313632","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #100: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"dfc8bf520445cbb8ee1596fb073ea283ea130251a6fdffa5c3f5f2aaf75ca808","s":"048e33efce147c9dd92823640e338e68bfd7d0dc7a4905b3a7ac711e577e90e7","hash":"ac18f8418c55a2502cb7d53f9affffffff5c31d89fda6a6b8476397c04edf411","valid":true,"msg":"3130363836363535353436","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #101: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ad019f74c6941d20efda70b46c53db166503a0e393e932f688227688ba6a5762","s":"93320eb7ca0710255346bdbb3102cdcf7964ef2e0988e712bc05efe16c199345","hash":"4f9618f98e2d3a15b24094f72bb5ffffffffa2fd3e2893683e5a6ab8cf0ee610","valid":true,"msg":"3632313535323436","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #102: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"ac8096842e8add68c34e78ce11dd71e4b54316bd3ebf7fffdeb7bd5a3ebc1883","s":"f5ca2f4f23d674502d4caf85d187215d36e3ce9f0ce219709f21a3aac003b7a8","hash":"422e82a3d56ed10a9cc21d31d37a25ffffffff67edf7c40204caae73ab0bc75a","valid":true,"msg":"37303330383138373734","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #103: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"677b2d3a59b18a5ff939b70ea002250889ddcd7b7b9d776854b4943693fb92f7","s":"6b4ba856ade7677bf30307b21f3ccda35d2f63aee81efd0bab6972cc0795db55","hash":"7075d245ccc3281b6e7b329ff738fbb417a5ffffffffa0842d9890b5cf95d018","valid":true,"msg":"35393234353233373434","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #104: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"479e1ded14bcaed0379ba8e1b73d3115d84d31d4b7c30e1f05e1fc0d5957cfb0","s":"918f79e35b3d89487cf634a4f05b2e0c30857ca879f97c771e877027355b2443","hash":"3c80de54cd9226989443d593fa4fd6597e280ebeffffffffc1847eb76c217a95","valid":true,"msg":"31343935353836363231","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #105: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"43dfccd0edb9e280d9a58f01164d55c3d711e14b12ac5cf3b64840ead512a0a3","s":"1dbe33fa8ba84533cd5c4934365b3442ca1174899b78ef9a3199f49584389772","hash":"de21754e29b85601980bef3d697ea2770ce891a8cdffffffffc7906aa794b39b","valid":true,"msg":"34303035333134343036","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #106: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5b09ab637bd4caf0f4c7c7e4bca592fea20e9087c259d26a38bb4085f0bbff11","s":"45b7eb467b6748af618e9d80d6fdcd6aa24964e5a13f885bca8101de08eb0d75","hash":"8f65d92927cfb86a84dd59623fb531bb599e4d5f7289ffffffff2f1f2f57881c","valid":true,"msg":"33303936343537353132","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #107: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"5e9b1c5a028070df5728c5c8af9b74e0667afa570a6cfa0114a5039ed15ee06f","s":"b1360907e2d9785ead362bb8d7bd661b6c29eeffd3c5037744edaeb9ad990c20","hash":"6b63e9a74e092120160bea3877dace8a2cc7cd0e8426cbfffffffffafc8c3ca8","valid":true,"msg":"32373834303235363230","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #108: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"0671a0a85c2b72d54a2fb0990e34538b4890050f5a5712f6d1a7a5fb8578f32e","s":"db1846bab6b7361479ab9c3285ca41291808f27fd5bd4fdac720e5854713694c","hash":"fc28259702a03845b6d75219444e8b43d094586e249c8699ffffffffe852512e","valid":true,"msg":"32363138373837343138","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #109: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7673f8526748446477dbbb0590a45492c5d7d69859d301abbaedb35b2095103a","s":"3dc70ddf9c6b524d886bed9e6af02e0e4dec0d417a414fed3807ef4422913d7c","hash":"1273b4502ea4e3bccee044ee8e8db7f774ecbcd52e8ceb571757ffffffffe20a","valid":true,"msg":"31363432363235323632","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #110: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"7f085441070ecd2bb21285089ebb1aa6450d1a06c36d3ff39dfd657a796d12b5","s":"249712012029870a2459d18d47da9aa492a5e6cb4b2d8dafa9e4c5c54a2b9a8b","hash":"08fb565610a79baa0c566c66228d81814f8c53a15b96e602fb49ffffffffff6e","valid":true,"msg":"36383234313839343336","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #111: special case hash"} -{"x":"2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838","y":"c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e","r":"914c67fb61dd1e27c867398ea7322d5ab76df04bc5aa6683a8e0f30a5d287348","s":"fa07474031481dda4953e3ac1959ee8cea7e66ec412b38d6c96d28f6d37304ea","hash":"d59291cc2cf89f3087715fcb1aa4e79aa2403f748e97d7cd28ecaefeffffffff","valid":true,"msg":"343834323435343235","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #112: special case hash"} -{"x":"d705d16f80987e2d9b1a6957d29ce22febf7d10fa515153182415c8361baaca4","y":"b1fc105ee5ce80d514ec1238beae2037a6f83625593620d460819e8682160926","r":"000000000000000000000000000000004319055358e8617b0c46353d039cdaab","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #113: k*G has a large x-coordinate"} -{"x":"d705d16f80987e2d9b1a6957d29ce22febf7d10fa515153182415c8361baaca4","y":"b1fc105ee5ce80d514ec1238beae2037a6f83625593620d460819e8682160926","r":"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #114: r too large"} -{"x":"3cd8d2f81d6953b0844c09d7b560d527cd2ef67056893eadafa52c8501387d59","y":"ee41fdb4d10402ce7a0c5e3b747adfa3a490b62a6b7719068903485c0bb6dc2d","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #115: r,s are large"} -{"x":"8240cd81edd91cb6936133508c3915100e81f332c4545d41189b481196851378","y":"e05b06e72d4a1bff80ea5db514aa2f93ea6dd6d9c0ae27b7837dc432f9ce89d9","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"909135bdb6799286170f5ead2de4f6511453fe50914f3df2de54a36383df8dd4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #116: r and s^-1 have a large Hamming weight"} -{"x":"b062947356748b0fc17f1704c65aa1dca6e1bfe6779756fa616d91eaad13df2c","y":"0b38c17f3d0672e7409cfc5992a99fff12b84a4f8432293b431113f1b2fb579d","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"27b4577ca009376f71303fd5dd227dcef5deb773ad5f5a84360644669ca249a5","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #117: r and s^-1 have a large Hamming weight"} -{"x":"4a03ef9f92eb268cafa601072489a56380fa0dc43171d7712813b3a19a1eb5e5","y":"3e213e28a608ce9a2f4a17fd830c6654018a79b3e0263d91a8ba90622df6f2f0","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #118: small r and s"} -{"x":"091194c1cba17f34e286b4833701606a41cef26177ada8850b601ea1f859e701","y":"27242fcec708828758403ce2fe501983a7984e6209f4d6b95db9ad77767f55eb","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000003","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #120: small r and s"} -{"x":"103c6ecceff59e71ea8f56fee3a4b2b148e81c2bdbdd39c195812c96dcfb41a7","y":"2303a193dc591be150b883d770ec51ebb4ebce8b09042c2ecb16c448d8e57bf5","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000005","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #122: small r and s"} -{"x":"3b66b829fe604638bcb2bfe8c22228be67390c20111bd2b451468927e87fb6ea","y":"bc8e59c009361758b274ba2cad36b58fde485a3ed09dade76712fa9e9c4ac212","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"0000000000000000000000000000000000000000000000000000000000000006","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #124: small r and s"} -{"x":"3b66b829fe604638bcb2bfe8c22228be67390c20111bd2b451468927e87fb6ea","y":"bc8e59c009361758b274ba2cad36b58fde485a3ed09dade76712fa9e9c4ac212","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632556","s":"0000000000000000000000000000000000000000000000000000000000000006","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #126: r is larger than n"} -{"x":"4ff2f6c24e4a33cd71c09fdcbc74a6233961b874b8c8e0eb94582092cbc50c30","y":"84fa9547afda5c66335f3f937d4c79afa120486b534139d59ae82d61ead26420","r":"0000000000000000000000000000000000000000000000000000000000000005","s":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc75fbd8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #127: s is larger than n"} -{"x":"84b959080bb30859cd53c2fb973cf14d60cdaa8ee00587889b5bc657ac588175","y":"a02ce5c1e53cb196113c78b4cb8dc7d360e5ea7850b0f6650b0c45af2c3cd7ca","r":"0000000000000000000000000000000000000000000000000000000000000100","s":"8f1e3c7862c58b16bb76eddbb76eddbb516af4f63f2d74d76e0d28c9bb75ea88","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #128: small r and s^-1"} -{"x":"df4083bd6ecbda5a77ae578e5d835fa7f74a07ebb91e0570e1ff32a563354e99","y":"25af80b09a167d9ef647df28e2d9acd0d4bc4f2deec5723818edaf9071e311f8","r":"000000000000000000000000000000000000000000000000002d9b4d347952d6","s":"ef3043e7329581dbb3974497710ab11505ee1c87ff907beebadd195a0ffe6d7a","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #129: smallish r and s^-1"} -{"x":"c2569a3c9bf8c1838ca821f7ba6f000cc8679d278f3736b414a34a7c956a0377","y":"0387ea85bc4f28804b4a91c9b7d65bc6434c975806795ab7d441a4e9683aeb09","r":"000000000000000000000000000000000000001033e67e37b32b445580bf4eff","s":"8b748b74000000008b748b748b748b7466e769ad4a16d3dcd87129b8e91d1b4d","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #130: 100-bit r and small s^-1"} -{"x":"4a9f7da2a6c359a16540c271774a6bf1c586357c978256f44a6496d80670968a","y":"c496e73a44563f8d56fbd7bb9e4e3ae304c86f2c508eb777b03924755beb40d4","r":"0000000000000000000000000000000000000000000000000000000000000100","s":"ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #131: small r and 100 bit s^-1"} -{"x":"874146432b3cd2c9e26204c0a34136996067d466dde4917a8ff23a8e95ca106b","y":"709b3d50976ef8b385a813bc35f3a20710bdc6edd465e6f43ac4866703a6608c","r":"00000000000000000000000000000000000000062522bbd3ecbe7c39e93e7c25","s":"ef9f6ba4d97c09d03178fa20b4aaad83be3cf9cb824a879fec3270fc4b81ef5b","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #132: 100-bit r and s^-1"} -{"x":"7a736d8e326a9ca62bbe25a34ea4e3633b499a96afa7aaa3fcf3fd88f8e07ede","y":"b3e45879d8622b93e818443a686e869eeda7bf9ae46aa3eafcc48a5934864627","r":"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6324d5","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #133: r and s^-1 are close to n"} -{"x":"e84d9b232e971a43382630f99725e423ec1ecb41e55172e9c69748a03f0d5988","y":"618b15b427ad83363bd041ff75fac98ef2ee923714e7d1dfe31753793c7588d4","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"0000000000000000000000000000000000000000000000000000000000000001","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #134: s == 1"} -{"x":"e84d9b232e971a43382630f99725e423ec1ecb41e55172e9c69748a03f0d5988","y":"618b15b427ad83363bd041ff75fac98ef2ee923714e7d1dfe31753793c7588d4","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"0000000000000000000000000000000000000000000000000000000000000000","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #135: s == 0"} -{"x":"0203736fcb198b15d8d7a0c80f66dddd15259240aa78d08aae67c467de045034","y":"34383438d5041ea9a387ee8e4d4e84b4471b160c6bcf2568b072f8f20e87a996","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #136: point at infinity during verify"} -{"x":"78d844dc7f16b73b1f2a39730da5d8cd99fe2e70a18482384e37dcd2bfea02e1","y":"ed6572e01eb7a8d113d02c666c45ef22d3b9a6a6dea99aa43a8183c26e75d336","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #137: edge case for signature malleability"} -{"x":"dec6c8257dde94110eacc8c09d2e5789cc5beb81a958b02b4d62da9599a74014","y":"66fae1614174be63970b83f6524421067b06dd6f4e9c56baca4e344fdd690f1d","r":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","s":"7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #138: edge case for signature malleability"} -{"x":"a17f5b75a35ed64623ca5cbf1f91951292db0c23f0c2ea24c3d0cad0988cabc0","y":"83a7a618625c228940730b4fa3ee64faecbb2fc20fdde7c58b3a3f6300424dc6","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #139: u1 == 1"} -{"x":"04ba0cba291a37db13f33bf90dab628c04ec8393a0200419e9eaa1ebcc9fb5c3","y":"1f3a0a0e6823a49b625ad57b12a32d4047970fc3428f0f0049ecf4265dc12f62","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #140: u1 == n - 1"} -{"x":"692b6c828e0feed63d8aeaa2b7322f9ccbe8723a1ed39f229f204a434b8900ef","y":"a1f6f6abcb38ea3b8fde38b98c7c271f274af56a8c5628dc3329069ae4dd5716","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #141: u2 == 1"} -{"x":"00cefd9162d13e64cb93687a9cd8f9755ebb5a3ef7632f800f84871874ccef09","y":"543ecbeaf7e8044ef721be2fb5f549e4b8480d2587404ebf7dbbef2c54bc0cb1","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #142: u2 == n - 1"} -{"x":"b975183b42551cf52f291d5c1921fd5e12f50c8c85a4beb9de03efa3f0f24486","y":"2243018e6866df922dc313612020311ff21e242ce3fb15bc78c406b25ab43091","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"710f8e3edc7c2d5a3fd23de844002bb949d9f794f6d5405f6d97c1bb03dd2bd2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #143: edge case for u1"} -{"x":"c25f1d166f3e211cdf042a26f8abf6094d48b8d17191d74ed717149274466999","y":"65d06dd6a88abfa49e8b4c5da6bb922851969adf9604b5accfb52a114e77ccdb","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"edffbc270f722c243069a7e5f40335a61a58525c7b4db2e7a8e269274ffe4e1b","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #144: edge case for u1"} -{"x":"8fe5e88243a76e41a004236218a3c3a2d6eee398a23c3a0b008d7f0164cbc0ca","y":"98a20d1bdcf573513c7cfd9b83c63e3a82d40127c897697c86b8cb387af7f240","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"a25adcae105ed7ff4f95d2344e24ee523314c3e178525d007904b68919ba4d53","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #145: edge case for u1"} -{"x":"02148256b530fbc470c7b341970b38243ecee6d5a840a37beca2efb37e8dff2c","y":"c0adbea0882482a7489ca703a399864ba987eeb6ddb738af53a83573473cb30d","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"2e4348c645707dce6760d773de3f3e87346924b2f64bd3dd0297e766b5805ebb","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #146: edge case for u1"} -{"x":"a34db012ce6eda1e9c7375c5fcf3e54ed698e19615124273b3a621d021c76f8e","y":"777458d6f55a364c221e39e1205d5510bb4fbb7ddf08d8d8fdde13d1d6df7f14","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"348c673b07dce3920d773de3f3e87408869e916dbcf797d8f9684fb67753d1dc","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #147: edge case for u1"} -{"x":"b97af3fe78be15f2912b6271dd8a43badb6dd2a1b315b2ce7ae37b4e7778041d","y":"930d71ee1992d2466495c42102d08e81154c305307d1dcd52d0fa4c479b278e7","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"6918ce760fb9c7241aee7bc7e7d0e8110d3d22db79ef2fb1f2d09f6ceea7a3b8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #148: edge case for u1"} -{"x":"81e7198a3c3f23901cedc7a1d6eff6e9bf81108e6c35cd8559139af3135dbcbb","y":"9ef1568530291a8061b90c9f4285eefcba990d4570a4e3b7b737525b5d580034","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"73b3c694391d8eadde3f3e874089464715ac20e4c126bbf6d864d648969f5b5a","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #149: edge case for u1"} -{"x":"ab4d792ca121d1dba39cb9de645149c2ab573e8becc6ddff3cc9960f188ddf73","y":"7f90ba23664153e93262ff73355415195858d7be1315a69456386de68285a3c8","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bb07ac7a86948c2c2989a16db1930ef1b89ce112595197656877e53c41457f28","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #150: edge case for u1"} -{"x":"518412b69af43aae084476a68d59bbde51fbfa9e5be80563f587c9c2652f88ef","y":"2d3b90d25baa6bdb7b0c55e5240a3a98fbc24afed8523edec1c70503fc10f233","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"27e4d82cb6c061dd9337c69bf9332ed3d198662d6f2299443f62c861187db648","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #151: edge case for u1"} -{"x":"a08f14a644b9a935dffea4761ebaf592d1f66fe6cd373aa7f5d370af34f8352d","y":"a54b5bc4025cf335900a914c2934ec2fec7a396d0a7affcad732a5741c7aaaf5","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"e7c5cf3aac2e88923b77850515fff6a12d13b356dfe9ec275c3dd81ae94609a4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #152: edge case for u1"} -{"x":"ccf2296a6a89b62b90739d38af4ae3a20e9f45715b90044639241061e33f8f8c","y":"aace0046491eeaa1c6e9a472b96d88f4af83e7ff1bb84438c7e058034412ae08","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"c77838df91c1e953e016e10bddffea2317f9fee32bacfe553cede9e57a748f68","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #153: edge case for u1"} -{"x":"94b0fc1525bcabf82b1f34895e5819a06c02b23e04002276e165f962c86e3927","y":"be7c2ab4d0b25303204fb32a1f8292902792225e16a6d2dbfb29fbc89a9c3376","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"8ef071c02383d2a6c02dc217bbffd446730d0318b0425e2586220907f885f97f","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #154: edge case for u1"} -{"x":"5351f37e1de0c88c508527d89882d183ccdcf2efca407edb0627cadfd16de6ec","y":"44b4b57cdf960d32ebcc4c97847eed218425853b5b675eb781b766a1a1300349","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"5668aaa0b545bbf9a044a32399ffbe69ce20074e34d7bdf5cf56282a76976396","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #155: edge case for u1"} -{"x":"748bbafc320e6735cb64019710a269c6c2b5d147bdc831325cb2fb276ac971a6","y":"9d655e9a755bc9d800ad21ee3fd4d980d93a7a49a8c5ccd37005177578f51163","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"d12d6e56882f6c0027cae91a27127728f7fddf478fb4fdc2b65f40a60b0eb952","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #156: edge case for u1"} -{"x":"14b3bbd75c5e1c0c36535a934d4ab85112410b3b90fa97a31c33038964fd85cc","y":"112f7d837f8f9c36b460d636c965a5f818f2b50c5d00fb3f9705561dd6631883","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffffaaaaaaaaffffffffffffffffe9a2538f37b28a2c513dee40fecbb71a","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #157: edge case for u2"} -{"x":"d823533c04cd8edc6d6f950a8e08ade04a9bafa2f14a590356935671ae9305bf","y":"43178d1f88b6a57a96924c265f0ddb75b58312907b195acb59d7797303123775","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"b62f26b5f2a2b26f6de86d42ad8a13da3ab3cccd0459b201de009e526adf21f2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #158: edge case for u2"} -{"x":"db2b3408b3167d91030624c6328e8ce3ec108c105575c2f3d209b92e654bab69","y":"c34318139c50b0802c6e612f0fd3189d800df7c996d5d7b7c3d6be82836fa258","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bb1d9ac949dd748cd02bbbe749bd351cd57b38bb61403d700686aa7b4c90851e","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #159: edge case for u2"} -{"x":"09179ce7c59225392216453b2ac1e9d178c24837dfae26bc1dd7ab6063852742","y":"5556b42e330289f3b826b2db7a86d19d45c2860a59f2be1ddcc3b691f95a9255","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"66755a00638cdaec1c732513ca0234ece52545dac11f816e818f725b4f60aaf2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #160: edge case for u2"} -{"x":"01959fb8deda56e5467b7e4b214ea4c2d0c2fb29d70ff19b6b1eccebd6568d7e","y":"d9dbd77a918297fd970bff01e1343f6925167db5a14d098a211c39cc3a413398","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"55a00c9fcdaebb6032513ca0234ecfffe98ebe492fdf02e48ca48e982beb3669","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #161: edge case for u2"} -{"x":"567f1fdc387e5350c852b4e8f8ba9d6d947e1c5dd7ccc61a5938245dd6bcab3a","y":"9960bebaf919514f9535c22eaaf0b5812857970e26662267b1f3eb1011130a11","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ab40193f9b5d76c064a27940469d9fffd31d7c925fbe05c919491d3057d66cd2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #162: edge case for u2"} -{"x":"3499f974ff4ca6bbb2f51682fd5f51762f9dd6dd2855262660b36d46d3e4bec2","y":"f498fae2487807e220119152f0122476c64d4fa46ddce85c4546630f0d5c5e81","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"ca0234ebb5fdcb13ca0234ecffffffffcb0dadbbc7f549f8a26b4408d0dc8600","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #163: edge case for u2"} -{"x":"2c5c01662cf00c1929596257db13b26ecf30d0f3ec4b9f0351b0f27094473426","y":"e986a086060d086eee822ddd2fc744247a0154b57f7a69c51d9fdafa484e4ac7","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff3ea3677e082b9310572620ae19933a9e65b285598711c77298815ad3","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #164: edge case for u2"} -{"x":"91d4cba813a04d86dbae94c23be6f52c15774183be7ba5b2d9f3cf010b160501","y":"900b8adfea6491019a9ac080d516025a541bf4b952b0ad7be4b1874b02fd544a","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"266666663bbbbbbbe6666666666666665b37902e023fab7c8f055d86e5cc41f4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #165: edge case for u2"} -{"x":"ef7fd0a3a36386638330ecad41e1a3b302af36960831d0210c614b948e8aa124","y":"ef0d6d800e4047d6d3c1be0fdeaf11fcd8cab5ab59c730eb34116e35a8c7d098","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff36db6db7a492492492492492146c573f4c6dfc8d08a443e258970b09","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #166: edge case for u2"} -{"x":"a521dab13cc9152d8ca77035a607fea06c55cc3ca5dbeb868cea92eafe93df2a","y":"7bfb9b28531996635e6a5ccaa2826a406ce1111bdb9c2e0ca36500418a2f43de","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"bfffffff2aaaaaab7fffffffffffffffc815d0e60b3e596ecb1ad3a27cfd49c4","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #167: edge case for u2"} -{"x":"474d58a4eec16e0d565f2187fe11d4e8e7a2683a12f38b4fc01d1237a81a1097","y":"6e55f73bb7cdda46bdb67ef77f6fd2969df2b67920fb5945fde3a517a6ded4cd","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"7fffffff55555555ffffffffffffffffd344a71e6f651458a27bdc81fd976e37","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #168: edge case for u2"} -{"x":"692da5cd4309d9a6e5cb525c37da8fa0879f7b57208cdabbf47d223a5b23a621","y":"40e0daa78cfdd207a7389aaed61738b17fc5fc3e6a5ed3397d2902e9125e6ab4","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"3fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192aa","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #169: edge case for u2"} -{"x":"85689b3e0775c7718a90279f14a8082cfcd4d1f1679274f4e9b8805c570a0670","y":"167fcc5ca734552e09afa3640f4a034e15b9b7ca661ec7ff70d3f240ebe705b1","r":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd","s":"5d8ecd64a4eeba466815ddf3a4de9a8e6abd9c5db0a01eb80343553da648428f","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #170: edge case for u2"} -{"x":"0158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237e","y":"2a964fc00d377a8592b8b61aafa7a4aaa7c7b9fd2b41d6e0e17bd1ba5677edcd","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #171: point duplication during verification"} -{"x":"0158137755b901f797a90d4ca8887e023cb2ef63b2ba2c0d455edaef42cf237e","y":"d569b03ef2c8857b6d4749e550585b5558384603d4be291f1e842e45a9881232","r":"6f2347cab7dd76858fe0555ac3bc99048c4aacafdfb6bcbe05ea6c42c4934569","s":"f21d907e3890916dc4fa1f4703c1e50d3f54ddf7383e44023a41de562aa18ed8","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #172: duplication bug"} -{"x":"38a084ffccc4ae2f8204be2abca9fb8ad4ab283b2aa50f13b6bb2347adabc69c","y":"a699799b77b1cc6dad271e88b899c12931986e958e1f5cf5653dddf7389365e2","r":"0000000000000000000000000000000000000000000000000000000000000001","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #173: point with x-coordinate 0"} -{"x":"664ce273320d918d8bdb2e61201b4549b36b7cdc54e33b84adb6f2c10aac831e","y":"49e68831f18bda2973ac3d76bfbc8c5ee1cceed2dd862e2dc7c915c736cef1f4","r":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aa9","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #175: comparison with point at infinity "} -{"x":"961691a5e960d07a301dbbad4d86247ec27d7089faeb3ddd1add395efff1e0fe","y":"7254622cc371866cdf990d2c5377790e37d1f1519817f09a231bd260a9e78aeb","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #176: extreme value for k and edgecase s"} -{"x":"5d283e13ce8ca60da868e3b0fb33e6b4f1074793274e2928250e71e2aca63e9c","y":"214dc74fa25371fb4d9e506d418ed9a1bfd6d0c8bb6591d3e0f44505a84886ce","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #177: extreme value for k and s^-1"} -{"x":"0fc351da038ae0803bd1d86514ae0462f9f8216551d9315aa9d297f792eef6a3","y":"41c74eed786f2d33da35360ca7aa925e753f00d6077a1e9e5fc339d634019c73","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #178: extreme value for k and s^-1"} -{"x":"a1e34c8f16d138673fee55c080547c2bfd4de7550065f638322bba9430ce4b60","y":"662be9bb512663aa4d7df8ab3f3b4181c5d44a7bdf42436620b7d8a6b81ac936","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #179: extreme value for k and s^-1"} -{"x":"7e1a8a8338d7fd8cf41d322a302d2078a87a23c7186150ed7cda6e52817c1bdf","y":"d0a9135a89d21ce821e29014b2898349254d748272b2d4eb8d59ee34c615377f","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #180: extreme value for k and s^-1"} -{"x":"5c19fe227a61abc65c61ee7a018cc9571b2c6f663ea33583f76a686f64be078b","y":"7b4a0d734940f613d52bc48673b457c2cf78492490a5cc5606c0541d17b24ddb","r":"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #181: extreme value for k"} -{"x":"db02d1f3421d600e9d9ef9e47419dba3208eed08c2d4189a5db63abeb2739666","y":"e0ed26967b9ada9ed7ffe480827f90a0d210d5fd8ec628e31715e6b24125512a","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"555555550000000055555555555555553ef7a8e48d07df81a693439654210c70","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #182: extreme value for k and edgecase s"} -{"x":"6222d1962655501893c29e441395b6c05711bd3ed5a0ef72cfab338b88229c4b","y":"aaae079cb44a1af070362aaa520ee24cac2626423b0bf81af1c54311d8e2fd23","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #183: extreme value for k and s^-1"} -{"x":"4ccfa24c67f3def7fa81bc99c70bb0419c0952ba599f4c03361da184b04cdca5","y":"db76b797f7f41d9c729a2219478a7e629728df870800be8cf6ca7a0a82153bfa","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"cccccccc00000000cccccccccccccccc971f2ef152794b9d8fc7d568c9e8eaa7","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #184: extreme value for k and s^-1"} -{"x":"ea1c72c91034036bac71402b6e9ecc4af3dbde7a99dc574061e99fefff9d84da","y":"b7dd057e75b78ac6f56e34eb048f0a9d29d5d055408c90d02bc2ea918c18cb63","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"3333333300000000333333333333333325c7cbbc549e52e763f1f55a327a3aaa","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #185: extreme value for k and s^-1"} -{"x":"c2879a66d86cb20b820b7795da2da62b38924f7817d1cd350d936988e90e79bc","y":"5431a7268ff6931c7a759de024eff90bcb0177216db6fd1f3aaaa11fa3b6a083","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"49249248db6db6dbb6db6db6db6db6db5a8b230d0b2b51dcd7ebf0c9fef7c185","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #186: extreme value for k and s^-1"} -{"x":"ab1c0f273f74abc2b848c75006f2ef3c54c26df27711b06558f455079aee0ba3","y":"df510f2ecef6d9a05997c776f14ad6456c179f0a13af1771e4d6c37fa48b47f2","r":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","s":"16a4502e2781e11ac82cbc9d1edd8c981584d13e18411e2f6e0478c34416e3bb","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #187: extreme value for k"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #188: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5","r":"acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #189: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #190: testing point duplication"} -{"x":"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296","y":"b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a","r":"acd155416a8b77f34089464733ff7cd39c400e9c69af7beb9eac5054ed2ec72c","s":"249249246db6db6ddb6db6db6db6db6dad4591868595a8ee6bf5f864ff7be0c2","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":false,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #191: testing point duplication"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"a8ea150cb80125d7381c4c1f1da8e9de2711f9917060406a73d7904519e51388","s":"f3ab9fa68bd47973a73b2d40480c2ba50c22c9d76ec217257288293285449b86","hash":"bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023","valid":true,"msg":"313233343030","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #269: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"30e782f964b2e2ff065a051bc7adc20615d8c43a1365713c88268822c253bcce","s":"5b16df652aa1ecb2dc8b46c515f9604e2e84cacfa7c6eec30428d2d3f4e08ed5","hash":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","valid":true,"msg":"54657374","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #270: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"b292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a","s":"0177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2","hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","valid":true,"msg":"","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #271: pseudorandom signature"} -{"x":"04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5","y":"87d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d","r":"986e65933ef2ed4ee5aada139f52b70539aaf63f00a91f29c69178490d57fb71","s":"3dafedfb8da6189d372308cbf1489bbbdabf0c0217d1c0ff0f701aaa7a694b9c","hash":"de47c9b27eb8d300dbb5f2c353e632c393262cf06340c4fa7f1b40c4cbd36f90","valid":true,"msg":"0000000000000000000000000000000000000000","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #272: pseudorandom signature"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"d434e262a49eab7781e353a3565e482550dd0fd5defa013c7f29745eff3569f1","s":"9b0c0a93f267fb6052fd8077be769c2b98953195d7bc10de844218305c6ba17a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #288: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"0fe774355c04d060f76d79fd7a772e421463489221bf0a33add0be9b1979110b","s":"500dcba1c69a8fbd43fa4f57f743ce124ca8b91a1f325f3fac6181175df55737","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #289: x-coordinate of the public key has many trailing 0's"} -{"x":"4f337ccfd67726a805e4f1600ae2849df3807eca117380239fbd816900000000","y":"ed9dea124cc8c396416411e988c30f427eb504af43a3146cd5df7ea60666d685","r":"bb40bf217bed3fb3950c7d39f03d36dc8e3b2cd79693f125bfd06595ee1135e3","s":"541bf3532351ebb032710bdb6a1bf1bfc89a1e291ac692b3fa4780745bb55677","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #290: x-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a","s":"59f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #291: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"4cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b43","s":"9638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #292: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"84fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000","r":"e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04","s":"a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b55","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #293: y-coordinate of the public key has many trailing 0's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"1158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf3466830","s":"228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f285519","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #294: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d","s":"3e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a1251336","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #295: y-coordinate of the public key has many trailing 1's"} -{"x":"3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935","y":"7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff","r":"b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86","s":"ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #296: y-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b4","s":"3dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd139929","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #297: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"5eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af78","s":"2c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb5","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #298: x-coordinate of the public key has many trailing 1's"} -{"x":"2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff","y":"a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e","r":"96843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28","s":"f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #299: x-coordinate of the public key has many trailing 1's"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f6","s":"402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #300: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9","s":"edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dba","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #301: x-coordinate of the public key is large"} -{"x":"fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5","y":"5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73","r":"d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84","s":"feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #302: x-coordinate of the public key is large"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7","s":"b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb3","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #303: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"6b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f7","s":"5939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #304: x-coordinate of the public key is small"} -{"x":"00000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e","y":"1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71","r":"efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361","s":"f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #305: x-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"31230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb07","s":"0f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beff","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #306: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743","s":"cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #307: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2","r":"7e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed800185945","s":"9450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aa","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #308: y-coordinate of the public key is small"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b356","s":"89c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #309: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b34","s":"72b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #310: y-coordinate of the public key is large"} -{"x":"bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015","y":"fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d","r":"70bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67","s":"aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9","hash":"2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91","valid":true,"msg":"4d657373616765","comment":"wycheproof/ecdsa_webcrypto_test.json EcdsaP1363Verify SHA-256 #311: y-coordinate of the public key is large"} \ No newline at end of file diff --git a/grouperBot/lib/solady/test/ext/delegatexyz/DelegateCheckerLib.t.sol b/grouperBot/lib/solady/test/ext/delegatexyz/DelegateCheckerLib.t.sol deleted file mode 100644 index 35f4750..0000000 --- a/grouperBot/lib/solady/test/ext/delegatexyz/DelegateCheckerLib.t.sol +++ /dev/null @@ -1,543 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./../../utils/SoladyTest.sol"; -import {DelegateCheckerLib} from "../../../src/utils/ext/delegatexyz/DelegateCheckerLib.sol"; -import {FixedPointMathLib} from "../../../src/utils/FixedPointMathLib.sol"; - -interface IDelegateRegistryV1 { - function delegateForAll(address delegate, bool value) external; - function delegateForContract(address delegate, address contract_, bool value) external; - function delegateForToken(address delegate, address contract_, uint256 id, bool value) - external; - function checkDelegateForAll(address delegate, address vault) external view returns (bool); - function checkDelegateForContract(address delegate, address vault, address contract_) - external - view - returns (bool); - function checkDelegateForToken(address delegate, address vault, address contract_, uint256 id) - external - view - returns (bool); -} - -interface IDelegateRegistryV2 { - function delegateAll(address to, bytes32 rights, bool enable) - external - payable - returns (bytes32 delegationHash); - function delegateContract(address to, address contract_, bytes32 rights, bool enable) - external - payable - returns (bytes32 delegationHash); - function delegateERC721(address to, address contract_, uint256 id, bytes32 rights, bool enable) - external - payable - returns (bytes32 delegationHash); - function delegateERC20(address to, address contract_, bytes32 rights, uint256 amount) - external - payable - returns (bytes32 delegationHash); - function delegateERC1155( - address to, - address contract_, - uint256 id, - bytes32 rights, - uint256 amount - ) external payable returns (bytes32 delegationHash); - function checkDelegateForAll(address to, address from, bytes32 rights) - external - view - returns (bool); - function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) - external - view - returns (bool); - function checkDelegateForERC721( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) external view returns (bool); - function checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) - external - view - returns (uint256); - function checkDelegateForERC1155( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) external view returns (uint256); -} - -contract DelegateCheckerLibTest is SoladyTest { - IDelegateRegistryV1 v1; - IDelegateRegistryV2 v2; - bool testForGas; - - function setUp() public { - vm.etch( - DelegateCheckerLib.DELEGATE_REGISTRY_V1, - hex"608060405234801561001057600080fd5b50600436106101005760003560e01c8063685ee3e811610097578063aba69cf811610066578063aba69cf81461021c578063ed4b878e1461022f578063f956cf9414610242578063fa352c001461026257600080fd5b8063685ee3e8146101c35780636f007d87146101d657806390c9a2d0146101f65780639c395bc21461020957600080fd5b806336137872116100d3578063361378721461017557806349c95d291461017d5780634fc6928214610190578063537a5c3d146101b057600080fd5b806301ffc9a7146101055780631221156b1461012d5780631b61f6751461014d578063219044b014610160575b600080fd5b61011861011336600461138f565b610275565b60405190151581526020015b60405180910390f35b61014061013b3660046113d5565b6102ac565b6040516101249190611411565b61014061015b36600461145e565b6102c3565b61017361016e36600461145e565b6102d3565b005b6101736102e0565b61017361018b366004611489565b610336565b6101a361019e36600461145e565b6103ad565b60405161012491906114e2565b6101736101be36600461157f565b6105e8565b6101736101d13660046115cc565b610667565b6101e96101e436600461145e565b6106d4565b60405161012491906115ff565b610118610204366004611665565b61084d565b61011861021736600461169f565b6108f8565b61011861022a3660046116c9565b61097e565b61014061023d36600461169f565b610a33565b61025561025036600461145e565b610a4a565b6040516101249190611714565b61017361027036600461145e565b610baa565b60006001600160e01b03198216630596d3d560e01b14806102a657506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606102bb8460038585610bb4565b949350505050565b60606102a6826001600080610bb4565b6102dd3382610e2e565b50565b33600090815260016020526040812080549091906102fd90611779565b909155506040513381527f32d74befd0b842e19694e3e3af46263e18bcce41352c8b600ff0002b49edf6629060200160405180910390a1565b6000610343338585610eac565b9050610356848284600233886000610f1e565b604080513381526001600160a01b038681166020830152851681830152831515606082015290517f8d6b2f5255b8d815cc368855b2251146e003bf4e2fcccaec66145fff5c174b4f9181900360800190a150505050565b6001600160a01b03811660009081526003602052604081206060916103d182611100565b905060008167ffffffffffffffff8111156103ee576103ee611792565b60405190808252806020026020018201604052801561044757816020015b6040805160a08101825260008082526020808301829052928201819052606082018190526080820152825260001990920191018161040c5790505b50935060005b828110156105cd576000610461858361110a565b600081815260046020526040808220815160a0810190925280549394509192909190829060ff166003811115610499576104996114cc565b60038111156104aa576104aa6114cc565b815281546001600160a01b03610100909104811660208084019190915260018085015483166040850152600285015490921660608401526003909301546080909201919091529082015182519293509190600090826003811115610510576105106114cc565b0361052e5761051f838c611116565b8503610529575060015b61058d565b6002826003811115610542576105426114cc565b036105565761051f838c8660600151610eac565b600382600381111561056a5761056a6114cc565b0361058d57610583838c86606001518760800151611184565b850361058d575060015b80156105bd57838a8861059f81611779565b9950815181106105b1576105b16117a8565b60200260200101819052505b856001019550505050505061044d565b50808211156105e0578351818303900384525b505050919050565b60006105f633868686611184565b90506106088582846003338989610f1e565b604080513381526001600160a01b03878116602083015286168183015260608101859052831515608082015290517fe89c6ba1e8957285aed22618f52aa1dcb9d5bb64e1533d8b55136c72fcf5aa5d9181900360a00190a15050505050565b60006106733384611116565b9050610686838284600133600080610f1e565b604080513381526001600160a01b03851660208201528315158183015290517f58781eab4a0743ab1c285a238be846a235f06cdb5b968030573a635e5f8c92fa9181900360600190a1505050565b6001600160a01b03811660009081526020818152604080832060018352818420548452909152812060609161070882611100565b905060008167ffffffffffffffff81111561072557610725611792565b60405190808252806020026020018201604052801561077057816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816107435790505b50935060005b828110156105cd57600061078a858361110a565b60008181526004602052604090209091506003815460ff1660038111156107b3576107b36114cc565b03610843576001810154600282015460038301546107e1928b926001600160a01b0391821692911690611184565b8203610843576040805160608101825260028301546001600160a01b0390811682526003840154602083015260018401541691810191909152878561082581611779565b965081518110610837576108376117a8565b60200260200101819052505b5050600101610776565b6001600160a01b03828116600081815260016020908152604080832054600283528184208987168086529084528285205483518086019290925281840187905296881660608201526080810182905260a0808201979097528251808203909701875260c00182528551958301959095209383528282528083209483529390529182206108d990826111f3565b6108ec576108e785856108f8565b6108ef565b60015b95945050505050565b6001600160a01b038181166000818152600160209081526040808320546002835281842095881680855295835281842054825180850197909752868301869052606087018290526080808801919091528251808803909101815260a090960182528551958301959095209383528282528083209483529390529182206102bb90826111f3565b6001600160a01b03808416600090815260016020908152604080832054600283528184209489168452938252808320549051929384936109c9938a938a938a938a93919291016117be565b60408051601f1981840301815291815281516020928301206001600160a01b0388166000908152808452828120600185528382205482529093529120909150610a1290826111f3565b610a2657610a2186868661084d565b610a29565b60015b9695505050505050565b6060610a43836002846000610bb4565b9392505050565b6001600160a01b038116600090815260208181526040808320600183528184205484529091528120606091610a7e82611100565b905060008167ffffffffffffffff811115610a9b57610a9b611792565b604051908082528060200260200182016040528015610ae057816020015b6040805180820190915260008082526020820152815260200190600190039081610ab95790505b50935060005b828110156105cd576000610afa858361110a565b60008181526004602052604090209091506002815460ff166003811115610b2357610b236114cc565b03610ba05760018101546002820154610b4a918a916001600160a01b039182169116610eac565b8203610ba0576040805180820190915260028201546001600160a01b03908116825260018301541660208201528785610b8281611779565b965081518110610b9457610b946117a8565b60200260200101819052505b5050600101610ae6565b6102dd8133610e2e565b6001600160a01b038416600090815260208181526040808320600183528184205484529091528120606091610be882611100565b905060008167ffffffffffffffff811115610c0557610c05611792565b604051908082528060200260200182016040528015610c2e578160200160208202803683370190505b50935060005b82811015610e10576000610c48858361110a565b6000818152600460205260409020909150896003811115610c6b57610c6b6114cc565b815460ff166003811115610c8157610c816114cc565b03610e065760018a6003811115610c9a57610c9a6114cc565b03610d0f576001810154610cb8908c906001600160a01b0316611116565b8203610d0a5760018101546001600160a01b03168785610cd781611779565b965081518110610ce957610ce96117a8565b60200260200101906001600160a01b031690816001600160a01b0316815250505b610e06565b60028a6003811115610d2357610d236114cc565b03610d595760028101546001600160a01b03808b16911603610d0a576001810154610cb8908c906001600160a01b03168b610eac565b60038a6003811115610d6d57610d6d6114cc565b03610e065760028101546001600160a01b038a81169116148015610d945750878160030154145b15610e06576001810154610db4908c906001600160a01b03168b8b611184565b8203610e065760018101546001600160a01b03168785610dd381611779565b965081518110610de557610de56117a8565b60200260200101906001600160a01b031690816001600160a01b0316815250505b5050600101610c34565b5080821115610e23578351818303900384525b505050949350505050565b6001600160a01b03808216600090815260026020908152604080832093861683529290529081208054909190610e6390611779565b90915550604080516001600160a01b03831681523360208201527f3e34a3ee53064fb79c0ee57448f03774a627a9270b0c41286efb7d8e32dcde93910160405180910390a15050565b6001600160a01b0392831660008181526001602090815260408083205460028352818420968816808552968352928190205481518084019790975286820194909452939095166060850152608084015260a0808401919091528151808403909101815260c09092019052805191012090565b8415611060576001600160a01b038316600090815260208181526040808320600183528184205484529091529020610f56908761120b565b506001600160a01b0387166000908152600360205260409020610f79908761120b565b506040518060a00160405280856003811115610f9757610f976114cc565b81526001600160a01b038086166020808401919091528a82166040808501919091529186166060840152608090920184905260008981526004909252902081518154829060ff19166001836003811115610ff357610ff36114cc565b0217905550602082015181546001600160a01b0391821661010002610100600160a81b031990911617825560408301516001830180549183166001600160a01b031992831617905560608401516002840180549190931691161790556080909101516003909101556110f7565b6001600160a01b0383166000908152602081815260408083206001835281842054845290915290206110929087611217565b506001600160a01b03871660009081526003602052604090206110b59087611217565b50600086815260046020526040812080546001600160a81b03191681556001810180546001600160a01b03199081169091556002820180549091169055600301555b50505050505050565b60006102a6825490565b6000610a438383611223565b6001600160a01b03918216600081815260016020908152604080832054600283528184209590961680845294825291829020548251808301959095528483019390935260608401949094526080808401929092528051808403909201825260a0909201909152805191012090565b6001600160a01b0380851660009081526001602090815260408083205460028352818420948816845293825280832054905192939290916111d19188918a918991899188918891016117be565b6040516020818303038152906040528051906020012092505050949350505050565b60008181526001830160205260408120541515610a43565b6000610a43838361124d565b6000610a43838361129c565b600082600001828154811061123a5761123a6117a8565b9060005260206000200154905092915050565b6000818152600183016020526040812054611294575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102a6565b5060006102a6565b600081815260018301602052604081205480156113855760006112c06001836117f7565b85549091506000906112d4906001906117f7565b90508181146113395760008660000182815481106112f4576112f46117a8565b9060005260206000200154905080876000018481548110611317576113176117a8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061134a5761134a61180a565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102a6565b60009150506102a6565b6000602082840312156113a157600080fd5b81356001600160e01b031981168114610a4357600080fd5b80356001600160a01b03811681146113d057600080fd5b919050565b6000806000606084860312156113ea57600080fd5b6113f3846113b9565b9250611401602085016113b9565b9150604084013590509250925092565b6020808252825182820181905260009190848201906040850190845b818110156114525783516001600160a01b03168352928401929184019160010161142d565b50909695505050505050565b60006020828403121561147057600080fd5b610a43826113b9565b803580151581146113d057600080fd5b60008060006060848603121561149e57600080fd5b6114a7846113b9565b92506114b5602085016113b9565b91506114c360408501611479565b90509250925092565b634e487b7160e01b600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b838110156115715782518051600480821061152857634e487b7160e01b855260218152602485fd5b508652808801516001600160a01b039081168988015287820151811688880152606080830151909116908701526080908101519086015260a09094019391860191600101611500565b509298975050505050505050565b6000806000806080858703121561159557600080fd5b61159e856113b9565b93506115ac602086016113b9565b9250604085013591506115c160608601611479565b905092959194509250565b600080604083850312156115df57600080fd5b6115e8836113b9565b91506115f660208401611479565b90509250929050565b602080825282518282018190526000919060409081850190868401855b8281101561165857815180516001600160a01b03908116865287820151888701529086015116858501526060909301929085019060010161161c565b5091979650505050505050565b60008060006060848603121561167a57600080fd5b611683846113b9565b9250611691602085016113b9565b91506114c3604085016113b9565b600080604083850312156116b257600080fd5b6116bb836113b9565b91506115f6602084016113b9565b600080600080608085870312156116df57600080fd5b6116e8856113b9565b93506116f6602086016113b9565b9250611704604086016113b9565b9396929550929360600135925050565b602080825282518282018190526000919060409081850190868401855b8281101561165857815180516001600160a01b0390811686529087015116868501529284019290850190600101611731565b634e487b7160e01b600052601160045260246000fd5b60006001820161178b5761178b611763565b5060010190565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925260a081019190915260c00190565b818103818111156102a6576102a6611763565b634e487b7160e01b600052603160045260246000fdfea26469706673582212206b0b0a636b8da72fa85cb1817045c30ca104b227b960f8aae85f0c81f76bd66764736f6c63430008110033" - ); - vm.etch( - DelegateCheckerLib.DELEGATE_REGISTRY_V2, - hex"60806040526004361061015e5760003560e01c80638988eea9116100c0578063b9f3687411610074578063d90e73ab11610059578063d90e73ab14610383578063e839bd5314610396578063e8e834a9146103b657600080fd5b8063b9f3687414610343578063ba63c8171461036357600080fd5b8063ac9650d8116100a5578063ac9650d8146102f0578063b18e2bbb14610310578063b87058751461032357600080fd5b80638988eea9146102bd578063ab764683146102dd57600080fd5b806335faa416116101175780634705ed38116100fc5780634705ed381461025d57806351525e9a1461027d57806361451a301461029d57600080fd5b806335faa4161461021957806342f87c251461023057600080fd5b806301ffc9a71161014857806301ffc9a7146101b6578063063182a5146101e657806330ff31401461020657600080fd5b80623c2ba61461016357806301a920a014610189575b600080fd5b6101766101713660046120b4565b6103d5565b6040519081526020015b60405180910390f35b34801561019557600080fd5b506101a96101a43660046120f6565b610637565b6040516101809190612118565b3480156101c257600080fd5b506101d66101d136600461215c565b61066e565b6040519015158152602001610180565b3480156101f257600080fd5b506101a96102013660046120f6565b6106e1565b6101766102143660046121ae565b610712565b34801561022557600080fd5b5061022e6108f9565b005b34801561023c57600080fd5b5061025061024b3660046120f6565b610917565b6040516101809190612219565b34801561026957600080fd5b50610250610278366004612368565b610948565b34801561028957600080fd5b506102506102983660046120f6565b610bf0565b3480156102a957600080fd5b506101a96102b8366004612368565b610c21565b3480156102c957600080fd5b506101d66102d83660046123aa565b610cc6565b6101766102eb3660046123f5565b610dd8565b6103036102fe366004612368565b611056565b6040516101809190612442565b61017661031e366004612510565b61118d565b34801561032f57600080fd5b5061017661033e366004612567565b6113bd565b34801561034f57600080fd5b506101d661035e366004612567565b6115d8565b34801561036f57600080fd5b5061017661037e3660046123aa565b611767565b6101766103913660046125bc565b61192d565b3480156103a257600080fd5b506101d66103b1366004612609565b611b3f565b3480156103c257600080fd5b506101766103d1366004612645565b5490565b60408051603c810185905260288101869052336014820152838152605c902060081b6004176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156105865773ffffffffffffffffffffffffffffffffffffffff81166104ec57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301556104d582600486910155565b84156104e7576104e782600287910155565b6105d4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff82160161055d5781547fffffffffffffffffffffffff000000000000000000000000000000000000000016331782556104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036104e7576104e782600486910155565b3373ffffffffffffffffffffffffffffffffffffffff8216036105d45781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518681526020810186905273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f6ebd000dfc4dc9df04f723f827bae7694230795e8f22ed4af438e074cc982d1891015b60405180910390a45050949350505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611bc2565b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083169081147f5f68bc5a0000000000000000000000000000000000000000000000000000000090911417610668565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611bc2565b60408051602881018590523360148201528381526048902060081b6001176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156108555773ffffffffffffffffffffffffffffffffffffffff81166107eb57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8b16808552600283529084208054808501825590855291909320018690559184559083015584156107e6576107e682600287910155565b61089c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016107e65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561089c565b3373ffffffffffffffffffffffffffffffffffffffff82160361089c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff88169133917fda3ef6410e30373a9137f83f9781a8129962b6882532b7c229de2e39de423227910160405180910390a350509392505050565b6000806000804770de1e80ea5a234fb5488fee2584251bc7e85af150565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902060609061066890611d41565b60608167ffffffffffffffff8111156109635761096361265e565b6040519080825280602002602001820160405280156109e857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816109815790505b50905060005b82811015610be9576000610a25858584818110610a0d57610a0d61268d565b90506020020135600090815260208190526040902090565b90506000610a47825473ffffffffffffffffffffffffffffffffffffffff1690565b9050610a528161200f565b15610ab6576040805160e08101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0909101528451859085908110610aa657610aa661268d565b6020026020010181905250610bdf565b815460018301546040805160e08101825273ffffffffffffffffffffffffffffffffffffffff83169360a09390931c9290911c73ffffffffffffffff00000000000000000000000016919091179080610b278a8a89818110610b1a57610b1a61268d565b9050602002013560ff1690565b6005811115610b3857610b386121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001610b80866002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001610bac866003015490565b8152602001610bbc866004015490565b815250868681518110610bd157610bd161268d565b602002602001018190525050505b50506001016109ee565b5092915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902060609061066890611d41565b6060818067ffffffffffffffff811115610c3d57610c3d61265e565b604051908082528060200260200182016040528015610c66578160200160208202803683370190505b50915060008060005b83811015610cbc57868682818110610c8957610c8961268d565b9050602002013592508254915081858281518110610ca957610ca961268d565b6020908102919091010152600101610c6f565b5050505092915050565b6000610cd18461200f565b610dcc576040805160288101879052601481018690526000808252604890912060081b6001178152602081905220610d0a905b85612035565b80610d4a575060408051603c810185905260288101879052601481018690526000808252605c90912060081b6002178152602081905220610d4a90610d04565b9050801515821517610dcc576040805160288101879052601481018690528381526048902060081b6001176000908152602081905220610d8990610d04565b80610dc9575060408051603c81018590526028810187905260148101869052838152605c902060081b6002176000908152602081905220610dc990610d04565b90505b80151560005260206000f35b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6005176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315610f9c5773ffffffffffffffffffffffffffffffffffffffff8116610f0257336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b1790830155610edf82600388910155565b610eeb82600486910155565b8415610efd57610efd82600287910155565b610fea565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601610f735781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610efd57610efd82600486910155565b3373ffffffffffffffffffffffffffffffffffffffff821603610fea5781547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001178255600060048301555b604080518781526020810187905290810185905273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f27ab1adc9bca76301ed7a691320766dfa4b4b1aa32c9e05cf789611be7f8c75f906060015b60405180910390a4505095945050505050565b60608167ffffffffffffffff8111156110715761107161265e565b6040519080825280602002602001820160405280156110a457816020015b606081526020019060019003908161108f5790505b5090506000805b8381101561118557308585838181106110c6576110c661268d565b90506020028101906110d891906126bc565b6040516110e6929190612721565b600060405180830381855af49150503d8060008114611121576040519150601f19603f3d011682016040523d82523d6000602084013e611126565b606091505b508483815181106111395761113961268d565b602090810291909101015291508161117d576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001016110ab565b505092915050565b60408051605c8101859052603c810186905260288101879052336014820152838152607c902060081b6003176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff1683156113155773ffffffffffffffffffffffffffffffffffffffff81166112ab57336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8d168085526002835281852080548086018255908652929094209091018790558a901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a089901b179083015561129482600388910155565b84156112a6576112a682600287910155565b61135c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff8216016112a65781547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317825561135c565b3373ffffffffffffffffffffffffffffffffffffffff82160361135c5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051878152602081018790528515159181019190915273ffffffffffffffffffffffffffffffffffffffff80891691908a169033907f15e7a1bdcd507dd632d797d38e60cc5a9c0749b9a63097a215c4d006126825c690606001611043565b60006113c88561200f565b6115ce576040805160288101889052601481018790526000808252604890912060081b6001178152602081905220611401905b86612035565b80611441575060408051603c810186905260288101889052601481018790526000808252605c90912060081b6002178152602081905220611441906113fb565b61148e5760408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b6005178152602081905220611489905b6004015490565b6114b0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101889052601481018790528381526048902060081b60011760009081526020819052908120611513905b87612035565b80611553575060408051603c81018790526028810189905260148101889052848152605c902060081b60021760009081526020819052206115539061150d565b61159d5760408051605c8101869052603c81018790526028810189905260148101889052848152607c902060081b600517600090815260208190522061159890611482565b6115bf565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508181108282180281189150505b8060005260206000f35b60006115e38561200f565b610dcc576040805160288101889052601481018790526000808252604890912060081b600117815260208190522061161a906113fb565b8061165a575060408051603c810186905260288101889052601481018790526000808252605c90912060081b600217815260208190522061165a906113fb565b806116a1575060408051605c8101859052603c810186905260288101889052601481018790526000808252607c90912060081b60031781526020819052206116a1906113fb565b9050801515821517610dcc576040805160288101889052601481018790528381526048902060081b60011760009081526020819052206116e0906113fb565b80611720575060408051603c81018690526028810188905260148101879052838152605c902060081b6002176000908152602081905220611720906113fb565b80610dc9575060408051605c8101859052603c81018690526028810188905260148101879052838152607c902060081b6003176000908152602081905220610dc9906113fb565b60006117728461200f565b6115ce576040805160288101879052601481018690526000808252604890912060081b60011781526020819052206117a990610d04565b806117e9575060408051603c810185905260288101879052601481018690526000808252605c90912060081b60021781526020819052206117e990610d04565b61182c5760408051603c810185905260288101879052601481018690526000808252605c90912060081b600417815260208190522061182790611482565b61184e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81148215176115ce576040805160288101879052601481018690528381526048902060081b600117600090815260208190529081206118af906113fb565b806118ef575060408051603c81018690526028810188905260148101879052848152605c902060081b60021760009081526020819052206118ef906113fb565b61159d5760408051603c81018690526028810188905260148101879052848152605c902060081b600417600090815260208190522061159890611482565b60408051603c810185905260288101869052336014820152838152605c902060081b6002176000818152602081905291909120805473ffffffffffffffffffffffffffffffffffffffff168315611aa25773ffffffffffffffffffffffffffffffffffffffff8116611a3857336000818152600160208181526040808420805480850182559085528285200188905573ffffffffffffffffffffffffffffffffffffffff8c1680855260028352818520805480860182559086529290942090910187905589901b7bffffffffffffffff000000000000000000000000000000000000000016909217845560a088901b17908301558415611a3357611a3382600287910155565b611ae9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff821601611a335781547fffffffffffffffffffffffff00000000000000000000000000000000000000001633178255611ae9565b3373ffffffffffffffffffffffffffffffffffffffff821603611ae95781547fffffffffffffffffffffffff00000000000000000000000000000000000000001660011782555b60408051868152851515602082015273ffffffffffffffffffffffffffffffffffffffff80891692908a169133917f021be15e24de4afc43cfb5d0ba95ca38e0783571e05c12bbe6aece8842ae82df9101610625565b6000611b4a8361200f565b610dcc576040805160288101869052601481018590526000808252604890912060081b6001178152602081905220611b83905b84612035565b9050801515821517610dcc576040805160288101869052601481018590528381526048902060081b6001176000908152602081905220610dc990611b7d565b805460609060009081808267ffffffffffffffff811115611be557611be561265e565b604051908082528060200260200182016040528015611c0e578160200160208202803683370190505b50905060005b83811015611ca757868181548110611c2e57611c2e61268d565b90600052602060002001549250611c75611c70611c5685600090815260208190526040902090565b5473ffffffffffffffffffffffffffffffffffffffff1690565b61200f565b611c9f5782828680600101975081518110611c9257611c9261268d565b6020026020010181815250505b600101611c14565b508367ffffffffffffffff811115611cc157611cc161265e565b604051908082528060200260200182016040528015611cea578160200160208202803683370190505b50945060005b84811015611d3757818181518110611d0a57611d0a61268d565b6020026020010151868281518110611d2457611d2461268d565b6020908102919091010152600101611cf0565b5050505050919050565b805460609060009081808267ffffffffffffffff811115611d6457611d6461265e565b604051908082528060200260200182016040528015611d8d578160200160208202803683370190505b50905060005b83811015611e0757868181548110611dad57611dad61268d565b90600052602060002001549250611dd5611c70611c5685600090815260208190526040902090565b611dff5782828680600101975081518110611df257611df261268d565b6020026020010181815250505b600101611d93565b508367ffffffffffffffff811115611e2157611e2161265e565b604051908082528060200260200182016040528015611ea657816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611e3f5790505b5094506000805b8581101561200457828181518110611ec757611ec761268d565b60200260200101519350611ee684600090815260208190526040902090565b805460018201546040805160e08101825293955073ffffffffffffffffffffffffffffffffffffffff808416949083169360a09390931c9290911c73ffffffffffffffff0000000000000000000000001691909117908060ff89166005811115611f5257611f526121ea565b81526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001611f9a876002015490565b81526020018273ffffffffffffffffffffffffffffffffffffffff168152602001611fc6876003015490565b8152602001611fd6876004015490565b8152508a8581518110611feb57611feb61268d565b6020026020010181905250505050806001019050611ead565b505050505050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff8316908114901517610668565b6000612055835473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146120af57600080fd5b919050565b600080600080608085870312156120ca57600080fd5b6120d38561208b565b93506120e16020860161208b565b93969395505050506040820135916060013590565b60006020828403121561210857600080fd5b6121118261208b565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561215057835183529284019291840191600101612134565b50909695505050505050565b60006020828403121561216e57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461211157600080fd5b803580151581146120af57600080fd5b6000806000606084860312156121c357600080fd5b6121cc8461208b565b9250602084013591506121e16040850161219e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208082528251828201819052600091906040908185019086840185805b8381101561230e578251805160068110612278577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b86528088015173ffffffffffffffffffffffffffffffffffffffff1688870152868101516122bd8888018273ffffffffffffffffffffffffffffffffffffffff169052565b506060818101519087015260808082015173ffffffffffffffffffffffffffffffffffffffff169087015260a0808201519087015260c0908101519086015260e09094019391860191600101612237565b509298975050505050505050565b60008083601f84011261232e57600080fd5b50813567ffffffffffffffff81111561234657600080fd5b6020830191508360208260051b850101111561236157600080fd5b9250929050565b6000806020838503121561237b57600080fd5b823567ffffffffffffffff81111561239257600080fd5b61239e8582860161231c565b90969095509350505050565b600080600080608085870312156123c057600080fd5b6123c98561208b565b93506123d76020860161208b565b92506123e56040860161208b565b9396929550929360600135925050565b600080600080600060a0868803121561240d57600080fd5b6124168661208b565b94506124246020870161208b565b94979496505050506040830135926060810135926080909101359150565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b83811015612502577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089870301855282518051808852835b818110156124bd578281018a01518982018b015289016124a2565b508781018901849052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690960187019550938601939186019160010161246a565b509398975050505050505050565b600080600080600060a0868803121561252857600080fd5b6125318661208b565b945061253f6020870161208b565b9350604086013592506060860135915061255b6080870161219e565b90509295509295909350565b600080600080600060a0868803121561257f57600080fd5b6125888661208b565b94506125966020870161208b565b93506125a46040870161208b565b94979396509394606081013594506080013592915050565b600080600080608085870312156125d257600080fd5b6125db8561208b565b93506125e96020860161208b565b9250604085013591506125fe6060860161219e565b905092959194509250565b60008060006060848603121561261e57600080fd5b6126278461208b565b92506126356020850161208b565b9150604084013590509250925092565b60006020828403121561265757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126f157600080fd5b83018035915067ffffffffffffffff82111561270c57600080fd5b60200191503681900382131561236157600080fd5b818382376000910190815291905056fea164736f6c6343000815000a" - ); - v1 = IDelegateRegistryV1(DelegateCheckerLib.DELEGATE_REGISTRY_V1); - v2 = IDelegateRegistryV2(DelegateCheckerLib.DELEGATE_REGISTRY_V2); - } - - function _etchStopV1() internal { - vm.etch(DelegateCheckerLib.DELEGATE_REGISTRY_V1, hex"00"); - } - - function _etchStopV2() internal { - vm.etch(DelegateCheckerLib.DELEGATE_REGISTRY_V2, hex"00"); - } - - function _randomAmount() internal returns (uint256) { - if (testForGas) return 111; - uint256 r = _random(); - if (r & 0x03 == 0) return type(uint256).max; - if (r & 0x30 == 0) return 0; - return _random(); - } - - function _maybeDelegateAll(address to, address from, bytes32 rights) internal { - if (testForGas) return; - uint256 r = _random(); - if (r & 0x01 == 0) { - vm.prank(from); - v1.delegateForAll(to, true); - } - if (r & 0x10 == 0) { - vm.prank(from); - v2.delegateAll(to, rights, true); - } - } - - function _maybeDelegateContract(address to, address from, address contract_, bytes32 rights) - internal - { - if (testForGas) return; - uint256 r = _random(); - if (r & 0x001 == 0) { - vm.prank(from); - v1.delegateForContract(to, contract_, true); - } - if (r & 0x010 == 0) { - vm.prank(from); - v2.delegateContract(to, contract_, rights, true); - } - if (r & 0x100 == 0) _maybeDelegateAll(to, from, rights); - } - - function _maybeDelegateERC721( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal { - if (testForGas) return; - uint256 r = _random(); - if (r & 0x001 == 0) { - vm.prank(from); - v1.delegateForToken(to, contract_, id, true); - } - if (r & 0x010 == 0) { - vm.prank(from); - v2.delegateERC721(to, contract_, id, rights, true); - } - if (r & 0x100 == 0) { - _maybeDelegateContract(to, from, contract_, _maybeMutateRights(rights)); - } - } - - function _maybeDelegateERC20(address to, address from, address contract_, bytes32 rights) - internal - { - if (testForGas) return; - uint256 r = _random(); - if (r & 0x01 == 0) { - vm.prank(from); - v2.delegateERC20(to, contract_, rights, _randomAmount()); - } - if (r & 0x10 == 0) { - _maybeDelegateContract(to, from, contract_, _maybeMutateRights(rights)); - } - } - - function _maybeDelegateERC1155( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal { - if (testForGas) return; - uint256 r = _random(); - if (r & 0x01 == 0) { - vm.prank(from); - v2.delegateERC1155(to, contract_, id, rights, _randomAmount()); - } - if (r & 0x10 == 0) { - _maybeDelegateContract(to, from, contract_, _maybeMutateRights(rights)); - } - } - - function _maybeMutateRights(bytes32 rights) internal returns (bytes32) { - uint256 r = testForGas ? 0 : _random(); - if (r & 0xf0 == 0) return bytes32(0); - if (r & 0x07 == 0) return bytes32(_random()); - return rights; - } - - function _maybeMutateId(uint256 id) internal returns (uint256) { - uint256 r = testForGas ? 0 : _random(); - if (r & 0x01 == 0) return 0; - if (r & 0x10 == 0) return _random(); - return id; - } - - modifier maybeBrutalizeMemory() { - if (!testForGas) if (_random() & 1 == 0) _brutalizeLowerMemory(); - _; - if (!testForGas) _checkMemory(); - } - - function _checkDelegateForAll(address to, address from) - internal - maybeBrutalizeMemory - returns (bool) - { - return DelegateCheckerLib.checkDelegateForAll(_brutalized(to), _brutalized(from)); - } - - function _checkDelegateForAll(address to, address from, bytes32 rights) - internal - maybeBrutalizeMemory - returns (bool) - { - return DelegateCheckerLib.checkDelegateForAll(_brutalized(to), _brutalized(from), rights); - } - - function _checkDelegateForContract(address to, address from, address contract_) - internal - maybeBrutalizeMemory - returns (bool) - { - return DelegateCheckerLib.checkDelegateForContract( - _brutalized(to), _brutalized(from), _brutalized(contract_) - ); - } - - function _checkDelegateForContract(address to, address from, address contract_, bytes32 rights) - internal - maybeBrutalizeMemory - returns (bool) - { - return DelegateCheckerLib.checkDelegateForContract( - _brutalized(to), _brutalized(from), _brutalized(contract_), rights - ); - } - - function _checkDelegateForERC721(address to, address from, address contract_, uint256 id) - internal - maybeBrutalizeMemory - returns (bool) - { - return DelegateCheckerLib.checkDelegateForERC721( - _brutalized(to), _brutalized(from), _brutalized(contract_), id - ); - } - - function _checkDelegateForERC721( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal maybeBrutalizeMemory returns (bool) { - return DelegateCheckerLib.checkDelegateForERC721( - _brutalized(to), _brutalized(from), _brutalized(contract_), id, rights - ); - } - - function _checkDelegateForERC20(address to, address from, address contract_) - internal - maybeBrutalizeMemory - returns (uint256) - { - return DelegateCheckerLib.checkDelegateForERC20( - _brutalized(to), _brutalized(from), _brutalized(contract_) - ); - } - - function _checkDelegateForERC20(address to, address from, address contract_, bytes32 rights) - internal - maybeBrutalizeMemory - returns (uint256) - { - return DelegateCheckerLib.checkDelegateForERC20( - _brutalized(to), _brutalized(from), _brutalized(contract_), rights - ); - } - - function _checkDelegateForERC1155(address to, address from, address contract_, uint256 id) - internal - maybeBrutalizeMemory - returns (uint256) - { - return DelegateCheckerLib.checkDelegateForERC1155( - _brutalized(to), _brutalized(from), _brutalized(contract_), id - ); - } - - function _checkDelegateForERC1155( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) internal maybeBrutalizeMemory returns (uint256) { - return DelegateCheckerLib.checkDelegateForERC1155( - _brutalized(to), _brutalized(from), _brutalized(contract_), id, rights - ); - } - - function testCheckDelegateForAll() public { - testForGas = true; - testCheckDelegateForAll(address(111), address(222), bytes32(0)); - } - - function testCheckDelegateForAll(address to, address from, bytes32 rights) public { - _maybeDelegateAll(to, from, rights); - rights = _maybeMutateRights(rights); - assertEq( - _checkDelegateForAll(to, from), - v2.checkDelegateForAll(to, from, "") || v1.checkDelegateForAll(to, from) - ); - assertEq( - _checkDelegateForAll(to, from, rights), - v2.checkDelegateForAll(to, from, rights) - || (rights == "" && v1.checkDelegateForAll(to, from)) - ); - - if (testForGas) return; - if (_random() & 0x3 != 0) return; - _etchStopV2(); - assertEq(_checkDelegateForAll(to, from), v1.checkDelegateForAll(to, from)); - assertEq( - _checkDelegateForAll(to, from, rights), rights == "" && v1.checkDelegateForAll(to, from) - ); - _etchStopV1(); - assertFalse(_checkDelegateForAll(to, from)); - assertFalse(_checkDelegateForAll(to, from, rights)); - } - - function testCheckDelegateForContract() public { - testForGas = true; - testCheckDelegateForContract(address(111), address(222), address(333), bytes32(0)); - } - - function testCheckDelegateForContract( - address to, - address from, - address contract_, - bytes32 rights - ) public { - _maybeDelegateContract(to, from, contract_, rights); - rights = _maybeMutateRights(rights); - assertEq( - _checkDelegateForContract(to, from, contract_), - v2.checkDelegateForContract(to, from, contract_, "") - || v1.checkDelegateForContract(to, from, contract_) - ); - if (_checkDelegateForAll(to, from)) { - assertTrue(_checkDelegateForContract(to, from, contract_)); - } - assertEq( - _checkDelegateForContract(to, from, contract_, rights), - v2.checkDelegateForContract(to, from, contract_, rights) - || (rights == "" && v1.checkDelegateForContract(to, from, contract_)) - ); - if (_checkDelegateForAll(to, from, rights)) { - assertTrue(_checkDelegateForContract(to, from, contract_, rights)); - } - - if (testForGas) return; - if (_random() & 0x3 != 0) return; - _etchStopV2(); - assertEq( - _checkDelegateForContract(to, from, contract_), - v1.checkDelegateForContract(to, from, contract_) - ); - assertEq( - _checkDelegateForContract(to, from, contract_, rights), - rights == "" && v1.checkDelegateForContract(to, from, contract_) - ); - _etchStopV1(); - assertFalse(_checkDelegateForContract(to, from, contract_)); - assertFalse(_checkDelegateForContract(to, from, contract_, rights)); - } - - function testCheckDelegateForERC721() public { - testForGas = true; - testCheckDelegateForERC721(address(111), address(222), address(333), 1, bytes32(0)); - } - - function testCheckDelegateForERC721( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) public { - _maybeDelegateERC721(to, from, contract_, id, rights); - rights = _maybeMutateRights(rights); - id = _maybeMutateId(id); - assertEq( - _checkDelegateForERC721(to, from, contract_, id), - v2.checkDelegateForERC721(to, from, contract_, id, "") - || v1.checkDelegateForToken(to, from, contract_, id) - ); - if (_checkDelegateForContract(to, from, contract_)) { - assertTrue(_checkDelegateForERC721(to, from, contract_, id)); - } - assertEq( - _checkDelegateForERC721(to, from, contract_, id, rights), - v2.checkDelegateForERC721(to, from, contract_, id, rights) - || (rights == "" && v1.checkDelegateForToken(to, from, contract_, id)) - ); - if (_checkDelegateForContract(to, from, contract_, rights)) { - assertTrue(_checkDelegateForERC721(to, from, contract_, id, rights)); - } - - if (testForGas) return; - if (_random() & 0x3 != 0) return; - _etchStopV2(); - assertEq( - _checkDelegateForERC721(to, from, contract_, id), - v1.checkDelegateForToken(to, from, contract_, id) - ); - assertEq( - _checkDelegateForERC721(to, from, contract_, id, rights), - rights == "" && v1.checkDelegateForToken(to, from, contract_, id) - ); - _etchStopV1(); - assertFalse(_checkDelegateForERC721(to, from, contract_, id)); - assertFalse(_checkDelegateForERC721(to, from, contract_, id, rights)); - } - - function testCheckDelegateForERC20() public { - testForGas = true; - testCheckDelegateForERC20(address(111), address(222), address(333), bytes32(0)); - } - - function testCheckDelegateForERC20(address to, address from, address contract_, bytes32 rights) - public - { - _maybeDelegateERC20(to, from, contract_, rights); - rights = _maybeMutateRights(rights); - assertEq( - _checkDelegateForERC20(to, from, contract_), - FixedPointMathLib.max( - v2.checkDelegateForERC20(to, from, contract_, ""), - _uintMaxIfTrueElse0(v1.checkDelegateForContract(to, from, contract_)) - ) - ); - if (_checkDelegateForContract(to, from, contract_)) { - assertEq(_checkDelegateForERC20(to, from, contract_), type(uint256).max); - } - assertEq( - _checkDelegateForERC20(to, from, contract_, rights), - FixedPointMathLib.max( - v2.checkDelegateForERC20(to, from, contract_, rights), - _uintMaxIfTrueElse0( - rights == "" && v1.checkDelegateForContract(to, from, contract_) - ) - ) - ); - if (_checkDelegateForContract(to, from, contract_, rights)) { - assertEq(_checkDelegateForERC20(to, from, contract_, rights), type(uint256).max); - } - - if (testForGas) return; - if (_random() & 0x3 != 0) return; - _etchStopV2(); - assertEq( - _checkDelegateForERC20(to, from, contract_), - _uintMaxIfTrueElse0(v1.checkDelegateForContract(to, from, contract_)) - ); - assertEq( - _checkDelegateForERC20(to, from, contract_, rights), - _uintMaxIfTrueElse0(rights == "" && v1.checkDelegateForContract(to, from, contract_)) - ); - _etchStopV1(); - assertEq(_checkDelegateForERC20(to, from, contract_), 0); - assertEq(_checkDelegateForERC20(to, from, contract_, rights), 0); - } - - function testCheckDelegateForERC1155() public { - testForGas = true; - testCheckDelegateForERC1155(address(111), address(222), address(333), 11, bytes32(0)); - } - - function testCheckDelegateForERC1155( - address to, - address from, - address contract_, - uint256 id, - bytes32 rights - ) public { - _maybeDelegateERC1155(to, from, contract_, id, rights); - rights = _maybeMutateRights(rights); - id = _maybeMutateId(id); - assertEq( - _checkDelegateForERC1155(to, from, contract_, id), - FixedPointMathLib.max( - v2.checkDelegateForERC1155(to, from, contract_, id, ""), - _uintMaxIfTrueElse0(v1.checkDelegateForContract(to, from, contract_)) - ) - ); - if (_checkDelegateForContract(to, from, contract_)) { - assertEq(_checkDelegateForERC1155(to, from, contract_, id), type(uint256).max); - } - assertEq( - _checkDelegateForERC1155(to, from, contract_, id, rights), - FixedPointMathLib.max( - v2.checkDelegateForERC1155(to, from, contract_, id, rights), - _uintMaxIfTrueElse0( - rights == "" && v1.checkDelegateForContract(to, from, contract_) - ) - ) - ); - if (_checkDelegateForContract(to, from, contract_, rights)) { - assertEq(_checkDelegateForERC1155(to, from, contract_, id, rights), type(uint256).max); - } - - if (testForGas) return; - if (_random() & 0x3 != 0) return; - _etchStopV2(); - assertEq( - _checkDelegateForERC1155(to, from, contract_, id), - _uintMaxIfTrueElse0(v1.checkDelegateForContract(to, from, contract_)) - ); - assertEq( - _checkDelegateForERC1155(to, from, contract_, id, rights), - _uintMaxIfTrueElse0(rights == "" && v1.checkDelegateForContract(to, from, contract_)) - ); - _etchStopV1(); - assertEq(_checkDelegateForERC1155(to, from, contract_, id), 0); - assertEq(_checkDelegateForERC1155(to, from, contract_, id, rights), 0); - } - - function _uintMaxIfTrueElse0(bool b) internal pure returns (uint256) { - return b ? type(uint256).max : 0; - } -} diff --git a/grouperBot/lib/solady/test/ext/ithaca/BLS.t.sol b/grouperBot/lib/solady/test/ext/ithaca/BLS.t.sol deleted file mode 100644 index 7e3e3d2..0000000 --- a/grouperBot/lib/solady/test/ext/ithaca/BLS.t.sol +++ /dev/null @@ -1,293 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./../../utils/SoladyTest.sol"; -import {BLS} from "../../../src/utils/ext/ithaca/BLS.sol"; - -contract BLSTest is SoladyTest { - function G1_GENERATOR() internal pure returns (BLS.G1Point memory) { - return BLS.G1Point( - _u(31827880280837800241567138048534752271), - _u(88385725958748408079899006800036250932223001591707578097800747617502997169851), - _u(11568204302792691131076548377920244452), - _u(114417265404584670498511149331300188430316142484413708742216858159411894806497) - ); - } - - function NEGATED_G1_GENERATOR() internal pure returns (BLS.G1Point memory) { - return BLS.G1Point( - _u(31827880280837800241567138048534752271), - _u(88385725958748408079899006800036250932223001591707578097800747617502997169851), - _u(22997279242622214937712647648895181298), - _u(46816884707101390882112958134453447585552332943769894357249934112654335001290) - ); - } - - function _u(uint256 x) internal pure returns (bytes32) { - return bytes32(x); - } - - function testSignAndVerify() public { - // Obtain the private key as a random scalar. - bytes32 privateKey = bytes32(_randomUniform()); - - // Public key is the generator point multiplied by the private key. - BLS.G1Point memory publicKey = _blsg1mul(G1_GENERATOR(), privateKey); - - // Compute the message point by mapping message's keccak256 hash to a point in G2. - bytes memory message = "hello world"; - BLS.G2Point memory messagePoint = BLS.toG2(BLS.Fp2(0, 0, 0, keccak256(message))); - - // Obtain the signature by multiplying the message point by the private key. - BLS.G2Point memory signature = _blsg2mul(messagePoint, privateKey); - - // Invoke the pairing check to verify the signature. - BLS.G1Point[] memory g1Points = new BLS.G1Point[](2); - g1Points[0] = NEGATED_G1_GENERATOR(); - g1Points[1] = publicKey; - - BLS.G2Point[] memory g2Points = new BLS.G2Point[](2); - g2Points[0] = signature; - g2Points[1] = messagePoint; - - assertTrue(BLS.pairing(g1Points, g2Points)); - } - - function testSignAndVerifyAggregated() public { - // private keys - bytes32 sk1 = bytes32(_randomUniform()); - bytes32 sk2 = bytes32(_randomUniform()); - - // public keys - BLS.G1Point memory pk1 = _blsg1mul(G1_GENERATOR(), sk1); - BLS.G1Point memory pk2 = _blsg1mul(G1_GENERATOR(), sk2); - - // Compute the message point by mapping message's keccak256 hash to a point in G2. - bytes memory message = "hello world"; - BLS.G2Point memory messagePoint = BLS.toG2(BLS.Fp2(0, 0, 0, keccak256(message))); - - // signatures - BLS.G2Point memory sig1 = _blsg2mul(messagePoint, sk1); - BLS.G2Point memory sig2 = _blsg2mul(messagePoint, sk2); - - // aggregated signature - BLS.G2Point memory sig = BLS.add(sig1, sig2); - - // Invoke the pairing check to verify the signature. - BLS.G1Point[] memory g1Points = new BLS.G1Point[](3); - g1Points[0] = NEGATED_G1_GENERATOR(); - g1Points[1] = pk1; - g1Points[2] = pk2; - - BLS.G2Point[] memory g2Points = new BLS.G2Point[](3); - g2Points[0] = sig; - g2Points[1] = messagePoint; - g2Points[2] = messagePoint; - - assertTrue(BLS.pairing(g1Points, g2Points)); - } - - function testHashToCurveG2() public { - testHashToCurveG2("hehe"); - } - - function testHashToCurveG2(bytes memory message) public { - bytes memory expected = abi.encode(this.hashToCurveG2Original(message)); - bytes memory computed = abi.encode(this.hashToCurveG2OptimizedBrutalized(message)); - assertEq(computed, expected); - } - - function hashToCurveG2Optimized(bytes memory message) - public - view - returns (BLS.G2Point memory result) - { - result = BLS.hashToG2(message); - } - - function hashToCurveG2OptimizedBrutalized(bytes memory message) - public - view - returns (BLS.G2Point memory result) - { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - result = BLS.hashToG2(message); - _checkMemory(); - } - - /// @notice Computes a point in G2 from a message - /// @dev Uses the eip-2537 precompiles - /// @param message Arbitrarylength byte string to be hashed - /// @return A point in G2 - function hashToCurveG2Original(bytes memory message) public view returns (BLS.G2Point memory) { - // 1. u = hash_to_field(msg, 2) - BLS.Fp2[2] memory u = - _hashToFieldFp2(message, bytes("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_")); - // 2. Q0 = map_to_curve(u[0]) - BLS.G2Point memory q0 = BLS.toG2(u[0]); - // 3. Q1 = map_to_curve(u[1]) - BLS.G2Point memory q1 = BLS.toG2(u[1]); - // 4. R = Q0 + Q1 - return BLS.add(q0, q1); - } - - /// @notice Computes a field point from a message - /// @dev Follows https://datatracker.ietf.org/doc/html/rfc9380#section-5.2 - /// @param message Arbitrarylength byte string to be hashed - /// @param dst The domain separation tag - /// @return Two field points - function _hashToFieldFp2(bytes memory message, bytes memory dst) - private - view - returns (BLS.Fp2[2] memory) - { - // 1. len_in_bytes = count * m * L - // so always 2 * 2 * 64 = 256 - uint16 lenInBytes = 256; - // 2. uniform_bytes = expand_message(msg, DST, len_in_bytes) - bytes32[] memory pseudoRandomBytes = _expandMsgXmd(message, dst, lenInBytes); - BLS.Fp2[2] memory u; - // No loop here saves 800 gas hardcoding offset an additional 300 - // 3. for i in (0, ..., count - 1): - // 4. for j in (0, ..., m - 1): - // 5. elm_offset = L * (j + i * m) - // 6. tv = substr(uniform_bytes, elm_offset, HTF_L) - // uint8 HTF_L = 64; - // bytes memory tv = new bytes(64); - // 7. e_j = OS2IP(tv) mod p - // 8. u_i = (e_0, ..., e_(m - 1)) - // tv = bytes.concat(pseudo_random_bytes[0], pseudo_random_bytes[1]); - BLS.Fp memory t; - t = _modfield(pseudoRandomBytes[0], pseudoRandomBytes[1]); - u[0].c0_a = t.a; - u[0].c0_b = t.b; - t = _modfield(pseudoRandomBytes[2], pseudoRandomBytes[3]); - u[0].c1_a = t.a; - u[0].c1_b = t.b; - t = _modfield(pseudoRandomBytes[4], pseudoRandomBytes[5]); - u[1].c0_a = t.a; - u[1].c0_b = t.b; - t = _modfield(pseudoRandomBytes[6], pseudoRandomBytes[7]); - u[1].c1_a = t.a; - u[1].c1_b = t.b; - // 9. return (u_0, ..., u_(count - 1)) - return u; - } - - /// @notice Computes a field point from a message - /// @dev Follows https://datatracker.ietf.org/doc/html/rfc9380#section-5.3 - /// @dev bytes32[] because len_in_bytes is always a multiple of 32 in our case even 128 - /// @param message Arbitrarylength byte string to be hashed - /// @param dst The domain separation tag of at most 255 bytes - /// @param lenInBytes The length of the requested output in bytes - /// @return A field point - function _expandMsgXmd(bytes memory message, bytes memory dst, uint16 lenInBytes) - private - pure - returns (bytes32[] memory) - { - // 1. ell = ceil(len_in_bytes / b_in_bytes) - // b_in_bytes seems to be 32 for sha256 - // ceil the division - uint256 ell = (lenInBytes - 1) / 32 + 1; - - // 2. ABORT if ell > 255 or len_in_bytes > 65535 or len(DST) > 255 - require(ell <= 255, "len_in_bytes too large for sha256"); - // Not really needed because of parameter type - // require(lenInBytes <= 65535, "len_in_bytes too large"); - // no length normalizing via hashing - require(dst.length <= 255, "dst too long"); - - bytes memory dstPrime = bytes.concat(dst, bytes1(uint8(dst.length))); - - // 4. Z_pad = I2OSP(0, s_in_bytes) - // this should be sha256 blocksize so 64 bytes - bytes memory zPad = new bytes(64); - - // 5. l_i_b_str = I2OSP(len_in_bytes, 2) - // length in byte string? - bytes2 libStr = bytes2(lenInBytes); - - // 6. msg_prime = Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime - bytes memory msgPrime = bytes.concat(zPad, message, libStr, hex"00", dstPrime); - - // 7. b_0 = H(msg_prime) - bytes32 b_0 = sha256(msgPrime); - - bytes32[] memory b = new bytes32[](ell); - - // 8. b_1 = H(b_0 || I2OSP(1, 1) || DST_prime) - b[0] = sha256(bytes.concat(b_0, hex"01", dstPrime)); - - // 9. for i in (2, ..., ell): - for (uint8 i = 2; i <= ell; i++) { - // 10. b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime) - bytes memory tmp = abi.encodePacked(b_0 ^ b[i - 2], i, dstPrime); - b[i - 1] = sha256(tmp); - } - // 11. uniform_bytes = b_1 || ... || b_ell - // 12. return substr(uniform_bytes, 0, len_in_bytes) - // Here we don't need the uniform_bytes because b is already properly formed - return b; - } - - // passing two bytes32 instead of bytes memory saves approx 700 gas per call - // Computes the mod against the bls12-381 field modulus - function _modfield(bytes32 _b1, bytes32 _b2) private view returns (BLS.Fp memory r) { - (bool success, bytes memory output) = address(0x5).staticcall( - abi.encode( - // arg[0] = base.length - 0x40, - // arg[1] = exp.length - 0x20, - // arg[2] = mod.length - 0x40, - // arg[3] = base.bits - // places the first 32 bytes of _b1 and the last 32 bytes of _b2 - _b1, - _b2, - // arg[4] = exp - // exponent always 1 - 1, - // arg[5] = mod - // this field_modulus as hex 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 - // we add the 0 prefix so that the result will be exactly 64 bytes - // saves 300 gas per call instead of sending it along every time - // places the first 32 bytes and the last 32 bytes of the field modulus - 0x000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd7, - 0x64774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab - ) - ); - require(success, "MODEXP failed"); - return abi.decode(output, (BLS.Fp)); - } - - function _blsg1mul(BLS.G1Point memory g1, bytes32 scalar) - private - view - returns (BLS.G1Point memory) - { - BLS.G1Point[] memory points = new BLS.G1Point[](1); - bytes32[] memory scalars = new bytes32[](1); - - points[0] = g1; - scalars[0] = scalar; - - return BLS.msm(points, scalars); - } - - function _blsg2mul(BLS.G2Point memory g2, bytes32 scalar) - private - view - returns (BLS.G2Point memory) - { - BLS.G2Point[] memory points = new BLS.G2Point[](1); - bytes32[] memory scalars = new bytes32[](1); - - points[0] = g2; - scalars[0] = scalar; - - return BLS.msm(points, scalars); - } -} diff --git a/grouperBot/lib/solady/test/ext/zksync/ERC1155.t.sol b/grouperBot/lib/solady/test/ext/zksync/ERC1155.t.sol deleted file mode 100644 index a7dbbb6..0000000 --- a/grouperBot/lib/solady/test/ext/zksync/ERC1155.t.sol +++ /dev/null @@ -1,1221 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./../../utils/SoladyTest.sol"; - -import {ERC1155, MockERC1155} from "./../../utils/mocks/ext/zksync/MockERC1155.sol"; - -abstract contract ERC1155TokenReceiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - external - virtual - returns (bytes4) - { - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual returns (bytes4) { - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} - -contract ERC1155Recipient is ERC1155TokenReceiver { - address public operator; - address public from; - uint256 public id; - uint256 public amount; - bytes public mintData; - - function onERC1155Received( - address _operator, - address _from, - uint256 _id, - uint256 _amount, - bytes calldata _data - ) public override returns (bytes4) { - operator = _operator; - from = _from; - id = _id; - amount = _amount; - mintData = _data; - - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - address public batchOperator; - address public batchFrom; - uint256[] internal _batchIds; - uint256[] internal _batchAmounts; - bytes public batchData; - - function batchIds() external view returns (uint256[] memory) { - return _batchIds; - } - - function batchAmounts() external view returns (uint256[] memory) { - return _batchAmounts; - } - - function onERC1155BatchReceived( - address _operator, - address _from, - uint256[] calldata _ids, - uint256[] calldata _amounts, - bytes calldata _data - ) external override returns (bytes4) { - batchOperator = _operator; - batchFrom = _from; - _batchIds = _ids; - _batchAmounts = _amounts; - batchData = _data; - - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} - -contract RevertingERC1155Recipient is ERC1155TokenReceiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - public - pure - override - returns (bytes4) - { - revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector))); - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external pure override returns (bytes4) { - revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector))); - } -} - -contract WrongReturnDataERC1155Recipient is ERC1155TokenReceiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - public - pure - override - returns (bytes4) - { - return 0xCAFEBEEF; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external pure override returns (bytes4) { - return 0xCAFEBEEF; - } -} - -contract NonERC1155Recipient {} - -contract MockERC1155WithHooks is MockERC1155 { - uint256 public beforeCounter; - uint256 public afterCounter; - - function _useBeforeTokenTransfer() internal view virtual override returns (bool) { - return true; - } - - function _useAfterTokenTransfer() internal view virtual override returns (bool) { - return true; - } - - function _beforeTokenTransfer( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) internal virtual override { - beforeCounter++; - } - - function _afterTokenTransfer(address, address, uint256[] memory, uint256[] memory, bytes memory) - internal - virtual - override - { - afterCounter++; - } -} - -contract ERC1155HooksTest is SoladyTest, ERC1155TokenReceiver { - uint256 public expectedBeforeCounter; - uint256 public expectedAfterCounter; - - function _checkCounters() internal view { - require( - expectedBeforeCounter == MockERC1155WithHooks(msg.sender).beforeCounter(), - "Before counter mismatch." - ); - require( - expectedAfterCounter == MockERC1155WithHooks(msg.sender).afterCounter(), - "After counter mismatch." - ); - } - - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - external - virtual - override - returns (bytes4) - { - _checkCounters(); - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual override returns (bytes4) { - _checkCounters(); - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } - - function _testHooks(MockERC1155WithHooks token) internal { - address from = _randomNonZeroAddress(); - expectedBeforeCounter++; - expectedAfterCounter++; - token.mint(address(this), 1, 1000, ""); - - expectedBeforeCounter++; - expectedAfterCounter++; - token.safeTransferFrom(address(this), from, 1, 1000, ""); - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.safeTransferFrom(from, address(this), 1, 1, ""); - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.directSafeTransferFrom(from, address(this), 1, 1, ""); - - uint256[] memory ids = new uint256[](1); - uint256[] memory amounts = new uint256[](1); - ids[0] = 1; - amounts[0] = 1; - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.safeBatchTransferFrom(from, address(this), ids, amounts, ""); - - vm.prank(from); - expectedBeforeCounter++; - expectedAfterCounter++; - token.directSafeBatchTransferFrom(from, address(this), ids, amounts, ""); - } - - function testERC1155Hooks() public { - MockERC1155WithHooks token = new MockERC1155WithHooks(); - - for (uint256 i; i < 32; ++i) { - _testHooks(token); - } - } -} - -contract ERC1155Test is SoladyTest, ERC1155TokenReceiver { - MockERC1155 token; - - event TransferSingle( - address indexed operator, - address indexed from, - address indexed to, - uint256 id, - uint256 amount - ); - - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] amounts - ); - - event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); - - mapping(address => mapping(uint256 => uint256)) public userMintAmounts; - mapping(address => mapping(uint256 => uint256)) public userTransferOrBurnAmounts; - - struct _TestTemps { - address from; - address to; - uint256 n; - uint256[] ids; - uint256[] mintAmounts; - uint256[] transferAmounts; - uint256[] burnAmounts; - uint256 id; - uint256 mintAmount; - uint256 transferAmount; - uint256 burnAmount; - bytes mintData; - bytes burnData; - bytes transferData; - } - - function _randomArray(uint256 n) internal returns (uint256[] memory a) { - /// @solidity memory-safe-assembly - assembly { - a := mload(0x40) - mstore(a, n) - mstore(0x40, add(add(a, 0x20), shl(5, n))) - } - unchecked { - for (uint256 i; i != n; ++i) { - a[i] = _random(); - } - } - } - - function _testTemps() internal returns (_TestTemps memory t) { - unchecked { - t.from = _randomNonZeroAddress(); - do { - t.to = _randomNonZeroAddress(); - } while (t.from == t.to); - uint256 n = _random() % 4; - t.n = n; - t.ids = _randomArray(n); - t.mintAmounts = _randomArray(n); - t.transferAmounts = _randomArray(n); - t.burnAmounts = _randomArray(n); - t.mintData = _randomBytes(); - t.burnData = _randomBytes(); - t.transferData = _randomBytes(); - t.id = _random(); - t.transferAmount = _random(); - t.burnAmount = _random(); - t.mintAmount = _random(); - } - } - - function _safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal { - if (_randomChance(2)) { - token.safeTransferFrom(from, to, id, amount, data); - } else { - token.directSafeTransferFrom(from, to, id, amount, data); - } - } - - function _safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal { - if (_randomChance(2)) { - token.safeBatchTransferFrom(from, to, ids, amounts, data); - } else { - token.directSafeBatchTransferFrom(from, to, ids, amounts, data); - } - } - - function _setApprovalForAll(address operator, bool approved) internal { - if (_randomChance(2)) { - token.setApprovalForAll(operator, approved); - } else { - token.directSetApprovalForAll(operator, approved); - } - } - - function _expectMintEvent(address to, uint256 id, uint256 amount) internal { - _expectMintEvent(address(this), to, id, amount); - } - - function _expectMintEvent(address operator, address to, uint256 id, uint256 amount) internal { - _expectTransferEvent(operator, address(0), to, id, amount); - } - - function _expectBurnEvent(address from, uint256 id, uint256 amount) internal { - _expectBurnEvent(address(this), from, id, amount); - } - - function _expectBurnEvent(address operator, address from, uint256 id, uint256 amount) - internal - { - _expectTransferEvent(operator, from, address(0), id, amount); - } - - function _expectTransferEvent(address from, address to, uint256 id, uint256 amount) internal { - _expectTransferEvent(address(this), from, to, id, amount); - } - - function _expectTransferEvent( - address operator, - address from, - address to, - uint256 id, - uint256 amount - ) internal { - vm.expectEmit(true, true, true, true); - emit TransferSingle(operator, from, to, id, amount); - } - - function _expectMintEvent(address to, uint256[] memory ids, uint256[] memory amounts) - internal - { - _expectMintEvent(address(this), to, ids, amounts); - } - - function _expectMintEvent( - address operator, - address to, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - _expectTransferEvent(operator, address(0), to, ids, amounts); - } - - function _expectBurnEvent(address from, uint256[] memory ids, uint256[] memory amounts) - internal - { - _expectBurnEvent(address(this), from, ids, amounts); - } - - function _expectBurnEvent( - address operator, - address from, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - _expectTransferEvent(operator, from, address(0), ids, amounts); - } - - function _expectTransferEvent( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - _expectTransferEvent(address(this), from, to, ids, amounts); - } - - function _expectTransferEvent( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts - ) internal { - vm.expectEmit(true, true, true, true); - emit TransferBatch(operator, from, to, ids, amounts); - } - - function _expectApprovalForAllEvent(address operator, bool isApproved) internal { - _expectApprovalForAllEvent(address(this), operator, isApproved); - } - - function _expectApprovalForAllEvent(address owner, address operator, bool isApproved) - internal - { - vm.expectEmit(true, true, true, true); - emit ApprovalForAll(owner, operator, isApproved); - } - - function setUp() public { - token = new MockERC1155(); - } - - function testDirectSetApprovalForAll(address by, address operator, bool approved) public { - _expectApprovalForAllEvent(by, operator, approved); - vm.prank(by); - token.directSetApprovalForAll(operator, approved); - } - - function testAuthorizedEquivalence(address by, address from, bool isApprovedAccount) public { - bool a = true; - bool b = true; - /// @solidity memory-safe-assembly - assembly { - if by { if iszero(eq(by, from)) { a := isApprovedAccount } } - if iszero(or(iszero(by), eq(by, from))) { b := isApprovedAccount } - } - assertEq(a, b); - } - - function testMintToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - _expectMintEvent(t.to, t.id, t.mintAmount); - token.mint(t.to, t.id, t.mintAmount, t.mintData); - - assertEq(token.balanceOf(t.to, t.id), t.mintAmount); - } - - function testMintToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - - ERC1155Recipient to = new ERC1155Recipient(); - - _expectMintEvent(address(to), t.id, t.mintAmount); - token.mint(address(to), t.id, t.mintAmount, t.mintData); - - assertEq(token.balanceOf(address(to), t.id), t.mintAmount); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), t.id); - assertEq(to.mintData(), t.mintData); - } - - function testBatchMintToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.to][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[t.to][id] += mintAmount; - } - - _expectMintEvent(t.to, t.ids, t.mintAmounts); - token.batchMint(t.to, t.ids, t.mintAmounts, t.mintData); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - assertEq(token.balanceOf(t.to, id), userMintAmounts[t.to][id]); - } - } - - function testBatchMintToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - - ERC1155Recipient to = new ERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - _expectMintEvent(address(to), t.ids, t.mintAmounts); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), address(0)); - assertEq(to.batchIds(), t.ids); - assertEq(to.batchAmounts(), t.mintAmounts); - assertEq(to.batchData(), t.mintData); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - assertEq(token.balanceOf(address(to), id), userMintAmounts[address(to)][id]); - } - } - - function testBurn(uint256) public { - _TestTemps memory t = _testTemps(); - - t.burnAmount = _bound(t.burnAmount, 0, t.mintAmount); - - _expectMintEvent(t.to, t.id, t.mintAmount); - token.mint(t.to, t.id, t.mintAmount, t.mintData); - - if (_randomChance(2)) { - _expectBurnEvent(t.to, t.id, t.burnAmount); - token.uncheckedBurn(t.to, t.id, t.burnAmount); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - token.burn(t.to, t.id, t.burnAmount); - return; - } else { - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - _expectBurnEvent(t.to, t.id, t.burnAmount); - token.burn(t.to, t.id, t.burnAmount); - } - - assertEq(token.balanceOf(t.to, t.id), t.mintAmount - t.burnAmount); - } - - function testBatchBurn(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.to][id]; - - t.mintAmounts[i] = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - t.burnAmounts[i] = _bound(t.burnAmounts[i], 0, t.mintAmounts[i]); - - userMintAmounts[t.to][id] += t.mintAmounts[i]; - userTransferOrBurnAmounts[t.to][id] += t.burnAmounts[i]; - } - - _expectMintEvent(t.to, t.ids, t.mintAmounts); - token.batchMint(t.to, t.ids, t.mintAmounts, t.mintData); - - if (_randomChance(2)) { - _expectBurnEvent(t.to, t.ids, t.burnAmounts); - token.uncheckedBatchBurn(t.to, t.ids, t.burnAmounts); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - token.batchBurn(t.to, t.ids, t.burnAmounts); - return; - } else { - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - _expectBurnEvent(t.to, t.ids, t.burnAmounts); - token.batchBurn(t.to, t.ids, t.burnAmounts); - } - - for (uint256 i = 0; i < t.ids.length; i++) { - uint256 id = t.ids[i]; - - assertEq( - token.balanceOf(t.to, id), - userMintAmounts[t.to][id] - userTransferOrBurnAmounts[t.to][id] - ); - } - } - - function testApproveAll(address to, bool approved) public { - _expectApprovalForAllEvent(to, approved); - _setApprovalForAll(to, approved); - assertEq(token.isApprovedForAll(address(this), to), approved); - } - - function testSafeTransferFromToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - _expectMintEvent(t.from, t.id, t.mintAmount); - token.mint(t.from, t.id, t.mintAmount, t.mintData); - - if (_randomChance(2)) { - _expectTransferEvent(t.from, t.to, t.id, t.transferAmount); - token.uncheckedSafeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - _safeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - return; - } else { - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, t.to, t.id, t.transferAmount); - _safeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - } - - if (t.to == t.from) { - assertEq(token.balanceOf(t.to, t.id), t.mintAmount); - } else { - assertEq(token.balanceOf(t.to, t.id), t.transferAmount); - assertEq(token.balanceOf(t.from, t.id), t.mintAmount - t.transferAmount); - } - } - - function testSafeTransferFromToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - ERC1155Recipient to = new ERC1155Recipient(); - - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - _expectMintEvent(t.from, t.id, t.mintAmount); - token.mint(t.from, t.id, t.mintAmount, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, address(to), t.id, t.transferAmount); - _safeTransferFrom(t.from, address(to), t.id, t.transferAmount, t.transferData); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), t.from); - assertEq(to.id(), t.id); - assertEq(to.mintData(), t.transferData); - - assertEq(token.balanceOf(address(to), t.id), t.transferAmount); - assertEq(token.balanceOf(t.from, t.id), t.mintAmount - t.transferAmount); - } - - function testSafeTransferFromSelf(uint256) public { - _TestTemps memory t = _testTemps(); - - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - _expectMintEvent(address(this), t.id, t.mintAmount); - token.mint(address(this), t.id, t.mintAmount, t.mintData); - - _expectTransferEvent(address(this), t.to, t.id, t.transferAmount); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - - assertEq(token.balanceOf(t.to, t.id), t.transferAmount); - assertEq(token.balanceOf(address(this), t.id), t.mintAmount - t.transferAmount); - } - - function testSafeBatchTransfer() public { - for (uint256 i; i != 8; ++i) { - testSafeTransferFromToEOA(_random()); - testSafeBatchTransferFromToERC1155Recipient(_random()); - } - } - - function testSafeBatchTransferFromToEOA(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - userTransferOrBurnAmounts[t.from][id] += transferAmount; - } - _expectMintEvent(t.from, t.ids, t.mintAmounts); - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - if (_randomChance(2)) { - _expectTransferEvent(t.from, t.to, t.ids, t.transferAmounts); - token.uncheckedSafeBatchTransferFrom( - t.from, t.to, t.ids, t.transferAmounts, t.transferData - ); - } else if (_randomChance(8)) { - vm.expectRevert(ERC1155.NotOwnerNorApproved.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - return; - } else { - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, t.to, t.ids, t.transferAmounts); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - assertEq(token.balanceOf(t.to, id), userTransferOrBurnAmounts[t.from][id]); - assertEq( - token.balanceOf(t.from, id), - userMintAmounts[t.from][id] - userTransferOrBurnAmounts[t.from][id] - ); - } - } - - function testSafeBatchTransferFromToERC1155Recipient(uint256) public { - _TestTemps memory t = _testTemps(); - - ERC1155Recipient to = new ERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - userTransferOrBurnAmounts[t.from][id] += transferAmount; - } - - _expectMintEvent(t.from, t.ids, t.mintAmounts); - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - _expectTransferEvent(t.from, address(to), t.ids, t.transferAmounts); - _safeBatchTransferFrom(t.from, address(to), t.ids, t.transferAmounts, t.transferData); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), t.from); - assertEq(to.batchIds(), t.ids); - assertEq(to.batchAmounts(), t.transferAmounts); - assertEq(to.batchData(), t.transferData); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - uint256 transferAmount = userTransferOrBurnAmounts[t.from][id]; - - assertEq(token.balanceOf(address(to), id), transferAmount); - assertEq(token.balanceOf(t.from, id), userMintAmounts[t.from][id] - transferAmount); - } - } - - function testBatchBalanceOf(uint256) public { - _TestTemps memory t = _testTemps(); - - address[] memory tos = new address[](t.n); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - address to = _randomNonZeroAddress(); - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id]; - - tos[i] = to; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - token.mint(to, id, mintAmount, t.mintData); - - userMintAmounts[to][id] += mintAmount; - } - - uint256[] memory balances = token.balanceOfBatch(tos, t.ids); - - for (uint256 i = 0; i != t.n; i++) { - assertEq(balances[i], token.balanceOf(tos[i], t.ids[i])); - } - } - - function testMintToZeroReverts(uint256) public { - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - token.mint(address(0), _random(), _random(), _randomBytes()); - } - - function testMintToNonERC155RecipientReverts(uint256) public { - address to = address(new NonERC1155Recipient()); - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.mint(to, _random(), _random(), _randomBytes()); - } - - function testMintToRevertingERC155RecipientReverts(uint256) public { - address to = address(new RevertingERC1155Recipient()); - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector)); - token.mint(to, _random(), _random(), _randomBytes()); - } - - function testMintToWrongReturnDataERC155RecipientReverts(uint256) public { - address to = address(new WrongReturnDataERC1155Recipient()); - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.mint(to, _random(), _random(), _randomBytes()); - } - - function testBurnInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - while (t.mintAmount == type(uint256).max) t.mintAmount = _random(); - t.burnAmount = _bound(t.burnAmount, t.mintAmount + 1, type(uint256).max); - - token.mint(t.to, t.id, t.mintAmount, t.mintData); - - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - token.burn(t.to, t.id, t.burnAmount); - } - - function testSafeTransferFromInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - while (t.mintAmount == type(uint256).max) t.mintAmount = _random(); - - t.transferAmount = _bound(t.transferAmount, t.mintAmount + 1, type(uint256).max); - - token.mint(t.from, t.id, t.mintAmount, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - _safeTransferFrom(t.from, t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromSelfInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - while (t.mintAmount == type(uint256).max) t.mintAmount = _random(); - - t.transferAmount = _bound(t.transferAmount, t.mintAmount + 1, type(uint256).max); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToZeroReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - _safeTransferFrom(address(this), address(0), t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToNonERC155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - t.to = address(new NonERC1155Recipient()); - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToRevertingERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - t.to = address(new RevertingERC1155Recipient()); - - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector)); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeTransferFromToWrongReturnDataERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - t.transferAmount = _bound(t.transferAmount, 0, t.mintAmount); - - token.mint(address(this), t.id, t.mintAmount, t.mintData); - t.to = address(new WrongReturnDataERC1155Recipient()); - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeTransferFrom(address(this), t.to, t.id, t.transferAmount, t.transferData); - } - - function testSafeBatchTransferInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - while (t.n == 0) t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - if (mintAmount == type(uint256).max) return; - uint256 transferAmount = _bound(t.transferAmounts[i], mintAmount + 1, type(uint256).max); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToZeroReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - _safeBatchTransferFrom(t.from, address(0), t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToNonERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - t.to = address(new NonERC1155Recipient()); - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToRevertingERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - t.to = address(new RevertingERC1155Recipient()); - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector)); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromToWrongReturnDataERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.from][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = _bound(t.transferAmounts[i], 0, mintAmount); - - t.mintAmounts[i] = mintAmount; - t.transferAmounts[i] = transferAmount; - - userMintAmounts[t.from][id] += mintAmount; - } - - token.batchMint(t.from, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.from); - _setApprovalForAll(address(this), true); - - t.to = address(new WrongReturnDataERC1155Recipient()); - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - _safeBatchTransferFrom(t.from, t.to, t.ids, t.transferAmounts, t.transferData); - } - - function testSafeBatchTransferFromWithArrayLengthMismatchReverts(uint256) public { - uint256[] memory ids = new uint256[](_random() % 4); - uint256[] memory mintAmounts = new uint256[](_random() % 4); - - if (ids.length == mintAmounts.length) return; - - address from = address(0xABCD); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.batchMint(from, ids, mintAmounts, _randomBytes()); - - uint256[] memory transferAmounts = new uint256[](_random() % 4); - if (ids.length == transferAmounts.length) return; - - vm.prank(from); - _setApprovalForAll(address(this), true); - - address to = _randomNonZeroAddress(); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - _safeBatchTransferFrom(from, to, ids, transferAmounts, _randomBytes()); - } - - function testBatchMintToZeroReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(0)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(0)][id] += mintAmount; - } - - vm.expectRevert(ERC1155.TransferToZeroAddress.selector); - token.batchMint(address(0), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintToNonERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - NonERC1155Recipient to = new NonERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintToRevertingERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - RevertingERC1155Recipient to = new RevertingERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - vm.expectRevert(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector)); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintToWrongReturnDataERC1155RecipientReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - - t.mintAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - vm.expectRevert(ERC1155.TransferToNonERC1155ReceiverImplementer.selector); - token.batchMint(address(to), t.ids, t.mintAmounts, t.mintData); - } - - function testBatchMintWithArrayMismatchReverts(uint256) public { - uint256[] memory ids = new uint256[](_random() % 4); - uint256[] memory amounts = new uint256[](_random() % 4); - - if (ids.length == amounts.length) return; - - address to = _randomNonZeroAddress(); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.batchMint(to, ids, amounts, _randomBytes()); - } - - function testBatchBurnInsufficientBalanceReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - while (t.n == 0) t = _testTemps(); - - for (uint256 i = 0; i != t.n; i++) { - uint256 id = t.ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[t.to][id]; - - t.mintAmounts[i] = _bound(t.mintAmounts[i], 0, remainingMintAmountForId); - if (t.mintAmounts[i] == type(uint256).max) return; - t.burnAmounts[i] = _bound(t.burnAmounts[i], t.mintAmounts[i] + 1, type(uint256).max); - - userMintAmounts[t.to][id] += t.mintAmounts[i]; - } - - token.batchMint(t.to, t.ids, t.mintAmounts, t.mintData); - - vm.prank(t.to); - _setApprovalForAll(address(this), true); - - vm.expectRevert(ERC1155.InsufficientBalance.selector); - token.batchBurn(t.to, t.ids, t.burnAmounts); - } - - function testBatchBurnWithArrayLengthMismatchReverts(uint256) public { - _TestTemps memory t = _testTemps(); - - if (t.ids.length == t.burnAmounts.length) t.burnAmounts = _randomArray(t.n + 1); - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.batchBurn(t.to, t.ids, t.burnAmounts); - } - - function testBalanceOfBatchWithArrayMismatchReverts(uint256) public { - address[] memory tos = new address[](_random() % 4); - uint256[] memory ids = new uint256[](_random() % 4); - if (tos.length == ids.length) return; - - vm.expectRevert(ERC1155.ArrayLengthsMismatch.selector); - token.balanceOfBatch(tos, ids); - } -} diff --git a/grouperBot/lib/solady/test/ext/zksync/ERC1967Factory.t.sol b/grouperBot/lib/solady/test/ext/zksync/ERC1967Factory.t.sol deleted file mode 100644 index 69a9217..0000000 --- a/grouperBot/lib/solady/test/ext/zksync/ERC1967Factory.t.sol +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./../../utils/SoladyTest.sol"; - -import "./../../../src/utils/ext/zksync/ERC1967Factory.sol"; - -contract SampleImplementation { - uint256 public x; - - bytes public constant NAME = "Implementation"; - - event Foo(); - - error Hehe(); - - function foo() public { - emit Foo(); - } - - function setX(uint256 newX) public { - x = newX; - } - - function hehe() public pure { - revert Hehe(); - } - - function version() public pure virtual returns (uint256) { - return 1; - } -} - -contract SampleImplementation2 is SampleImplementation { - function version() public pure virtual override returns (uint256) { - return 2; - } -} - -contract ERC1967FactoryTest is SoladyTest { - ERC1967Factory public factory; - address public implementation; - address public implementation2; - - function setUp() public { - factory = new ERC1967Factory(); - implementation = address(new SampleImplementation()); - implementation2 = address(new SampleImplementation2()); - } - - function testDeployDeterministicAndUpgrade() public { - bytes32 salt = 0x0000000000000000000000000000000000000000ff112233445566778899aabb; - address predicted = factory.predictDeterministicAddress(factory.proxyHash(), salt); - assertEq(factory.implementationOf(predicted), address(0)); - address instance = factory.deployProxyDeterministic(implementation, address(this), salt); - assertEq(factory.implementationOf(predicted), implementation); - assertEq(predicted, instance); - SampleImplementation(instance).setX(123); - assertEq(SampleImplementation(instance).x(), 123); - assertEq(SampleImplementation(instance).version(), 1); - assertGt(instance.code.length, 0); - - factory.upgradeAndCall( - instance, implementation2, abi.encodeWithSignature("setX(uint256)", uint256(456)) - ); - assertEq(SampleImplementation(instance).x(), 456); - assertEq(SampleImplementation(instance).version(), 2); - - _checkBehavesLikeProxy(instance); - } - - function testDeployBeaconProxyDeterministicAndUpgrade() public { - bytes32 salt = 0x0000000000000000000000000000000000000000ff112233445566778899aabb; - address predicted = factory.predictDeterministicAddress(factory.beaconHash(), salt); - assertEq(factory.implementationOf(predicted), address(0)); - address beacon = factory.deployBeaconDeterministic(implementation, address(this), salt); - assertEq(UpgradeableBeacon(beacon).implementation(), implementation); - assertEq(factory.implementationOf(predicted), implementation); - assertEq(predicted, beacon); - - predicted = factory.predictDeterministicAddress(factory.beaconProxyHash(), salt); - address beaconProxy = factory.deployBeaconProxyDeterministic(beacon, salt); - assertEq(predicted, beaconProxy); - assertEq(factory.implementationOf(beaconProxy), implementation); - - SampleImplementation(beaconProxy).setX(123); - assertEq(SampleImplementation(beaconProxy).x(), 123); - assertEq(SampleImplementation(beaconProxy).version(), 1); - - factory.upgrade(beacon, implementation2); - assertEq(SampleImplementation(beaconProxy).version(), 2); - - _checkBehavesLikeProxy(beaconProxy); - } - - function _checkBehavesLikeProxy(address instance) internal { - assertTrue(instance != address(0)); - uint256 x = _random(); - SampleImplementation(instance).setX(x); - assertEq(x, SampleImplementation(instance).x()); - vm.expectRevert(SampleImplementation.Hehe.selector); - SampleImplementation(instance).hehe(); - } -} diff --git a/grouperBot/lib/solady/test/ext/zksync/ERC721.t.sol b/grouperBot/lib/solady/test/ext/zksync/ERC721.t.sol deleted file mode 100644 index a713b99..0000000 --- a/grouperBot/lib/solady/test/ext/zksync/ERC721.t.sol +++ /dev/null @@ -1,1005 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./../../utils/SoladyTest.sol"; - -import {ERC721, MockERC721} from "./../../utils/mocks/ext/zksync/MockERC721.sol"; - -abstract contract ERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) - external - virtual - returns (bytes4) - { - return ERC721TokenReceiver.onERC721Received.selector; - } -} - -contract ERC721Recipient is ERC721TokenReceiver { - address public operator; - address public from; - uint256 public id; - bytes public data; - - function onERC721Received(address _operator, address _from, uint256 _id, bytes calldata _data) - public - virtual - override - returns (bytes4) - { - operator = _operator; - from = _from; - id = _id; - data = _data; - - return ERC721TokenReceiver.onERC721Received.selector; - } -} - -contract RevertingERC721Recipient is ERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) - public - virtual - override - returns (bytes4) - { - revert(string(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector))); - } -} - -contract WrongReturnDataERC721Recipient is ERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) - public - virtual - override - returns (bytes4) - { - return 0xCAFEBEEF; - } -} - -contract NonERC721Recipient {} - -contract MockERC721WithHooks is MockERC721 { - uint256 public beforeCounter; - uint256 public afterCounter; - - function _beforeTokenTransfer(address, address, uint256) internal virtual override { - beforeCounter++; - } - - function _afterTokenTransfer(address, address, uint256) internal virtual override { - afterCounter++; - } -} - -contract ERC721HooksTest is SoladyTest, ERC721TokenReceiver { - uint256 public expectedBeforeCounter; - uint256 public expectedAfterCounter; - uint256 public ticker; - - function _checkCounters() internal view { - require( - expectedBeforeCounter == MockERC721WithHooks(msg.sender).beforeCounter(), - "Before counter mismatch." - ); - require( - expectedAfterCounter == MockERC721WithHooks(msg.sender).afterCounter(), - "After counter mismatch." - ); - } - - function onERC721Received(address, address, uint256, bytes calldata) - external - virtual - override - returns (bytes4) - { - _checkCounters(); - return ERC721TokenReceiver.onERC721Received.selector; - } - - function _testHooks(MockERC721WithHooks token) internal { - address from = _randomNonZeroAddress(); - uint256 tokenId = - uint256(keccak256(abi.encode(expectedBeforeCounter, expectedAfterCounter))); - expectedBeforeCounter++; - expectedAfterCounter++; - token.mint(address(this), tokenId); - - expectedBeforeCounter++; - expectedAfterCounter++; - token.transferFrom(address(this), from, tokenId); - - expectedBeforeCounter++; - expectedAfterCounter++; - uint256 r = ticker < 4 ? ticker : _random() % 4; - vm.prank(from); - if (r == 0) { - token.safeTransferFrom(from, address(this), tokenId); - } else if (r == 1) { - token.safeTransferFrom(from, address(this), tokenId, ""); - } else if (r == 2) { - token.directSafeTransferFrom(from, address(this), tokenId); - } else if (r == 3) { - token.directSafeTransferFrom(from, address(this), tokenId, ""); - } else { - revert(); - } - } - - function testERC721Hooks() public { - MockERC721WithHooks token = new MockERC721WithHooks(); - - for (uint256 i; i < 32; ++i) { - _testHooks(token); - } - } -} - -contract ERC721Test is SoladyTest { - MockERC721 token; - - uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; - - event Transfer(address indexed from, address indexed to, uint256 indexed id); - - event Approval(address indexed owner, address indexed approved, uint256 indexed id); - - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - function setUp() public { - token = new MockERC721(); - } - - function _expectMintEvent(address to, uint256 id) internal { - _expectTransferEvent(address(0), to, id); - } - - function _expectBurnEvent(address from, uint256 id) internal { - _expectTransferEvent(from, address(0), id); - } - - function _expectTransferEvent(address from, address to, uint256 id) internal { - vm.expectEmit(true, true, true, true); - emit Transfer(_cleaned(from), _cleaned(to), id); - } - - function _expectApprovalEvent(address owner, address approved, uint256 id) internal { - vm.expectEmit(true, true, true, true); - emit Approval(_cleaned(owner), _cleaned(approved), id); - } - - function _expectApprovalForAllEvent(address owner, address operator, bool approved) internal { - vm.expectEmit(true, true, true, true); - emit ApprovalForAll(_cleaned(owner), _cleaned(operator), approved); - } - - function _aux(address owner) internal pure returns (uint224 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, owner) - result := shr(32, shl(32, keccak256(0x0c, 0x14))) - } - } - - function _extraData(uint256 id) internal pure returns (uint96 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id) - result := shr(160, shl(160, keccak256(0x00, 0x20))) - } - } - - function _transferFrom(address from, address to, uint256 id) internal { - if (_randomChance(2)) { - token.transferFrom(from, to, id); - } else { - token.directTransferFrom(from, to, id); - } - } - - function _safeTransferFrom(address from, address to, uint256 id) internal { - if (_randomChance(2)) { - token.safeTransferFrom(from, to, id); - } else { - token.directSafeTransferFrom(from, to, id); - } - } - - function _safeTransferFrom(address from, address to, uint256 id, bytes memory data) internal { - if (_randomChance(2)) { - token.safeTransferFrom(from, to, id, data); - } else { - token.directSafeTransferFrom(from, to, id, data); - } - } - - function _approve(address spender, uint256 id) internal { - if (_randomChance(2)) { - token.approve(spender, id); - } else { - token.directApprove(spender, id); - } - } - - function _setApprovalForAll(address operator, bool approved) internal { - if (_randomChance(2)) { - token.setApprovalForAll(operator, approved); - } else { - token.directSetApprovalForAll(operator, approved); - } - } - - function _ownerOf(uint256 id) internal returns (address) { - if (_randomChance(2)) { - return token.ownerOf(id); - } else { - return token.directOwnerOf(id); - } - } - - function _getApproved(uint256 id) internal returns (address) { - if (_randomChance(2)) { - return token.getApproved(id); - } else { - return token.directGetApproved(id); - } - } - - function _owners() internal returns (address a, address b) { - a = _randomNonZeroAddress(); - b = _randomNonZeroAddress(); - while (a == b) b = _randomNonZeroAddress(); - } - - function testSafetyOfCustomStorage(uint256 id0, uint256 id1) public { - bool safe; - while (id0 == id1) id1 = _random(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, id0) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let slot0 := add(id0, add(id0, keccak256(0x00, 0x20))) - let slot2 := add(1, slot0) - mstore(0x00, id1) - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - let slot1 := add(id1, add(id1, keccak256(0x00, 0x20))) - let slot3 := add(1, slot1) - safe := 1 - if eq(slot0, slot1) { safe := 0 } - if eq(slot0, slot2) { safe := 0 } - if eq(slot0, slot3) { safe := 0 } - if eq(slot1, slot2) { safe := 0 } - if eq(slot1, slot3) { safe := 0 } - if eq(slot2, slot3) { safe := 0 } - } - require(safe, "Custom storage not safe"); - } - - function testAuthorizedEquivalence(address by, bool isOwnerOrOperator, bool isApprovedAccount) - public - { - bool a = true; - bool b = true; - /// @solidity memory-safe-assembly - assembly { - if by { if iszero(isOwnerOrOperator) { a := isApprovedAccount } } - if iszero(or(iszero(by), isOwnerOrOperator)) { b := isApprovedAccount } - } - assertEq(a, b); - } - - function testCannotExceedMaxBalance() public { - bytes32 balanceSlot; - (address owner0, address owner1) = _owners(); - - /// @solidity memory-safe-assembly - assembly { - mstore(0x1c, _ERC721_MASTER_SLOT_SEED) - mstore(0x00, owner0) - balanceSlot := keccak256(0x0c, 0x1c) - } - - vm.store(address(token), balanceSlot, bytes32(uint256(0xfffffffe))); - token.setAux(owner0, type(uint224).max); - assertEq(token.balanceOf(owner0), 0xfffffffe); - assertEq(token.getAux(owner0), type(uint224).max); - token.mint(owner0, 0); - assertEq(token.balanceOf(owner0), 0xffffffff); - - vm.expectRevert(ERC721.AccountBalanceOverflow.selector); - token.mint(owner0, 1); - - vm.expectRevert(ERC721.AccountBalanceOverflow.selector); - token.mintWithExtraDataUnchecked(owner0, 1, _extraData(1)); - - token.uncheckedBurn(0); - assertEq(token.balanceOf(owner0), 0xfffffffe); - - token.mint(owner1, 0); - vm.prank(owner1); - _transferFrom(owner1, owner0, 0); - - token.mint(owner1, 1); - vm.expectRevert(ERC721.AccountBalanceOverflow.selector); - vm.prank(owner1); - _transferFrom(owner1, owner0, 1); - assertEq(token.getAux(owner0), type(uint224).max); - } - - function testMint(uint256 id) public { - address owner = _randomNonZeroAddress(); - - _expectMintEvent(owner, id); - token.mint(owner, id); - - assertEq(token.balanceOf(owner), 1); - assertEq(_ownerOf(id), owner); - } - - function testMintAndSetExtraDataUnchecked(uint256 id) public { - address owner = _randomNonZeroAddress(); - - _expectMintEvent(owner, id); - token.mintWithExtraDataUnchecked(owner, id, _extraData(id)); - - assertEq(token.balanceOf(owner), 1); - assertEq(_ownerOf(id), owner); - assertEq(token.getExtraData(id), _extraData(id)); - } - - function testMintAndSetExtraDataUncheckedWithOverwrite(uint256 id, uint96 random) public { - address owner = _randomNonZeroAddress(); - - token.setExtraData(id, random); - assertEq(token.getExtraData(id), random); - - _expectMintEvent(owner, id); - token.mintWithExtraDataUnchecked(owner, id, _extraData(id)); - - assertEq(token.getExtraData(id), _extraData(id)); - } - - function testBurn(uint256 id) public { - address owner = _randomNonZeroAddress(); - - _expectMintEvent(owner, id); - token.mint(owner, id); - - if (_randomChance(2)) { - _expectBurnEvent(owner, id); - token.uncheckedBurn(id); - } else { - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - token.burn(id); - uint256 r = _random() % 3; - if (r == 0) { - vm.prank(owner); - _transferFrom(owner, address(this), id); - _expectBurnEvent(address(this), id); - token.burn(id); - } - if (r == 1) { - vm.prank(owner); - _setApprovalForAll(address(this), true); - _expectBurnEvent(owner, id); - token.burn(id); - } - if (r == 2) { - vm.prank(owner); - _approve(address(this), id); - _expectBurnEvent(owner, id); - token.burn(id); - } - } - - assertEq(token.balanceOf(owner), 0); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } - - function testTransferFrom() public { - address owner = _randomNonZeroAddress(); - token.mint(owner, 0); - vm.prank(owner); - token.transferFrom(owner, address(this), 0); - } - - function testEverything(uint256) public { - address[2] memory owners; - uint256[][2] memory tokens; - - unchecked { - (owners[0], owners[1]) = _owners(); - for (uint256 j; j != 2; ++j) { - tokens[j] = new uint256[](_random() % 3); - } - - for (uint256 j; j != 2; ++j) { - token.setAux(owners[j], _aux(owners[j])); - for (uint256 i; i != tokens[j].length;) { - uint256 id = _random(); - if (!token.exists(id)) { - tokens[j][i++] = id; - _expectMintEvent(owners[j], id); - token.mint(owners[j], id); - token.setExtraData(id, _extraData(id)); - } - } - } - for (uint256 j; j != 2; ++j) { - assertEq(token.balanceOf(owners[j]), tokens[j].length); - for (uint256 i; i != tokens[j].length; ++i) { - vm.prank(owners[j]); - _expectApprovalEvent(owners[j], address(this), tokens[j][i]); - _approve(address(this), tokens[j][i]); - } - } - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(_getApproved(tokens[j][i]), address(this)); - uint256 fromBalanceBefore = token.balanceOf(owners[j]); - uint256 toBalanceBefore = token.balanceOf(owners[j ^ 1]); - _expectTransferEvent(owners[j], owners[j ^ 1], tokens[j][i]); - _transferFrom(owners[j], owners[j ^ 1], tokens[j][i]); - assertEq(token.balanceOf(owners[j]), fromBalanceBefore - 1); - assertEq(token.balanceOf(owners[j ^ 1]), toBalanceBefore + 1); - assertEq(_getApproved(tokens[j][i]), address(0)); - } - } - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(_ownerOf(tokens[j][i]), owners[j ^ 1]); - assertEq(token.getExtraData(tokens[j][i]), _extraData(tokens[j][i])); - } - } - if (_randomChance(2)) { - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - _transferFrom(owners[j ^ 1], owners[j], tokens[j][i]); - vm.prank(owners[j ^ 1]); - _expectApprovalEvent(owners[j ^ 1], address(this), tokens[j][i]); - _approve(address(this), tokens[j][i]); - _expectTransferEvent(owners[j ^ 1], owners[j], tokens[j][i]); - _transferFrom(owners[j ^ 1], owners[j], tokens[j][i]); - } - } - } else { - for (uint256 j; j != 2; ++j) { - vm.prank(owners[j ^ 1]); - _expectApprovalForAllEvent(owners[j ^ 1], address(this), true); - token.setApprovalForAll(address(this), true); - for (uint256 i; i != tokens[j].length; ++i) { - _expectTransferEvent(owners[j ^ 1], owners[j], tokens[j][i]); - _transferFrom(owners[j ^ 1], owners[j], tokens[j][i]); - } - } - } - for (uint256 j; j != 2; ++j) { - assertEq(token.getAux(owners[j]), _aux(owners[j])); - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(_ownerOf(tokens[j][i]), owners[j]); - assertEq(token.getExtraData(tokens[j][i]), _extraData(tokens[j][i])); - } - } - for (uint256 j; j != 2; ++j) { - for (uint256 i; i != tokens[j].length; ++i) { - token.uncheckedBurn(tokens[j][i]); - } - } - for (uint256 j; j != 2; ++j) { - assertEq(token.balanceOf(owners[j]), 0); - for (uint256 i; i != tokens[j].length; ++i) { - assertEq(token.getExtraData(tokens[j][i]), _extraData(tokens[j][i])); - } - } - } - } - - function testIsApprovedOrOwner(uint256 id) public { - (address owner0, address owner1) = _owners(); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - token.isApprovedOrOwner(owner0, id); - - token.mint(owner0, id); - assertEq(token.isApprovedOrOwner(owner0, id), true); - - vm.prank(owner0); - _transferFrom(owner0, owner1, id); - assertEq(token.isApprovedOrOwner(owner0, id), false); - - vm.prank(owner1); - _setApprovalForAll(owner0, true); - assertEq(token.isApprovedOrOwner(owner0, id), true); - - vm.prank(owner1); - _setApprovalForAll(owner0, false); - assertEq(token.isApprovedOrOwner(owner0, id), false); - - vm.prank(owner1); - _approve(owner0, id); - assertEq(token.isApprovedOrOwner(owner0, id), true); - } - - function testExtraData(uint256 id) public { - (address owner0, address owner1) = _owners(); - - bool setExtraData = _randomChance(2); - uint96 extraData = uint96(_bound(_random(), 0, type(uint96).max)); - if (setExtraData) { - token.setExtraData(id, extraData); - } - _expectMintEvent(owner0, id); - token.mint(owner0, id); - if (setExtraData) { - assertEq(token.getExtraData(id), extraData); - } else { - assertEq(token.getExtraData(id), 0); - } - - vm.prank(owner0); - _expectTransferEvent(owner0, owner1, id); - _transferFrom(owner0, owner1, id); - if (setExtraData) { - assertEq(token.getExtraData(id), extraData); - } else { - assertEq(token.getExtraData(id), 0); - } - assertEq(_ownerOf(id), owner1); - - if (_randomChance(2)) { - extraData = uint96(_bound(_random(), 0, type(uint96).max)); - token.setExtraData(id, extraData); - setExtraData = true; - } - - _expectBurnEvent(owner1, id); - token.uncheckedBurn(id); - if (setExtraData) { - assertEq(token.getExtraData(id), extraData); - } else { - assertEq(token.getExtraData(id), 0); - } - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } - - function testExtraData2(uint256 id0, uint256 id1) public { - while (id0 == id1) id1 = _random(); - token.setExtraData(id0, _extraData(id0)); - token.setExtraData(id1, _extraData(id1)); - assertEq(token.getExtraData(id0), _extraData(id0)); - assertEq(token.getExtraData(id1), _extraData(id1)); - } - - function testAux(uint256) public { - (address owner0, address owner1) = _owners(); - - bool setAux = _randomChance(2); - if (setAux) { - token.setAux(owner0, _aux(owner0)); - token.setAux(owner1, _aux(owner1)); - } - - for (uint256 i; i < 2; ++i) { - _expectMintEvent(owner0, i * 2 + 0); - token.mint(owner0, i * 2 + 0); - assertEq(token.balanceOf(owner0), i + 1); - - _expectMintEvent(owner1, i * 2 + 1); - token.mint(owner1, i * 2 + 1); - assertEq(token.balanceOf(owner1), i + 1); - - if (setAux) { - assertEq(token.getAux(owner0), _aux(owner0)); - assertEq(token.getAux(owner1), _aux(owner1)); - } else { - assertEq(token.getAux(owner0), 0); - assertEq(token.getAux(owner1), 0); - } - } - - for (uint256 i; i < 2; ++i) { - _expectBurnEvent(owner0, i * 2 + 0); - token.uncheckedBurn(i * 2 + 0); - assertEq(token.balanceOf(owner0), 1 - i); - - _expectBurnEvent(owner1, i * 2 + 1); - token.uncheckedBurn(i * 2 + 1); - assertEq(token.balanceOf(owner1), 1 - i); - - if (setAux) { - assertEq(token.getAux(owner0), _aux(owner0)); - assertEq(token.getAux(owner1), _aux(owner1)); - } else { - assertEq(token.getAux(owner0), 0); - assertEq(token.getAux(owner1), 0); - } - } - } - - function testApprove(uint256 id) public { - (address spender,) = _randomSigner(); - - token.mint(address(this), id); - - _expectApprovalEvent(address(this), spender, id); - _approve(spender, id); - assertEq(_getApproved(id), spender); - } - - function testApproveBurn(uint256 id) public { - (address spender,) = _randomSigner(); - - token.mint(address(this), id); - - _approve(spender, id); - - token.uncheckedBurn(id); - - assertEq(token.balanceOf(address(this)), 0); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _getApproved(id); - - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } - - function testApproveAll(uint256) public { - (address operator,) = _randomSigner(); - bool approved = _randomChance(2); - _expectApprovalForAllEvent(address(this), operator, approved); - _setApprovalForAll(operator, approved); - assertEq(token.isApprovedForAll(address(this), operator), approved); - } - - function testTransferFrom(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - if (_randomChance(2)) { - uint256 r = _random() % 3; - if (r == 0) { - vm.prank(from); - _approve(address(this), id); - _expectTransferEvent(from, to, id); - _transferFrom(from, to, id); - } - if (r == 1) { - vm.prank(from); - _setApprovalForAll(address(this), true); - _expectTransferEvent(from, to, id); - _transferFrom(from, to, id); - } - if (r == 2) { - vm.prank(from); - _expectTransferEvent(from, address(this), id); - _transferFrom(from, address(this), id); - _expectTransferEvent(address(this), to, id); - _transferFrom(address(this), to, id); - } - } else { - (address temp,) = _randomSigner(); - while (temp == from || temp == to) (temp,) = _randomSigner(); - if (_randomChance(2)) { - _expectTransferEvent(from, temp, id); - token.uncheckedTransferFrom(from, temp, id); - } else { - vm.prank(from); - _expectTransferEvent(from, temp, id); - _transferFrom(from, temp, id); - } - _expectTransferEvent(temp, to, id); - token.uncheckedTransferFrom(temp, to, id); - } - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testTransferFromSelf(uint256 id) public { - (address to,) = _randomSigner(); - - token.mint(address(this), id); - - _transferFrom(address(this), to, id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(address(this)), 0); - } - - function testTransferFromApproveAll(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _transferFrom(from, to, id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToEOA(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _safeTransferFrom(from, to, id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToERC721Recipient(uint256 id) public { - (address from,) = _randomSigner(); - - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _safeTransferFrom(from, address(recipient), id); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - assertEq(recipient.id(), id); - assertEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes memory data) public { - (address from,) = _randomSigner(); - - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - vm.prank(from); - _setApprovalForAll(address(this), true); - - _safeTransferFrom(from, address(recipient), id, data); - - assertEq(recipient.data(), data); - assertEq(recipient.id(), id); - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - - assertEq(_getApproved(id), address(0)); - assertEq(_ownerOf(id), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeMintToEOA(uint256 id) public { - (address to,) = _randomSigner(); - - token.safeMint(to, id); - - assertEq(_ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - } - - function testSafeMintToERC721Recipient(uint256 id) public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), id); - - assertEq(_ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), id); - assertEq(to.data(), ""); - } - - function testSafeMintToERC721RecipientWithData(uint256 id, bytes memory data) public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), id, data); - - assertEq(_ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), id); - assertEq(to.data(), data); - } - - function testMintToZeroReverts(uint256 id) public { - vm.expectRevert(ERC721.TransferToZeroAddress.selector); - token.mint(address(0), id); - - vm.expectRevert(ERC721.TransferToZeroAddress.selector); - token.mintWithExtraDataUnchecked(address(0), id, _extraData(id)); - } - - function testDoubleMintReverts(uint256 id) public { - (address to,) = _randomSigner(); - - token.mint(to, id); - vm.expectRevert(ERC721.TokenAlreadyExists.selector); - token.mint(to, id); - } - - function testBurnNonExistentReverts(uint256 id) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - token.uncheckedBurn(id); - } - - function testDoubleBurnReverts(uint256 id) public { - (address to,) = _randomSigner(); - - token.mint(to, id); - - token.uncheckedBurn(id); - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - token.uncheckedBurn(id); - } - - function testApproveNonExistentReverts(uint256 id, address to) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _approve(to, id); - } - - function testApproveUnauthorizedReverts(uint256 id) public { - (address owner, address to) = _owners(); - - token.mint(owner, id); - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - _approve(to, id); - } - - function testTransferFromNotExistentReverts(address from, address to, uint256 id) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _transferFrom(from, to, id); - } - - function testTransferFromWrongFromReverts(address to, uint256 id) public { - (address owner, address from) = _owners(); - - token.mint(owner, id); - vm.expectRevert(ERC721.TransferFromIncorrectOwner.selector); - _transferFrom(from, to, id); - } - - function testTransferFromToZeroReverts(uint256 id) public { - token.mint(address(this), id); - - vm.expectRevert(ERC721.TransferToZeroAddress.selector); - _transferFrom(address(this), address(0), id); - } - - function testTransferFromNotOwner(uint256 id) public { - (address from, address to) = _owners(); - - token.mint(from, id); - - vm.expectRevert(ERC721.NotOwnerNorApproved.selector); - _transferFrom(from, to, id); - } - - function testSafeTransferFromToNonERC721RecipientReverts(uint256 id) public { - token.mint(address(this), id); - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), address(to), id); - } - - function testSafeTransferFromToNonERC721RecipientWithDataReverts(uint256 id, bytes memory data) - public - { - token.mint(address(this), id); - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), to, id, data); - } - - function testSafeTransferFromToRevertingERC721RecipientReverts(uint256 id) public { - token.mint(address(this), id); - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - _safeTransferFrom(address(this), to, id); - } - - function testSafeTransferFromToRevertingERC721RecipientWithDataReverts( - uint256 id, - bytes memory data - ) public { - token.mint(address(this), id); - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - _safeTransferFrom(address(this), to, id, data); - } - - function testSafeTransferFromToERC721RecipientWithWrongReturnDataReverts(uint256 id) public { - token.mint(address(this), id); - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), to, id); - } - - function testSafeTransferFromToERC721RecipientWithWrongReturnDataWithDataReverts( - uint256 id, - bytes memory data - ) public { - token.mint(address(this), id); - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - _safeTransferFrom(address(this), to, id, data); - } - - function testSafeMintToNonERC721RecipientReverts(uint256 id) public { - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id); - } - - function testSafeMintToNonERC721RecipientWithDataReverts(uint256 id, bytes memory data) - public - { - address to = address(new NonERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id, data); - } - - function testSafeMintToRevertingERC721RecipientReverts(uint256 id) public { - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - token.safeMint(to, id); - } - - function testSafeMintToRevertingERC721RecipientWithDataReverts(uint256 id, bytes memory data) - public - { - address to = address(new RevertingERC721Recipient()); - vm.expectRevert(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector)); - token.safeMint(to, id, data); - } - - function testSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public { - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id); - } - - function testSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes memory data) - public - { - address to = address(new WrongReturnDataERC721Recipient()); - vm.expectRevert(ERC721.TransferToNonERC721ReceiverImplementer.selector); - token.safeMint(to, id, data); - } - - function testOwnerOfNonExistent(uint256 id) public { - vm.expectRevert(ERC721.TokenDoesNotExist.selector); - _ownerOf(id); - } -} diff --git a/grouperBot/lib/solady/test/ext/zksync/SafeTransferLib.t.sol b/grouperBot/lib/solady/test/ext/zksync/SafeTransferLib.t.sol deleted file mode 100644 index 7f9e80b..0000000 --- a/grouperBot/lib/solady/test/ext/zksync/SafeTransferLib.t.sol +++ /dev/null @@ -1,799 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {MockERC20} from "./../../utils/mocks/MockERC20.sol"; -import {MockERC20LikeUSDT} from "./../../utils/mocks/MockERC20LikeUSDT.sol"; -import {MockETHRecipient} from "./../../utils/mocks/MockETHRecipient.sol"; -import {RevertingToken} from "./../../utils/weird-tokens/RevertingToken.sol"; -import {ReturnsTwoToken} from "./../../utils/weird-tokens/ReturnsTwoToken.sol"; -import {ReturnsFalseToken} from "./../../utils/weird-tokens/ReturnsFalseToken.sol"; -import {MissingReturnToken} from "./../../utils/weird-tokens/MissingReturnToken.sol"; -import {ReturnsTooMuchToken} from "./../../utils/weird-tokens/ReturnsTooMuchToken.sol"; -import {ReturnsRawBytesToken} from "./../../utils/weird-tokens/ReturnsRawBytesToken.sol"; -import {ReturnsTooLittleToken} from "./../../utils/weird-tokens/ReturnsTooLittleToken.sol"; - -import "./../../utils/SoladyTest.sol"; - -import {ERC20} from "../../../src/tokens/ERC20.sol"; -import {SafeTransferLib} from "../../../src/utils/ext/zksync/SafeTransferLib.sol"; - -contract Griefer { - uint256 public receiveNumLoops; - - uint256[] internal _junk; - - event Junk(uint256 indexed i); - - function setReceiveNumLoops(uint256 amount) public { - receiveNumLoops = amount; - } - - function execute(address to, bytes memory data) public { - (bool success,) = to.call(data); - require(success); - } - - function doStuff() public payable { - unchecked { - uint256 n = receiveNumLoops; - if (n > 0xffffffff) revert(); - for (uint256 i; i < n; ++i) { - _junk.push(i); - } - } - } - - receive() external payable { - doStuff(); - } - - fallback() external payable { - doStuff(); - } -} - -contract SafeTransferLibTest is SoladyTest { - uint256 internal constant _SUCCESS = 1; - uint256 internal constant _REVERTS_WITH_SELECTOR = 2; - uint256 internal constant _REVERTS_WITH_ANY = 3; - - address internal constant _REGULAR_EVM_PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; - - RevertingToken reverting; - ReturnsTwoToken returnsTwo; - ReturnsFalseToken returnsFalse; - MissingReturnToken missingReturn; - ReturnsTooMuchToken returnsTooMuch; - ReturnsRawBytesToken returnsRawBytes; - ReturnsTooLittleToken returnsTooLittle; - - MockERC20 erc20; - - Griefer griefer; - - function setUp() public { - vm.chainId(1); - reverting = new RevertingToken(); - returnsTwo = new ReturnsTwoToken(); - returnsFalse = new ReturnsFalseToken(); - missingReturn = new MissingReturnToken(); - returnsTooMuch = new ReturnsTooMuchToken(); - returnsRawBytes = new ReturnsRawBytesToken(); - returnsTooLittle = new ReturnsTooLittleToken(); - - erc20 = new MockERC20("StandardToken", "ST", 18); - erc20.mint(address(this), type(uint256).max); - - griefer = new Griefer(); - } - - function testTransferWithMissingReturn() public { - verifySafeTransfer(address(missingReturn), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferWithStandardERC20() public { - verifySafeTransfer(address(erc20), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferWithReturnsTooMuch() public { - verifySafeTransfer(address(returnsTooMuch), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.TransferFailed.selector); - this.safeTransfer(address(0xBADBEEF), address(0xBEEF), 1e18); - } - - function testTransferFromWithMissingReturn() public { - verifySafeTransferFrom( - address(missingReturn), address(0xFEED), address(0xBEEF), 1e18, _SUCCESS - ); - } - - function testTransferFromWithStandardERC20() public { - verifySafeTransferFrom(address(erc20), address(0xFEED), address(0xBEEF), 1e18, _SUCCESS); - } - - function testTransferFromWithReturnsTooMuch() public { - verifySafeTransferFrom( - address(returnsTooMuch), address(0xFEED), address(0xBEEF), 1e18, _SUCCESS - ); - } - - function testTransferFromWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - this.safeTransferFrom(address(0xBADBEEF), address(0xFEED), address(0xBEEF), 1e18); - } - - function safeTransferFrom(address token, address from, address to, uint256 amount) public { - SafeTransferLib.safeTransferFrom( - _brutalized(token), _brutalized(from), _brutalized(to), amount - ); - } - - function testApproveWithMissingReturn() public { - verifySafeApprove(address(missingReturn), address(0xBEEF), 1e18, _SUCCESS); - } - - function testApproveWithStandardERC20() public { - verifySafeApprove(address(erc20), address(0xBEEF), 1e18, _SUCCESS); - } - - function testApproveWithReturnsTooMuch() public { - verifySafeApprove(address(returnsTooMuch), address(0xBEEF), 1e18, _SUCCESS); - } - - function testApproveWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApprove(address(0xBADBEEF), address(0xBEEF), 1e18); - } - - function safeApprove(address token, address to, uint256 amount) public { - SafeTransferLib.safeApprove(token, to, amount); - } - - function testApproveWithRetryWithNonContractReverts() public { - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApproveWithRetry(address(0xBADBEEF), address(0xBEEF), 1e18); - } - - function safeApproveWithRetry(address token, address to, uint256 amount) public { - SafeTransferLib.safeApproveWithRetry(token, to, amount); - } - - function testTransferETH() public { - SafeTransferLib.safeTransferETH(address(0xBEEF), 1e18); - } - - function testTransferAllETH() public { - SafeTransferLib.safeTransferAllETH(address(0xBEEF)); - } - - function testTryTransferETH() public { - MockETHRecipient recipient = new MockETHRecipient(false, false); - bool success = SafeTransferLib.trySafeTransferETH(address(recipient), 1e18, gasleft()); - assertTrue(success); - } - - function testTryTransferAllETH() public { - MockETHRecipient recipient = new MockETHRecipient(false, false); - bool success = SafeTransferLib.trySafeTransferAllETH(address(recipient), gasleft()); - assertTrue(success); - } - - function testTransferWithReturnsFalseReverts() public { - verifySafeTransfer(address(returnsFalse), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithRevertingReverts() public { - verifySafeTransfer(address(reverting), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithReturnsTooLittleReverts() public { - verifySafeTransfer(address(returnsTooLittle), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithReturnsFalseReverts() public { - verifySafeTransferFrom( - address(returnsFalse), address(0xFEED), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR - ); - } - - function testTransferFromWithRevertingReverts() public { - verifySafeTransferFrom( - address(reverting), address(0xFEED), address(0xBEEF), 1e18, _REVERTS_WITH_ANY - ); - } - - function testTransferFromWithReturnsTooLittleReverts() public { - verifySafeTransferFrom( - address(returnsTooLittle), - address(0xFEED), - address(0xBEEF), - 1e18, - _REVERTS_WITH_SELECTOR - ); - } - - function testApproveWithReturnsFalseReverts() public { - verifySafeApprove(address(returnsFalse), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithRevertingReverts() public { - verifySafeApprove(address(reverting), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithReturnsTooLittleReverts() public { - verifySafeApprove(address(returnsTooLittle), address(0xBEEF), 1e18, _REVERTS_WITH_SELECTOR); - } - - function testBalanceOfStandardERC20() public view { - erc20.balanceOf(address(this)); - } - - function testBalanceOfStandardERC20(address to, uint256 amount) public { - uint256 originalBalance = erc20.balanceOf(address(this)); - while (originalBalance < amount) amount = _random(); - while (to == address(this)) to = _randomHashedAddress(); - - SafeTransferLib.safeTransfer(address(erc20), _brutalized(to), originalBalance - amount); - assertEq(SafeTransferLib.balanceOf(address(erc20), _brutalized(address(this))), amount); - } - - function testTransferAllWithStandardERC20() public { - SafeTransferLib.safeTransferAll(address(erc20), address(1)); - } - - function testTransferAllWithStandardERC20(address to, uint256 amount) public { - uint256 originalBalance = erc20.balanceOf(address(this)); - while (originalBalance < amount) amount = _random(); - while (to == address(this)) to = _randomHashedAddress(); - - SafeTransferLib.safeTransfer(address(erc20), _brutalized(to), originalBalance - amount); - assertEq(erc20.balanceOf(address(this)), amount); - - assertEq(SafeTransferLib.safeTransferAll(address(erc20), _brutalized(to)), amount); - - assertEq(erc20.balanceOf(address(this)), 0); - assertEq(erc20.balanceOf(to), originalBalance); - } - - function testTrySafeTransferFrom(address from, address to, uint256 amount) public { - uint256 balance = _random(); - while (from == address(this) || to == address(this) || from == to) { - from = _randomNonZeroAddress(); - to = _randomNonZeroAddress(); - } - erc20.transfer(from, balance); - vm.prank(from); - erc20.approve(address(this), type(uint256).max); - bool result = SafeTransferLib.trySafeTransferFrom(address(erc20), from, to, amount); - assertEq(result, amount <= balance); - } - - function testTransferAllFromWithStandardERC20() public { - forceApprove(address(erc20), address(this), address(this), type(uint256).max); - SafeTransferLib.safeTransferAllFrom(address(erc20), address(this), address(1)); - } - - function testTransferAllFromWithStandardERC20(address from, address to, uint256 amount) - public - { - while (!(to != from && to != address(this) && from != address(this))) { - to = _randomNonZeroAddress(); - from = _randomNonZeroAddress(); - } - - SafeTransferLib.safeTransferAll(address(erc20), _brutalized(from)); - - uint256 originalBalance = erc20.balanceOf(from); - while (originalBalance < amount) amount = _random(); - - forceApprove(address(erc20), from, address(this), type(uint256).max); - - SafeTransferLib.safeTransferFrom( - address(erc20), _brutalized(from), _brutalized(to), originalBalance - amount - ); - assertEq(erc20.balanceOf(from), amount); - - assertEq( - SafeTransferLib.safeTransferAllFrom(address(erc20), _brutalized(from), _brutalized(to)), - amount - ); - - assertEq(erc20.balanceOf(address(this)), 0); - assertEq(erc20.balanceOf(to), originalBalance); - } - - function testTransferWithMissingReturn(address to, uint256 amount) public { - verifySafeTransfer(address(missingReturn), to, amount, _SUCCESS); - } - - function testTransferWithStandardERC20(address to, uint256 amount) public { - verifySafeTransfer(address(erc20), to, amount, _SUCCESS); - } - - function testTransferWithReturnsTooMuch(address to, uint256 amount) public { - verifySafeTransfer(address(returnsTooMuch), to, amount, _SUCCESS); - } - - function testTransferWithNonGarbage(address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateNonGarbage()); - - verifySafeTransfer(address(returnsRawBytes), to, amount, _SUCCESS); - } - - function testTransferWithNonContractReverts(bytes32, address to, uint256 amount) public { - vm.expectRevert(SafeTransferLib.TransferFailed.selector); - this.safeTransfer(_randomHashedAddress(), to, amount); - } - - function safeTransfer(address token, address to, uint256 amount) public { - SafeTransferLib.safeTransfer(token, to, amount); - } - - function testTransferETHToContractWithoutFallbackReverts() public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferETH(address(this), 1e18); - } - - function testTransferAllETHToContractWithoutFallbackReverts() public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferAllETH(address(this)); - } - - function testTransferFromWithMissingReturn(address from, address to, uint256 amount) public { - verifySafeTransferFrom(address(missingReturn), from, to, amount, _SUCCESS); - } - - function testTransferFromWithStandardERC20(address from, address to, uint256 amount) public { - verifySafeTransferFrom(address(erc20), from, to, amount, _SUCCESS); - } - - function testTransferFromWithReturnsTooMuch(address from, address to, uint256 amount) public { - verifySafeTransferFrom(address(returnsTooMuch), from, to, amount, _SUCCESS); - } - - function testTransferFromWithNonGarbage(address from, address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateNonGarbage()); - - verifySafeTransferFrom(address(returnsRawBytes), from, to, amount, _SUCCESS); - } - - function testTransferFromWithNonContractReverts( - address nonContract, - address from, - address to, - uint256 amount - ) public { - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) { - return; - } - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - this.safeTransferFrom(nonContract, from, to, amount); - } - - function testApproveWithMissingReturn(address to, uint256 amount) public { - if (to == _REGULAR_EVM_PERMIT2) return; - verifySafeApprove(address(missingReturn), to, amount, _SUCCESS); - } - - function testApproveWithStandardERC20(address to, uint256 amount) public { - if (to == _REGULAR_EVM_PERMIT2) return; - verifySafeApprove(address(erc20), to, amount, _SUCCESS); - } - - function testApproveWithReturnsTooMuch(address to, uint256 amount) public { - if (to == _REGULAR_EVM_PERMIT2) return; - verifySafeApprove(address(returnsTooMuch), to, amount, _SUCCESS); - } - - function testApproveWithNonGarbage(address to, uint256 amount) public { - if (to == _REGULAR_EVM_PERMIT2) return; - returnsRawBytes.setRawBytes(_generateNonGarbage()); - - verifySafeApprove(address(returnsRawBytes), to, amount, _SUCCESS); - } - - function testApproveWithNonContractReverts(address nonContract, address to, uint256 amount) - public - { - if (to == _REGULAR_EVM_PERMIT2) return; - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) { - return; - } - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApprove(nonContract, to, amount); - } - - function testApproveWithRetryWithNonContractReverts( - address nonContract, - address to, - uint256 amount - ) public { - if (to == _REGULAR_EVM_PERMIT2) return; - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) { - return; - } - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - this.safeApproveWithRetry(nonContract, to, amount); - } - - function testApproveWithRetry(address to, uint256 amount0, uint256 amount1) public { - if (to == _REGULAR_EVM_PERMIT2) return; - MockERC20LikeUSDT usdt = new MockERC20LikeUSDT(); - assertEq(usdt.allowance(address(this), to), 0); - SafeTransferLib.safeApproveWithRetry(address(usdt), _brutalized(to), amount0); - assertEq(usdt.allowance(address(this), to), amount0); - if (amount0 != 0 && amount1 != 0) { - verifySafeApprove(address(usdt), to, amount1, _REVERTS_WITH_SELECTOR); - } - SafeTransferLib.safeApproveWithRetry(address(usdt), _brutalized(to), amount1); - assertEq(usdt.allowance(address(this), to), amount1); - } - - function testApproveWithRetry() public { - testApproveWithRetry(address(1), 123, 456); - } - - function testTransferETH(bytes32, uint256 amount) public { - amount = _bound(amount, 0, address(this).balance); - SafeTransferLib.safeTransferETH(_randomHashedAddress(), amount); - } - - function testTransferAllETH(bytes32) public { - SafeTransferLib.safeTransferAllETH(_randomHashedAddress()); - } - - function testTransferWithReturnsFalseReverts(address to, uint256 amount) public { - verifySafeTransfer(address(returnsFalse), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithRevertingReverts(address to, uint256 amount) public { - verifySafeTransfer(address(reverting), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithReturnsTooLittleReverts(address to, uint256 amount) public { - verifySafeTransfer(address(returnsTooLittle), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithReturnsTwoReverts(address to, uint256 amount) public { - verifySafeTransfer(address(returnsTwo), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferWithGarbageReverts(address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateGarbage()); - - verifySafeTransfer(address(returnsRawBytes), to, amount, _REVERTS_WITH_ANY); - } - - function testTransferFromWithReturnsFalseReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(returnsFalse), from, to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithRevertingReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(reverting), from, to, amount, _REVERTS_WITH_ANY); - } - - function testTransferFromWithReturnsTooLittleReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(returnsTooLittle), from, to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithReturnsTwoReverts(address from, address to, uint256 amount) - public - { - verifySafeTransferFrom(address(returnsTwo), from, to, amount, _REVERTS_WITH_SELECTOR); - } - - function testTransferFromWithGarbageReverts(address from, address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateGarbage()); - - verifySafeTransferFrom(address(returnsRawBytes), from, to, amount, _REVERTS_WITH_ANY); - } - - function testApproveWithReturnsFalseReverts(address to, uint256 amount) public { - verifySafeApprove(address(returnsFalse), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithRevertingReverts(address to, uint256 amount) public { - verifySafeApprove(address(reverting), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithReturnsTooLittleReverts(address to, uint256 amount) public { - verifySafeApprove(address(returnsTooLittle), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithReturnsTwoReverts(address to, uint256 amount) public { - verifySafeApprove(address(returnsTwo), to, amount, _REVERTS_WITH_SELECTOR); - } - - function testApproveWithGarbageReverts(address to, uint256 amount) public { - returnsRawBytes.setRawBytes(_generateGarbage()); - - verifySafeApprove(address(returnsRawBytes), to, amount, _REVERTS_WITH_ANY); - } - - function testTransferETHToContractWithoutFallbackReverts(uint256 amount) public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferETH(address(this), amount); - } - - function testTransferAllETHToContractWithoutFallbackReverts(uint256) public { - vm.expectRevert(SafeTransferLib.ETHTransferFailed.selector); - this.safeTransferAllETH(address(this)); - } - - function verifySafeTransfer(address token, address to, uint256 amount, uint256 mode) public { - if (mode == _REVERTS_WITH_SELECTOR) { - vm.expectRevert(SafeTransferLib.TransferFailed.selector); - } else if (mode == _REVERTS_WITH_ANY) { - (bool success,) = address(this).call( - abi.encodeWithSignature( - "verifySafeTransfer(address,address,uint256)", token, to, amount - ) - ); - assertFalse(success); - return; - } - this.verifySafeTransfer(token, to, amount); - } - - function verifySafeTransfer(address token, address to, uint256 amount) public brutalizeMemory { - uint256 preBal = ERC20(token).balanceOf(to); - if (amount == ERC20(token).balanceOf(address(this)) && _randomChance(2)) { - SafeTransferLib.safeTransferAll(address(token), _brutalized(to)); - } else { - SafeTransferLib.safeTransfer(address(token), _brutalized(to), amount); - } - - uint256 postBal = ERC20(token).balanceOf(to); - - if (to == address(this)) { - assertEq(preBal, postBal); - } else { - assertEq(postBal - preBal, amount); - } - } - - function verifySafeTransferFrom( - address token, - address from, - address to, - uint256 amount, - uint256 mode - ) public { - if (mode == _REVERTS_WITH_SELECTOR) { - vm.expectRevert(SafeTransferLib.TransferFromFailed.selector); - } else if (mode == _REVERTS_WITH_ANY) { - (bool success,) = address(this).call( - abi.encodeWithSignature( - "verifySafeTransferFrom(address,address,address,uint256)", - token, - from, - to, - amount - ) - ); - assertFalse(success); - return; - } - this.verifySafeTransferFrom(token, from, to, amount); - } - - function verifySafeTransferFrom(address token, address from, address to, uint256 amount) - public - brutalizeMemory - { - forceApprove(token, from, address(this), amount); - - // We cast to MissingReturnToken here because it won't check - // that there was return data, which accommodates all tokens. - MissingReturnToken(token).transfer(from, amount); - - uint256 preBal = ERC20(token).balanceOf(to); - if (amount == ERC20(token).balanceOf(from) && _randomChance(2)) { - SafeTransferLib.safeTransferAllFrom(address(token), _brutalized(from), _brutalized(to)); - } else { - SafeTransferLib.safeTransferFrom(token, _brutalized(from), _brutalized(to), amount); - } - uint256 postBal = ERC20(token).balanceOf(to); - - if (from == to) { - assertEq(preBal, postBal); - } else { - assertEq(postBal - preBal, amount); - } - } - - function verifySafeApprove(address token, address to, uint256 amount, uint256 mode) public { - if (mode == _REVERTS_WITH_SELECTOR) { - vm.expectRevert(SafeTransferLib.ApproveFailed.selector); - } else if (mode == _REVERTS_WITH_ANY) { - (bool success,) = address(this).call( - abi.encodeWithSignature( - "verifySafeApprove(address,address,uint256)", token, to, amount - ) - ); - assertFalse(success); - return; - } - this.verifySafeApprove(token, to, amount); - } - - function verifySafeApprove(address token, address to, uint256 amount) public { - SafeTransferLib.safeApprove(_brutalized(address(token)), _brutalized(to), amount); - - assertEq(ERC20(token).allowance(address(this), to), amount); - } - - function forceApprove(address token, address from, address to, uint256 amount) public { - if (token == address(erc20)) { - bytes32 allowanceSlot; - /// @solidity memory-safe-assembly - assembly { - mstore(0x20, to) - mstore(0x0c, 0x7f5e9f20) // `_ALLOWANCE_SLOT_SEED`. - mstore(0x00, from) - allowanceSlot := keccak256(0x0c, 0x34) - } - vm.store(token, allowanceSlot, bytes32(uint256(amount))); - } else { - vm.store( - token, - keccak256(abi.encode(to, keccak256(abi.encode(from, uint256(2))))), - bytes32(uint256(amount)) - ); - } - - assertEq(ERC20(token).allowance(from, to), amount, "wrong allowance"); - } - - function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) public { - SafeTransferLib.forceSafeTransferETH(to, amount, gasStipend); - } - - function forceSafeTransferETH(address to, uint256 amount) public { - SafeTransferLib.forceSafeTransferETH(to, amount); - } - - function safeTransferETH(address to, uint256 amount) public { - SafeTransferLib.safeTransferETH(to, amount); - } - - function safeTransferAllETH(address to) public { - SafeTransferLib.safeTransferAllETH(to); - } - - function _generateGarbage() internal returns (bytes memory result) { - uint256 r = _random(); - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - mstore(0x00, r) - result := mload(0x40) - let n := and(r, 0x7f) - mstore(result, n) - r := keccak256(0x00, 0x40) - mstore(add(result, 0x20), r) - mstore(0x40, add(result, 0x100)) - if and(or(lt(n, 0x20), iszero(eq(r, 1))), gt(n, 0)) { break } - } - } - } - - function _generateNonGarbage() internal returns (bytes memory result) { - uint256 r = _random(); - /// @solidity memory-safe-assembly - assembly { - if iszero(and(r, 1)) { - result := mload(0x40) - mstore(result, 0x20) - mstore(add(result, 0x20), 1) - mstore(0x40, add(result, 0x40)) - } - } - } - - function testTotalSupplyQuery() public { - uint256 totalSupplyBefore = this.totalSupplyQuery(address(erc20)); - erc20.burn(address(this), 123); - assertEq(this.totalSupplyQuery(address(erc20)), totalSupplyBefore - 123); - vm.expectRevert(SafeTransferLib.TotalSupplyQueryFailed.selector); - this.totalSupplyQuery(address(0)); - } - - function totalSupplyQuery(address token) public view returns (uint256) { - return SafeTransferLib.totalSupply(token); - } - - function testForceSafeTransferETH(uint256 amount) public { - address vault; - amount = _bound(amount, 0, 1 ether); - vm.deal(address(this), 1 ether); - griefer.setReceiveNumLoops(1 << 128); - - vault = SafeTransferLib.forceSafeTransferETH(address(griefer), 1 ether); - assertNotEq(vault, address(0)); - assertEq(vault.balance, 1 ether); - - griefer.setReceiveNumLoops(0); - - if (_randomChance(2)) { - vm.prank(address(griefer)); - (bool success,) = vault.call(""); - assertTrue(success); - assertEq(address(griefer).balance, 1 ether); - } else { - (address to, bytes memory data) = _sampleToAndVaultCalldata(); - if (uint160(to) < 0xffff) return; - vm.prank(address(griefer)); - (bool success,) = vault.call(data); - assertTrue(success); - assertEq(to.balance, 1 ether); - } - } - - function _sampleToAndVaultCalldata() internal returns (address to, bytes memory data) { - if (_randomChance(2)) { - to = _randomHashedAddress(); - data = abi.encodePacked(abi.encode(to), new bytes(_randomUniform() % 64)); - return (to, data); - } - uint256 r = _randomUniform(); - uint256 n = _bound(_randomUniform(), 1, 32); - /// @solidity memory-safe-assembly - assembly { - data := mload(0x40) - mstore(add(data, 0x20), r) - mstore(data, n) - mstore(0x40, add(n, add(0x20, data))) - mstore(0x00, 0) - mstore(sub(0x20, n), r) - to := mload(0x00) - } - } - - function testForceSafeTransferETH() public { - address vault; - vm.deal(address(this), 1 ether); - vault = SafeTransferLib.forceSafeTransferETH(address(griefer), 0.1 ether); - assertEq(address(griefer).balance, 0.1 ether); - - griefer.setReceiveNumLoops(1 << 128); - vault = SafeTransferLib.forceSafeTransferETH(address(griefer), 0.1 ether); - assertEq(address(griefer).balance, 0.1 ether); - - griefer.setReceiveNumLoops(0); - griefer.execute(vault, abi.encode(address(griefer))); - assertEq(address(griefer).balance, 0.2 ether); - - griefer.setReceiveNumLoops(1 << 128); - vault = SafeTransferLib.forceSafeTransferETH(address(griefer), 0.1 ether); - - griefer.setReceiveNumLoops(0); - griefer.execute(vault, ""); - assertEq(address(griefer).balance, 0.3 ether); - - griefer.setReceiveNumLoops(1 << 128); - vault = SafeTransferLib.forceSafeTransferETH(address(griefer), 0.1 ether); - - griefer.setReceiveNumLoops(0); - griefer.execute(vault, abi.encodePacked(address(griefer))); - assertEq(address(griefer).balance, 0.4 ether); - - address anotherRecipient = address(new Griefer()); - - griefer.setReceiveNumLoops(1 << 128); - vault = SafeTransferLib.forceSafeTransferETH(address(griefer), 0.1 ether); - - griefer.setReceiveNumLoops(0); - griefer.execute(vault, abi.encodePacked(address(anotherRecipient))); - assertEq(address(anotherRecipient).balance, 0.1 ether); - } -} diff --git a/grouperBot/lib/solady/test/ext/zksync/SignatureCheckerLib.t.sol b/grouperBot/lib/solady/test/ext/zksync/SignatureCheckerLib.t.sol deleted file mode 100644 index aa4647a..0000000 --- a/grouperBot/lib/solady/test/ext/zksync/SignatureCheckerLib.t.sol +++ /dev/null @@ -1,387 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./../../utils/SoladyTest.sol"; -import {SignatureCheckerLib} from "../../../src/utils/ext/zksync/SignatureCheckerLib.sol"; -import {ECDSA} from "../../../src/utils/ECDSA.sol"; -import {MockERC1271Wallet} from "./../../utils/mocks/MockERC1271Wallet.sol"; -import {MockERC1271Malicious} from "./../../utils/mocks/MockERC1271Malicious.sol"; - -contract SignatureCheckerLibTest is SoladyTest { - bytes32 constant TEST_MESSAGE = - 0x7dbaf558b0a1a5dc7a67202117ab143c1d8605a983e4a743bc06fcc03162dc0d; - - bytes32 constant WRONG_MESSAGE = - 0x2d0828dd7c97cff316356da3c16c68ba2316886a0e05ebafb8291939310d51a3; - - address constant SIGNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; - - address constant OTHER = address(uint160(1)); - - bytes32 constant TEST_SIGNED_MESSAGE_HASH = - 0x7d768af957ef8cbf6219a37e743d5546d911dae3e46449d8a5810522db2ef65e; - - bytes32 constant WRONG_SIGNED_MESSAGE_HASH = - 0x8cd3e659093d21364c6330514aff328218aa29c2693c5b0e96602df075561952; - - bytes constant SIGNATURE = - hex"8688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - - bytes constant INVALID_SIGNATURE = - hex"7688e590483917863a35ef230c0f839be8418aa4ee765228eddfcea7fe2652815db01c2c84b0ec746e1b74d97475c599b3d3419fa7181b4e01de62c02b721aea1b"; - - MockERC1271Wallet mockERC1271Wallet; - - MockERC1271Malicious mockERC1271Malicious; - - function setUp() public { - mockERC1271Wallet = new MockERC1271Wallet(SIGNER); - mockERC1271Malicious = new MockERC1271Malicious(); - } - - function testSignatureCheckerOnEOAWithMatchingSignerAndSignature() public { - _checkSignature(SIGNER, TEST_SIGNED_MESSAGE_HASH, SIGNATURE, true); - } - - function testSignatureCheckerOnEOAWithInvalidSigner() public { - _checkSignature(OTHER, TEST_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnEOAWithWrongSignedMessageHash() public { - _checkSignature(SIGNER, WRONG_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnEOAWithInvalidSignature() public { - _checkSignature(SIGNER, TEST_SIGNED_MESSAGE_HASH, INVALID_SIGNATURE, false); - } - - function testSignatureCheckerOnWalletWithMatchingSignerAndSignature() public { - address signer = address(mockERC1271Wallet); - bytes32 hash = TEST_SIGNED_MESSAGE_HASH; - bytes memory signature = SIGNATURE; - _checkSignature(true, signer, hash, signature, true); - _checkSignature(false, signer, hash, signature, true); - vm.etch(signer, ""); - _checkSignature(false, signer, hash, signature, false); - } - - function testSignatureCheckerOnWalletWithInvalidSigner() public { - _checkSignatureBothModes(address(this), TEST_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnWalletWithZeroAddressSigner() public { - _checkSignatureBothModes(address(0), TEST_SIGNED_MESSAGE_HASH, SIGNATURE, false); - } - - function testSignatureCheckerOnWalletWithWrongSignedMessageHash() public { - _checkSignatureBothModes( - address(mockERC1271Wallet), WRONG_SIGNED_MESSAGE_HASH, SIGNATURE, false - ); - } - - function testSignatureCheckerOnWalletWithInvalidSignature() public { - _checkSignatureBothModes( - address(mockERC1271Wallet), TEST_SIGNED_MESSAGE_HASH, INVALID_SIGNATURE, false - ); - } - - function testSignatureCheckerOnMaliciousWallet() public { - _checkSignatureBothModes( - address(mockERC1271Malicious), WRONG_SIGNED_MESSAGE_HASH, SIGNATURE, false - ); - } - - function testSignatureChecker(bytes32 digest) public { - (address signer, uint256 privateKey) = _randomSigner(); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - _checkSignature(signer, digest, abi.encodePacked(r, s, v), true); - - if (_randomChance(8)) { - assertEq( - this.isValidSignatureNowCalldata(signer, digest, abi.encodePacked(r, s, v)), true - ); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encodePacked(r, s, v)), - true - ); - assertEq( - SignatureCheckerLib.isValidSignatureNow( - signer, digest, abi.encodePacked(r, s, v + 1) - ), - false - ); - assertEq( - SignatureCheckerLib.isValidSignatureNow( - signer, digest, abi.encodePacked(r, s, v - 1) - ), - false - ); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, v, r, s), true); - } - - if (_randomChance(8)) { - bytes32 vs; - /// @solidity memory-safe-assembly - assembly { - vs := or(shl(255, sub(v, 27)), s) - } - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, r, vs), true); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encode(r, vs)), true - ); - assertEq(this.isValidSignatureNowCalldata(signer, digest, abi.encode(r, vs)), true); - } - - if (_randomChance(8)) { - bytes32 vsc; // Corrupted `vs`. - /// @solidity memory-safe-assembly - assembly { - vsc := or(shl(255, xor(1, sub(v, 27))), s) - } - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, r, vsc), false); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encode(r, vsc)), false - ); - assertEq(this.isValidSignatureNowCalldata(signer, digest, abi.encode(r, vsc)), false); - } - - if (_randomChance(8) && r != bytes32(0) && s != bytes32(0)) { - bytes32 rc = bytes32(uint256(r) - (_random() & 1)); // Corrupted `r`. - bytes32 sc = bytes32(uint256(s) - (_random() & 1)); // Corrupted `s`. - bool anyCorrupted = rc != r || sc != s; - _checkSignature(signer, digest, abi.encodePacked(rc, sc, v), !anyCorrupted); - } - - if (_randomChance(8)) { - uint8 vc = uint8(_random()); // Corrupted `v`. - while (vc == 28 || vc == 27) vc = uint8(_random()); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, digest, vc, r, s), false); - assertEq( - SignatureCheckerLib.isValidSignatureNow(signer, digest, abi.encodePacked(r, s, vc)), - false - ); - assertEq( - this.isValidSignatureNowCalldata(signer, digest, abi.encodePacked(r, s, vc)), false - ); - } - } - - function _checkSignatureBothModes( - address signer, - bytes32 hash, - bytes memory signature, - bool expectedResult - ) internal { - _checkSignature(false, signer, hash, signature, expectedResult); - _checkSignature(true, signer, hash, signature, expectedResult); - } - - function _checkSignature( - address signer, - bytes32 hash, - bytes memory signature, - bool expectedResult - ) internal { - _checkSignature(false, signer, hash, signature, expectedResult); - } - - function _checkSignature( - bool onlyERC1271, - address signer, - bytes32 hash, - bytes memory signature, - bool expectedResult - ) internal { - bool callResult; - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - - // `bytes4(keccak256("isValidSignatureNow(address,bytes32,bytes)"))`. - mstore(m, shl(224, 0x6ccea652)) - if onlyERC1271 { - // `bytes4(keccak256("isValidERC1271SignatureNow(address,bytes32,bytes)"))`. - mstore(m, shl(224, 0x3ae5d83c)) - } - // We'll still clean the upper 96 bits of signer, - // so that it will pass the implicit calldata check added by Solidity. - mstore(add(m, 0x04), shr(96, shl(96, signer))) - mstore(add(m, 0x24), hash) - mstore(add(m, 0x44), 0x60) // Offset of signature in calldata. - mstore(add(m, 0x64), mload(signature)) - mstore(add(m, 0x84), mload(add(signature, 0x20))) - mstore(add(m, 0xa4), mload(add(signature, 0x40))) - mstore(add(m, 0xc4), mload(add(signature, 0x60))) - // Brutalize the bytes following the 8-bit `v`. All ones will do. - mstore(add(m, 0xc5), not(0)) - - // We have to do the call in assembly to ensure that Solidity does not - // clean up the brutalized bits. - callResult := - and( - and( - // Whether the returndata is equal to 1. - eq(mload(0x00), 1), - // Whether the returndata is exactly 0x20 bytes (1 word) long . - eq(returndatasize(), 0x20) - ), - // Whether the staticcall does not revert. - // This must be placed at the end of the `and` clause, - // as the arguments are evaluated from right to left. - staticcall( - gas(), // Remaining gas. - address(), // The current contract's address. - m, // Offset of calldata in memory. - 0xe4, // Length of calldata in memory. - 0x00, // Offset of returndata. - 0x20 // Length of returndata to write. - ) - ) - } - assertEq(callResult, expectedResult); - - uint8 v; - bytes32 r; - bytes32 s; - bytes32 vs; - /// @solidity memory-safe-assembly - assembly { - // Contaminate the upper 96 bits. - signer := or(shl(160, 1), signer) - // Extract `r`, `s`, `v`. - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := byte(0, mload(add(signature, 0x60))) - // Pack `vs`. - vs := or(shl(255, sub(v, 27)), s) - - // Brutalize the memory. Just all ones will do. - let m := mload(0x40) - for { let i := 0 } lt(i, 30) { i := add(i, 1) } { mstore(add(m, shl(5, i)), not(0)) } - } - - if (onlyERC1271) { - assertEq( - SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, r, vs), expectedResult - ); - assertEq( - SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, v, r, s), - expectedResult - ); - } else { - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, r, vs), expectedResult); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, v, r, s), expectedResult); - } - } - - function isValidSignatureNow(address signer, bytes32 hash, bytes calldata signature) - external - returns (bool result) - { - bool signatureIsBrutalized; - /// @solidity memory-safe-assembly - assembly { - // Contaminate the upper 96 bits. - signer := or(shl(160, 1), signer) - // Ensure that the bytes right after the signature is brutalized. - signatureIsBrutalized := calldataload(add(signature.offset, signature.length)) - } - if (!signatureIsBrutalized) revert("Signature is not brutalized."); - - result = SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, signature), result); - } - - function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes calldata signature) - external - returns (bool result) - { - bool signatureIsBrutalized; - /// @solidity memory-safe-assembly - assembly { - // Contaminate the upper 96 bits. - signer := or(shl(160, 1), signer) - // Ensure that the bytes right after the signature is brutalized. - signatureIsBrutalized := calldataload(add(signature.offset, signature.length)) - } - if (!signatureIsBrutalized) revert("Signature is not brutalized."); - - result = SignatureCheckerLib.isValidERC1271SignatureNowCalldata(signer, hash, signature); - assertEq(SignatureCheckerLib.isValidERC1271SignatureNow(signer, hash, signature), result); - } - - function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature) - external - view - returns (bool result) - { - result = SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature); - } - - function isValidERC1271SignatureNowCalldata( - address signer, - bytes32 hash, - bytes calldata signature - ) external view returns (bool result) { - result = SignatureCheckerLib.isValidERC1271SignatureNowCalldata(signer, hash, signature); - } - - function testEmptyCalldataHelpers() public { - assertFalse( - SignatureCheckerLib.isValidSignatureNow( - address(1), bytes32(0), SignatureCheckerLib.emptySignature() - ) - ); - } - - function testToEthSignedMessageHashDifferential(bytes32 hash) public { - assertEq( - SignatureCheckerLib.toEthSignedMessageHash(hash), ECDSA.toEthSignedMessageHash(hash) - ); - } - - function testToEthSignedMessageHashDifferential(bytes memory s) public { - assertEq(SignatureCheckerLib.toEthSignedMessageHash(s), ECDSA.toEthSignedMessageHash(s)); - } - - function testSignatureCheckerPassthrough(bytes calldata signature) public { - bytes32 hash = keccak256(signature); - mockERC1271Wallet.setUseSignaturePassthrough(true); - if (_randomChance(8)) { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - } - address signer = address(mockERC1271Wallet); - assertEq(SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature), true); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, signature), true); - - hash = bytes32(uint256(hash) ^ 1); - assertEq(SignatureCheckerLib.isValidSignatureNowCalldata(signer, hash, signature), false); - assertEq(SignatureCheckerLib.isValidSignatureNow(signer, hash, signature), false); - } - - function _makeShortSignature(bytes memory signature) - internal - pure - returns (bytes memory result) - { - require(signature.length == 65); - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - let r := mload(add(signature, 0x20)) - let s := mload(add(signature, 0x40)) - let v := byte(0, mload(add(signature, 0x60))) - let vs := 0 - switch v - case 27 { vs := shr(1, shl(1, s)) } - case 28 { vs := or(shl(255, 1), shr(1, shl(1, s))) } - default { invalid() } - mstore(result, 0x40) // Length. - mstore(add(result, 0x20), r) - mstore(add(result, 0x40), vs) - mstore(0x40, add(result, 0x60)) // Allocate memory. - } - } -} diff --git a/grouperBot/lib/solady/test/utils/Brutalizer.sol b/grouperBot/lib/solady/test/utils/Brutalizer.sol deleted file mode 100644 index 1c6447a..0000000 --- a/grouperBot/lib/solady/test/utils/Brutalizer.sol +++ /dev/null @@ -1,888 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract Brutalizer { - /// @dev Multiplier for a mulmod Lehmer psuedorandom number generator. - /// Prime, and a primitive root of `_LPRNG_MODULO`. - uint256 private constant _LPRNG_MULTIPLIER = 0x100000000000000000000000000000051; - - /// @dev Modulo for a mulmod Lehmer psuedorandom number generator. (prime) - uint256 private constant _LPRNG_MODULO = - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43; - - /// @dev Fills the memory with junk, for more robust testing of inline assembly - /// which reads/write to the memory. - function _brutalizeMemory() internal view { - // To prevent a solidity 0.8.13 bug. - // See: https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug - // Basically, we need to access a solidity variable from the assembly to - // tell the compiler that this assembly block is not in isolation. - uint256 zero; - /// @solidity memory-safe-assembly - assembly { - let offset := mload(0x40) // Start the offset at the free memory pointer. - calldatacopy(add(offset, 0x20), zero, calldatasize()) - mstore(offset, add(caller(), gas())) - - // Fill the 64 bytes of scratch space with garbage. - let r := keccak256(offset, add(calldatasize(), 0x40)) - mstore(zero, r) - mstore(0x20, keccak256(zero, 0x40)) - r := mulmod(mload(0x10), _LPRNG_MULTIPLIER, _LPRNG_MODULO) - - let cSize := add(codesize(), iszero(codesize())) - if iszero(lt(cSize, 32)) { cSize := sub(cSize, and(mload(0x02), 0x1f)) } - let start := mod(mload(0x10), cSize) - let size := mul(sub(cSize, start), gt(cSize, start)) - let times := div(0x7ffff, cSize) - if iszero(lt(times, 128)) { times := 128 } - - // Occasionally offset the offset by a pseudorandom large amount. - // Can't be too large, or we will easily get out-of-gas errors. - offset := add(offset, mul(iszero(and(r, 0xf00000000)), and(shr(64, r), 0xfffff))) - - // Fill the free memory with garbage. - // prettier-ignore - for { let w := not(0) } 1 {} { - mstore(offset, mload(0x00)) - mstore(add(offset, 0x20), mload(0x20)) - offset := add(offset, 0x40) - // We use codecopy instead of the identity precompile - // to avoid polluting the `forge test -vvvv` output with tons of junk. - codecopy(offset, start, size) - codecopy(add(offset, size), 0x00, start) - offset := add(offset, cSize) - times := add(times, w) // `sub(times, 1)`. - if iszero(times) { break } - } - // With a 1/16 chance, copy the contract's code to the scratch space. - if iszero(and(0xf00, r)) { - codecopy(0x00, mod(shr(128, r), add(codesize(), codesize())), 0x40) - mstore8(and(r, 0x3f), iszero(and(0x100000, r))) - } - } - } - - /// @dev Fills the scratch space with junk, for more robust testing of inline assembly - /// which reads/write to the memory. - function _brutalizeScratchSpace() internal view { - // To prevent a solidity 0.8.13 bug. - // See: https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug - // Basically, we need to access a solidity variable from the assembly to - // tell the compiler that this assembly block is not in isolation. - uint256 zero; - /// @solidity memory-safe-assembly - assembly { - let offset := mload(0x40) // Start the offset at the free memory pointer. - calldatacopy(add(offset, 0x20), zero, calldatasize()) - mstore(offset, add(caller(), gas())) - - // Fill the 64 bytes of scratch space with garbage. - let r := keccak256(offset, add(calldatasize(), 0x40)) - mstore(zero, r) - mstore(0x20, keccak256(zero, 0x40)) - r := mulmod(mload(0x10), _LPRNG_MULTIPLIER, _LPRNG_MODULO) - if iszero(and(0xf00, r)) { - codecopy(0x00, mod(shr(128, r), add(codesize(), codesize())), 0x40) - mstore8(and(r, 0x3f), iszero(and(0x100000, r))) - } - } - } - - /// @dev Fills the lower memory with junk, for more robust testing of inline assembly - /// which reads/write to the memory. - /// For efficiency, this only fills a small portion of the free memory. - function _brutalizeLowerMemory() internal view { - // To prevent a solidity 0.8.13 bug. - // See: https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug - // Basically, we need to access a solidity variable from the assembly to - // tell the compiler that this assembly block is not in isolation. - uint256 zero; - /// @solidity memory-safe-assembly - assembly { - let offset := mload(0x40) // Start the offset at the free memory pointer. - calldatacopy(add(offset, 0x20), zero, calldatasize()) - mstore(offset, add(caller(), gas())) - - // Fill the 64 bytes of scratch space with garbage. - let r := keccak256(offset, add(calldatasize(), 0x40)) - mstore(zero, r) - mstore(0x20, keccak256(zero, 0x40)) - r := mulmod(mload(0x10), _LPRNG_MULTIPLIER, _LPRNG_MODULO) - - for {} 1 {} { - if iszero(and(0x7000, r)) { - let x := keccak256(zero, 0x40) - mstore(offset, x) - mstore(add(0x20, offset), x) - mstore(add(0x40, offset), x) - mstore(add(0x60, offset), x) - mstore(add(0x80, offset), x) - mstore(add(0xa0, offset), x) - mstore(add(0xc0, offset), x) - mstore(add(0xe0, offset), x) - mstore(add(0x100, offset), x) - mstore(add(0x120, offset), x) - mstore(add(0x140, offset), x) - mstore(add(0x160, offset), x) - mstore(add(0x180, offset), x) - mstore(add(0x1a0, offset), x) - mstore(add(0x1c0, offset), x) - mstore(add(0x1e0, offset), x) - mstore(add(0x200, offset), x) - mstore(add(0x220, offset), x) - mstore(add(0x240, offset), x) - mstore(add(0x260, offset), x) - break - } - codecopy(offset, byte(0, r), codesize()) - break - } - if iszero(and(0x300, r)) { - codecopy(0x00, mod(shr(128, r), add(codesize(), codesize())), 0x40) - mstore8(and(r, 0x3f), iszero(and(0x100000, r))) - } - } - } - - /// @dev Fills the memory with junk, for more robust testing of inline assembly - /// which reads/write to the memory. - modifier brutalizeMemory() { - _brutalizeMemory(); - _; - _checkMemory(); - } - - /// @dev Fills the scratch space with junk, for more robust testing of inline assembly - /// which reads/write to the memory. - modifier brutalizeScratchSpace() { - _brutalizeScratchSpace(); - _; - _checkMemory(); - } - - /// @dev Fills the lower memory with junk, for more robust testing of inline assembly - /// which reads/write to the memory. - modifier brutalizeLowerMemory() { - _brutalizeLowerMemory(); - _; - _checkMemory(); - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalized(address value) internal pure returns (address result) { - uint256 r = uint256(uint160(value)); - r = (__brutalizerRandomness(r) << 160) ^ r; - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint8(uint8 value) internal pure returns (uint8 result) { - uint256 r = (__brutalizerRandomness(value) << 8) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes1(bytes1 value) internal pure returns (bytes1 result) { - bytes32 r = __brutalizedBytesN(value, 8); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint16(uint16 value) internal pure returns (uint16 result) { - uint256 r = (__brutalizerRandomness(value) << 16) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes2(bytes2 value) internal pure returns (bytes2 result) { - bytes32 r = __brutalizedBytesN(value, 16); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint24(uint24 value) internal pure returns (uint24 result) { - uint256 r = (__brutalizerRandomness(value) << 24) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes3(bytes3 value) internal pure returns (bytes3 result) { - bytes32 r = __brutalizedBytesN(value, 24); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint32(uint32 value) internal pure returns (uint32 result) { - uint256 r = (__brutalizerRandomness(value) << 32) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes4(bytes4 value) internal pure returns (bytes4 result) { - bytes32 r = __brutalizedBytesN(value, 32); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint40(uint40 value) internal pure returns (uint40 result) { - uint256 r = (__brutalizerRandomness(value) << 40) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes5(bytes5 value) internal pure returns (bytes5 result) { - bytes32 r = __brutalizedBytesN(value, 40); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint48(uint48 value) internal pure returns (uint48 result) { - uint256 r = (__brutalizerRandomness(value) << 48) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes6(bytes6 value) internal pure returns (bytes6 result) { - bytes32 r = __brutalizedBytesN(value, 48); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint56(uint56 value) internal pure returns (uint56 result) { - uint256 r = (__brutalizerRandomness(value) << 56) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes7(bytes7 value) internal pure returns (bytes7 result) { - bytes32 r = __brutalizedBytesN(value, 56); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint64(uint64 value) internal pure returns (uint64 result) { - uint256 r = (__brutalizerRandomness(value) << 64) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes8(bytes8 value) internal pure returns (bytes8 result) { - bytes32 r = __brutalizedBytesN(value, 64); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint72(uint72 value) internal pure returns (uint72 result) { - uint256 r = (__brutalizerRandomness(value) << 72) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes9(bytes9 value) internal pure returns (bytes9 result) { - bytes32 r = __brutalizedBytesN(value, 72); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint80(uint80 value) internal pure returns (uint80 result) { - uint256 r = (__brutalizerRandomness(value) << 80) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes10(bytes10 value) internal pure returns (bytes10 result) { - bytes32 r = __brutalizedBytesN(value, 80); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint88(uint88 value) internal pure returns (uint88 result) { - uint256 r = (__brutalizerRandomness(value) << 88) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes11(bytes11 value) internal pure returns (bytes11 result) { - bytes32 r = __brutalizedBytesN(value, 88); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint96(uint96 value) internal pure returns (uint96 result) { - uint256 r = (__brutalizerRandomness(value) << 96) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes12(bytes12 value) internal pure returns (bytes12 result) { - bytes32 r = __brutalizedBytesN(value, 96); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint104(uint104 value) internal pure returns (uint104 result) { - uint256 r = (__brutalizerRandomness(value) << 104) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes13(bytes13 value) internal pure returns (bytes13 result) { - bytes32 r = __brutalizedBytesN(value, 104); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint112(uint112 value) internal pure returns (uint112 result) { - uint256 r = (__brutalizerRandomness(value) << 112) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes14(bytes14 value) internal pure returns (bytes14 result) { - bytes32 r = __brutalizedBytesN(value, 112); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint120(uint120 value) internal pure returns (uint120 result) { - uint256 r = (__brutalizerRandomness(value) << 120) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes15(bytes15 value) internal pure returns (bytes15 result) { - bytes32 r = __brutalizedBytesN(value, 120); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint128(uint128 value) internal pure returns (uint128 result) { - uint256 r = (__brutalizerRandomness(value) << 128) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes16(bytes16 value) internal pure returns (bytes16 result) { - bytes32 r = __brutalizedBytesN(value, 128); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint136(uint136 value) internal pure returns (uint136 result) { - uint256 r = (__brutalizerRandomness(value) << 136) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes17(bytes17 value) internal pure returns (bytes17 result) { - bytes32 r = __brutalizedBytesN(value, 136); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint144(uint144 value) internal pure returns (uint144 result) { - uint256 r = (__brutalizerRandomness(value) << 144) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes18(bytes18 value) internal pure returns (bytes18 result) { - bytes32 r = __brutalizedBytesN(value, 144); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint152(uint152 value) internal pure returns (uint152 result) { - uint256 r = (__brutalizerRandomness(value) << 152) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes19(bytes19 value) internal pure returns (bytes19 result) { - bytes32 r = __brutalizedBytesN(value, 152); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint160(uint160 value) internal pure returns (uint160 result) { - uint256 r = (__brutalizerRandomness(value) << 160) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes20(bytes20 value) internal pure returns (bytes20 result) { - bytes32 r = __brutalizedBytesN(value, 160); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint168(uint168 value) internal pure returns (uint168 result) { - uint256 r = (__brutalizerRandomness(value) << 168) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes21(bytes21 value) internal pure returns (bytes21 result) { - bytes32 r = __brutalizedBytesN(value, 168); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint176(uint176 value) internal pure returns (uint176 result) { - uint256 r = (__brutalizerRandomness(value) << 176) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes22(bytes22 value) internal pure returns (bytes22 result) { - bytes32 r = __brutalizedBytesN(value, 176); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint184(uint184 value) internal pure returns (uint184 result) { - uint256 r = (__brutalizerRandomness(value) << 184) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes23(bytes23 value) internal pure returns (bytes23 result) { - bytes32 r = __brutalizedBytesN(value, 184); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint192(uint192 value) internal pure returns (uint192 result) { - uint256 r = (__brutalizerRandomness(value) << 192) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes24(bytes24 value) internal pure returns (bytes24 result) { - bytes32 r = __brutalizedBytesN(value, 192); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint200(uint200 value) internal pure returns (uint200 result) { - uint256 r = (__brutalizerRandomness(value) << 200) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes25(bytes25 value) internal pure returns (bytes25 result) { - bytes32 r = __brutalizedBytesN(value, 200); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint208(uint208 value) internal pure returns (uint208 result) { - uint256 r = (__brutalizerRandomness(value) << 208) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes26(bytes26 value) internal pure returns (bytes26 result) { - bytes32 r = __brutalizedBytesN(value, 208); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint216(uint216 value) internal pure returns (uint216 result) { - uint256 r = (__brutalizerRandomness(value) << 216) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes27(bytes27 value) internal pure returns (bytes27 result) { - bytes32 r = __brutalizedBytesN(value, 216); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint224(uint224 value) internal pure returns (uint224 result) { - uint256 r = (__brutalizerRandomness(value) << 224) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes28(bytes28 value) internal pure returns (bytes28 result) { - bytes32 r = __brutalizedBytesN(value, 224); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint232(uint232 value) internal pure returns (uint232 result) { - uint256 r = (__brutalizerRandomness(value) << 232) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes29(bytes29 value) internal pure returns (bytes29 result) { - bytes32 r = __brutalizedBytesN(value, 232); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint240(uint240 value) internal pure returns (uint240 result) { - uint256 r = (__brutalizerRandomness(value) << 240) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes30(bytes30 value) internal pure returns (bytes30 result) { - bytes32 r = __brutalizedBytesN(value, 240); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalizedUint248(uint248 value) internal pure returns (uint248 result) { - uint256 r = (__brutalizerRandomness(value) << 248) ^ uint256(value); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the lower bits dirtied. - function _brutalizedBytes31(bytes31 value) internal pure returns (bytes31 result) { - bytes32 r = __brutalizedBytesN(value, 248); - /// @solidity memory-safe-assembly - assembly { - result := r - } - } - - /// @dev Returns the result with the upper bits dirtied. - function _brutalized(bool value) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, 0x00, calldatasize()) - mstore(0x20, keccak256(result, calldatasize())) - mstore(0x10, xor(value, mload(0x10))) - let r := keccak256(0x00, 0x88) - mstore(0x10, r) - result := mul(iszero(iszero(value)), r) - if iszero(and(1, shr(128, mulmod(r, _LPRNG_MULTIPLIER, _LPRNG_MODULO)))) { - result := iszero(iszero(result)) - } - } - } - - /// @dev Returns a brutalizer randomness. - function __brutalizedBytesN(bytes32 x, uint256 s) private pure returns (bytes32) { - return bytes32(uint256((__brutalizerRandomness(uint256(x)) >> s) ^ uint256(x))); - } - - /// @dev Returns a brutalizer randomness. - function __brutalizerRandomness(uint256 seed) private pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - calldatacopy(result, 0x00, calldatasize()) - mstore(0x20, keccak256(result, calldatasize())) - mstore(0x10, xor(seed, mload(0x10))) - result := keccak256(0x00, 0x88) - mstore(0x10, result) - if iszero(and(7, shr(128, mulmod(result, _LPRNG_MULTIPLIER, _LPRNG_MODULO)))) { - result := 0 - } - } - } - - /// @dev Misaligns the free memory pointer. - /// The free memory pointer has a 1/32 chance to be aligned. - function _misalignFreeMemoryPointer() internal pure { - uint256 twoWords = 0x40; - /// @solidity memory-safe-assembly - assembly { - let m := mload(twoWords) - m := add(m, mul(and(keccak256(0x00, twoWords), 0x1f), iszero(and(m, 0x1f)))) - mstore(twoWords, m) - } - } - - /// @dev Check if the free memory pointer and the zero slot are not contaminated. - /// Useful for cases where these slots are used for temporary storage. - function _checkMemory() internal pure { - bool zeroSlotIsNotZero; - bool freeMemoryPointerOverflowed; - /// @solidity memory-safe-assembly - assembly { - // Write ones to the free memory, to make subsequent checks fail if - // insufficient memory is allocated. - mstore(mload(0x40), not(0)) - // Test at a lower, but reasonable limit for more safety room. - if gt(mload(0x40), 0xffffffff) { freeMemoryPointerOverflowed := 1 } - // Check the value of the zero slot. - zeroSlotIsNotZero := mload(0x60) - } - if (freeMemoryPointerOverflowed) revert("`0x40` overflowed!"); - if (zeroSlotIsNotZero) revert("`0x60` is not zero!"); - } - - /// @dev Check if `s`: - /// - Has sufficient memory allocated. - /// - Is zero right padded (cuz some frontends like Etherscan has issues - /// with decoding non-zero-right-padded strings). - function _checkMemory(bytes memory s) internal pure { - bool notZeroRightPadded; - bool insufficientMalloc; - /// @solidity memory-safe-assembly - assembly { - // Write ones to the free memory, to make subsequent checks fail if - // insufficient memory is allocated. - mstore(mload(0x40), not(0)) - let length := mload(s) - let lastWord := mload(add(add(s, 0x20), and(length, not(0x1f)))) - let remainder := and(length, 0x1f) - if remainder { if shl(mul(8, remainder), lastWord) { notZeroRightPadded := 1 } } - // Check if the memory allocated is sufficient. - if length { if gt(add(add(s, 0x20), length), mload(0x40)) { insufficientMalloc := 1 } } - } - if (notZeroRightPadded) revert("Not zero right padded!"); - if (insufficientMalloc) revert("Insufficient memory allocation!"); - _checkMemory(); - } - - /// @dev For checking the memory allocation for string `s`. - function _checkMemory(string memory s) internal pure { - _checkMemory(bytes(s)); - } - - /// @dev Check if `a`: - /// - Has sufficient memory allocated. - function _checkMemory(uint256[] memory a) internal pure { - bool insufficientMalloc; - /// @solidity memory-safe-assembly - assembly { - // Write ones to the free memory, to make subsequent checks fail if - // insufficient memory is allocated. - mstore(mload(0x40), not(0)) - // Check if the memory allocated is sufficient. - insufficientMalloc := gt(add(add(a, 0x20), shl(5, mload(a))), mload(0x40)) - } - if (insufficientMalloc) revert("Insufficient memory allocation!"); - _checkMemory(); - } - - /// @dev Check if `a`: - /// - Has sufficient memory allocated. - function _checkMemory(bytes32[] memory a) internal pure { - uint256[] memory casted; - /// @solidity memory-safe-assembly - assembly { - casted := a - } - _checkMemory(casted); - } - - /// @dev Check if `a`: - /// - Has sufficient memory allocated. - function _checkMemory(address[] memory a) internal pure { - uint256[] memory casted; - /// @solidity memory-safe-assembly - assembly { - casted := a - } - _checkMemory(casted); - } - - /// @dev Check if `a`: - /// - Has sufficient memory allocated. - function _checkMemory(bool[] memory a) internal pure { - uint256[] memory casted; - /// @solidity memory-safe-assembly - assembly { - casted := a - } - _checkMemory(casted); - } -} diff --git a/grouperBot/lib/solady/test/utils/InvariantTest.sol b/grouperBot/lib/solady/test/utils/InvariantTest.sol deleted file mode 100644 index 261af92..0000000 --- a/grouperBot/lib/solady/test/utils/InvariantTest.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract InvariantTest { - address[] private _targets; - - function targetContracts() public view virtual returns (address[] memory) { - require(_targets.length > 0, "NO_TARGET_CONTRACTS"); - return _targets; - } - - function _addTargetContract(address newTargetContract) internal virtual { - _targets.push(newTargetContract); - } -} diff --git a/grouperBot/lib/solady/test/utils/SoladyTest.sol b/grouperBot/lib/solady/test/utils/SoladyTest.sol deleted file mode 100644 index 4969db3..0000000 --- a/grouperBot/lib/solady/test/utils/SoladyTest.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "./forge-std/Test.sol"; -import "./TestPlus.sol"; - -contract SoladyTest is Test, TestPlus { - /// @dev Alias for `_hem`. - function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256) { - return _hem(x, min, max); - } -} diff --git a/grouperBot/lib/solady/test/utils/TestPlus.sol b/grouperBot/lib/solady/test/utils/TestPlus.sol deleted file mode 100644 index ef7b1e9..0000000 --- a/grouperBot/lib/solady/test/utils/TestPlus.sol +++ /dev/null @@ -1,763 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Brutalizer} from "./Brutalizer.sol"; - -contract TestPlus is Brutalizer { - event LogString(string name, string value); - event LogString(string value); - event LogBytes(string name, bytes value); - event LogBytes(bytes value); - event LogUint(string name, uint256 value); - event LogUint(uint256 value); - event LogBytes32(string name, bytes32 value); - event LogBytes32(bytes32 value); - event LogInt(string name, int256 value); - event LogInt(int256 value); - event LogAddress(string name, address value); - event LogAddress(address value); - event LogBool(string name, bool value); - event LogBool(bool value); - - event LogStringArray(string name, string[] value); - event LogStringArray(string[] value); - event LogBytesArray(string name, bytes[] value); - event LogBytesArray(bytes[] value); - event LogUintArray(string name, uint256[] value); - event LogUintArray(uint256[] value); - event LogBytes32Array(string name, bytes32[] value); - event LogBytes32Array(bytes32[] value); - event LogIntArray(string name, int256[] value); - event LogIntArray(int256[] value); - event LogAddressArray(string name, address[] value); - event LogAddressArray(address[] value); - event LogBoolArray(string name, bool[] value); - event LogBoolArray(bool[] value); - - /// @dev Canonical address of Nick's factory. - address internal constant _NICKS_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - - /// @dev The bytecode of Nick's factory. - bytes internal constant _NICKS_FACTORY_BYTECODE = - hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; - - /// @dev Canonical address of 0age's immutable create 2 factory. - address internal constant _IMMUTABLE_CREATE2_FACTORY = - 0x0000000000FFe8B47B3e2130213B802212439497; - - /// @dev The bytecode of 0age's immutable create 2 factory. - bytes internal constant _IMMUTABLE_CREATE2_FACTORY_BYTECODE = - hex"60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b34801561005057600080fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f35b61010f600480360360408110156100ae57600080fd5b813591908101906040810160208201356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd5b8035906020019184600183028401116401000000008311171561010457600080fd5b509092509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081101561015b57600080fd5b8135919081019060408101602082013564010000000081111561017d57600080fd5b82018360208201111561018f57600080fd5b803590602001918460018302840111640100000000831117156101b157600080fd5b509092509050610592565b3480156101c857600080fd5b5061010f600480360360408110156101df57600080fd5b508035906020013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116155b6102a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260458152602001806107746045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b6020831061033557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016102f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183528085528251928201929092207fff000000000000000000000000000000000000000000000000000000000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201969096526055808201979097528251808203909701875260750182525084519484019490942073ffffffffffffffffffffffffffffffffffffffff81166000908152938490529390922054929350505060ff16156104a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180610735603f913960400191505060405180910390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806107b96046913960600191505060405180910390fd5b50505073ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559392505050565b6000308484846040516020018083838082843760408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001825280845281516020928301207fff000000000000000000000000000000000000000000000000000000000000008383015260609990991b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166021820152603581019790975260558088019890985282518088039098018852607590960182525085519585019590952073ffffffffffffffffffffffffffffffffffffffff81166000908152948590529490932054939450505060ff909116159050610697575060005b9392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091523060601b6021830152603582018590526055808301859052835180840390910181526075909201835281519181019190912073ffffffffffffffffffffffffffffffffffffffff81166000908152918290529190205460ff161561072e575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a723058202bdc55310d97c4088f18acf04253db593f0914059f0c781a9df3624dcef0d1cf64736f6c634300050a0032"; - - /// @dev `address(bytes20(uint160(uint256(keccak256("hevm cheat code")))))`. - address private constant _VM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; - - /// @dev This is the keccak256 of a very long string I randomly mashed on my keyboard. - uint256 private constant _TESTPLUS_RANDOMNESS_SLOT = - 0xd715531fe383f818c5f158c342925dcf01b954d24678ada4d07c36af0f20e1ee; - - /// @dev The maximum private key. - uint256 private constant _PRIVATE_KEY_MAX = - 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140; - - /// @dev Some constant to brutalize the upper bits of addresses. - uint256 private constant _ADDRESS_BRUTALIZER = 0xc0618c2bfd481dcf3e31738f; - - /// @dev Multiplier for a mulmod Lehmer psuedorandom number generator. - /// Prime, and a primitive root of `_LPRNG_MODULO`. - uint256 private constant _LPRNG_MULTIPLIER = 0x100000000000000000000000000000051; - - /// @dev Modulo for a mulmod Lehmer psuedorandom number generator. (prime) - uint256 private constant _LPRNG_MODULO = - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43; - - /// @dev Returns whether the `value` has been generated for `typeId` and `groupId` before. - function __markAsGenerated(bytes32 typeId, bytes32 groupId, uint256 value) - private - returns (bool isSet) - { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - mstore(0x00, value) - mstore(0x20, groupId) - mstore(0x40, typeId) - mstore(0x60, _TESTPLUS_RANDOMNESS_SLOT) - let s := keccak256(0x00, 0x80) - isSet := sload(s) - sstore(s, 1) - mstore(0x40, m) // Restore the free memory pointer. - mstore(0x60, 0) // Restore the zero pointer. - } - } - - /// @dev Returns a pseudorandom random number from [0 .. 2**256 - 1] (inclusive). - /// For usage in fuzz tests, please ensure that the function has an unnamed uint256 argument. - /// e.g. `testSomething(uint256) public`. - /// This function may return a previously returned result. - function _random() internal returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := _TESTPLUS_RANDOMNESS_SLOT - let sValue := sload(result) - mstore(0x20, sValue) - let r := keccak256(0x20, 0x40) - // If the storage is uninitialized, initialize it to the keccak256 of the calldata. - if iszero(sValue) { - sValue := result - calldatacopy(mload(0x40), 0x00, calldatasize()) - r := keccak256(mload(0x40), calldatasize()) - } - sstore(result, add(r, 1)) - - // Do some biased sampling for more robust tests. - // prettier-ignore - for {} 1 {} { - let y := mulmod(r, _LPRNG_MULTIPLIER, _LPRNG_MODULO) - // With a 1/256 chance, randomly set `r` to any of 0,1,2,3. - if iszero(byte(19, y)) { - r := and(byte(11, y), 3) - break - } - let d := byte(17, y) - // With a 1/2 chance, set `r` to near a random power of 2. - if iszero(and(2, d)) { - // Set `t` either `not(0)` or `xor(sValue, r)`. - let t := or(xor(sValue, r), sub(0, and(1, d))) - // Set `r` to `t` shifted left or right. - // prettier-ignore - for {} 1 {} { - if iszero(and(8, d)) { - if iszero(and(16, d)) { t := 1 } - if iszero(and(32, d)) { - r := add(shl(shl(3, and(byte(7, y), 31)), t), sub(3, and(7, r))) - break - } - r := add(shl(byte(7, y), t), sub(511, and(1023, r))) - break - } - if iszero(and(16, d)) { t := shl(255, 1) } - if iszero(and(32, d)) { - r := add(shr(shl(3, and(byte(7, y), 31)), t), sub(3, and(7, r))) - break - } - r := add(shr(byte(7, y), t), sub(511, and(1023, r))) - break - } - // With a 1/2 chance, negate `r`. - r := xor(sub(0, shr(7, d)), r) - break - } - // Otherwise, just set `r` to `xor(sValue, r)`. - r := xor(sValue, r) - break - } - result := r - } - } - - /// @dev Returns a pseudorandom random number from [0 .. 2**256 - 1] (inclusive). - /// For usage in fuzz tests, please ensure that the function has an unnamed uint256 argument. - /// e.g. `testSomething(uint256) public`. - function _randomUnique(uint256 groupId) internal returns (uint256 result) { - result = _randomUnique(bytes32(groupId)); - } - - /// @dev Returns a pseudorandom random number from [0 .. 2**256 - 1] (inclusive). - /// For usage in fuzz tests, please ensure that the function has an unnamed uint256 argument. - /// e.g. `testSomething(uint256) public`. - function _randomUnique(bytes32 groupId) internal returns (uint256 result) { - do { - result = _random(); - } while (__markAsGenerated("uint256", groupId, result)); - } - - /// @dev Returns a pseudorandom random number from [0 .. 2**256 - 1] (inclusive). - /// For usage in fuzz tests, please ensure that the function has an unnamed uint256 argument. - /// e.g. `testSomething(uint256) public`. - function _randomUnique() internal returns (uint256 result) { - result = _randomUnique(""); - } - - /// @dev Returns a pseudorandom number, uniformly distributed in [0 .. 2**256 - 1] (inclusive). - function _randomUniform() internal returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := _TESTPLUS_RANDOMNESS_SLOT - // prettier-ignore - for { let sValue := sload(result) } 1 {} { - // If the storage is uninitialized, initialize it to the keccak256 of the calldata. - if iszero(sValue) { - calldatacopy(mload(0x40), 0x00, calldatasize()) - sValue := keccak256(mload(0x40), calldatasize()) - sstore(result, sValue) - result := sValue - break - } - mstore(0x1f, sValue) - sValue := keccak256(0x20, 0x40) - sstore(result, sValue) - result := sValue - break - } - } - } - - /// @dev Returns a boolean with an approximately 1/n chance of being true. - /// This function may return a previously returned result. - function _randomChance(uint256 n) internal returns (bool result) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - result := iszero(mod(r, n)) - } - } - - /// @dev Returns a random private key that can be used for ECDSA signing. - /// This function may return a previously returned result. - function _randomPrivateKey() internal returns (uint256 result) { - result = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - for {} 1 {} { - if iszero(and(result, 0x10)) { - if iszero(and(result, 0x20)) { - result := add(and(result, 0xf), 1) - break - } - result := sub(_PRIVATE_KEY_MAX, and(result, 0xf)) - break - } - result := shr(1, result) - break - } - } - } - - /// @dev Returns a random private key that can be used for ECDSA signing. - function _randomUniquePrivateKey(uint256 groupId) internal returns (uint256 result) { - result = _randomUniquePrivateKey(bytes32(groupId)); - } - - /// @dev Returns a random private key that can be used for ECDSA signing. - function _randomUniquePrivateKey(bytes32 groupId) internal returns (uint256 result) { - do { - result = _randomPrivateKey(); - } while (__markAsGenerated("uint256", groupId, result)); - } - - /// @dev Returns a random private key that can be used for ECDSA signing. - function _randomUniquePrivateKey() internal returns (uint256 result) { - result = _randomUniquePrivateKey(""); - } - - /// @dev Private helper function to get the signer from a private key. - function __getSigner(uint256 privateKey) private view returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, 0xffa18649) // `addr(uint256)`. - mstore(0x20, privateKey) - result := mload(staticcall(gas(), _VM_ADDRESS, 0x1c, 0x24, 0x01, 0x20)) - } - } - - /// @dev Private helper to ensure an address is brutalized. - function __toBrutalizedAddress(address a) private pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(0x00, 0x88) - result := xor(shl(160, xor(result, _ADDRESS_BRUTALIZER)), a) - mstore(0x10, result) - } - } - - /// @dev Private helper to ensure an address is brutalized. - function __toBrutalizedAddress(uint256 a) private pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(0x00, 0x88) - result := xor(shl(160, xor(result, _ADDRESS_BRUTALIZER)), a) - mstore(0x10, result) - } - } - - /// @dev Returns a pseudorandom signer and its private key. - /// This function may return a previously returned result. - /// The signer may have dirty upper 96 bits. - function _randomSigner() internal returns (address signer, uint256 privateKey) { - privateKey = _randomPrivateKey(); - signer = __toBrutalizedAddress(__getSigner(privateKey)); - } - - /// @dev Returns a pseudorandom signer and its private key. - /// The signer may have dirty upper 96 bits. - function _randomUniqueSigner(uint256 groupId) - internal - returns (address signer, uint256 privateKey) - { - (signer, privateKey) = _randomUniqueSigner(bytes32(groupId)); - } - - /// @dev Returns a pseudorandom signer and its private key. - /// The signer may have dirty upper 96 bits. - function _randomUniqueSigner(bytes32 groupId) - internal - returns (address signer, uint256 privateKey) - { - privateKey = _randomUniquePrivateKey(groupId); - signer = __toBrutalizedAddress(__getSigner(privateKey)); - } - - /// @dev Returns a pseudorandom signer and its private key. - /// The signer may have dirty upper 96 bits. - function _randomUniqueSigner() internal returns (address signer, uint256 privateKey) { - (signer, privateKey) = _randomUniqueSigner(""); - } - - /// @dev Returns a pseudorandom address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - /// This function may return a previously returned result. - function _randomAddress() internal returns (address result) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - result := xor(shl(158, r), and(sub(7, shr(252, r)), r)) - } - } - - /// @dev Returns a pseudorandom address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - function _randomUniqueAddress(uint256 groupId) internal returns (address result) { - result = _randomUniqueAddress(bytes32(groupId)); - } - - /// @dev Returns a pseudorandom address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - function _randomUniqueAddress(bytes32 groupId) internal returns (address result) { - do { - result = _randomAddress(); - } while (__markAsGenerated("address", groupId, uint160(result))); - } - - /// @dev Returns a pseudorandom address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - function _randomUniqueAddress() internal returns (address result) { - result = _randomUniqueAddress(""); - } - - /// @dev Returns a pseudorandom non-zero address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - /// This function may return a previously returned result. - function _randomNonZeroAddress() internal returns (address result) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - result := xor(shl(158, r), and(sub(7, shr(252, r)), r)) - if iszero(shl(96, result)) { - mstore(0x00, result) - result := keccak256(0x00, 0x30) - } - } - } - - /// @dev Returns a pseudorandom non-zero address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - function _randomUniqueNonZeroAddress(uint256 groupId) internal returns (address result) { - result = _randomUniqueNonZeroAddress(bytes32(groupId)); - } - - /// @dev Returns a pseudorandom non-zero address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - function _randomUniqueNonZeroAddress(bytes32 groupId) internal returns (address result) { - do { - result = _randomNonZeroAddress(); - } while (__markAsGenerated("address", groupId, uint160(result))); - } - - /// @dev Returns a pseudorandom non-zero address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - function _randomUniqueNonZeroAddress() internal returns (address result) { - result = _randomUniqueNonZeroAddress(""); - } - - /// @dev Cleans the upper 96 bits of the address. - /// This is included so that CI passes for older solc versions with --via-ir. - function _cleaned(address a) internal pure returns (address result) { - /// @solidity memory-safe-assembly - assembly { - result := shr(96, shl(96, a)) - } - } - - /// @dev Returns a pseudorandom address. - /// The result may have dirty upper 96 bits. - /// This function may return a previously returned result. - function _randomAddressWithVmVars() internal returns (address result) { - if (_randomChance(8)) result = __toBrutalizedAddress(_randomVmVar()); - else result = _randomAddress(); - } - - /// @dev Returns a pseudorandom non-zero address. - /// The result may have dirty upper 96 bits. - /// This function may return a previously returned result. - function _randomNonZeroAddressWithVmVars() internal returns (address result) { - do { - if (_randomChance(8)) result = __toBrutalizedAddress(_randomVmVar()); - else result = _randomAddress(); - } while (result == address(0)); - } - - /// @dev Returns a random variable in the virtual machine. - function _randomVmVar() internal returns (uint256 result) { - uint256 r = _randomUniform(); - uint256 t = r % 11; - if (t <= 4) { - if (t == 0) return uint160(address(this)); - if (t == 1) return uint160(tx.origin); - if (t == 2) return uint160(msg.sender); - if (t == 3) return uint160(_VM_ADDRESS); - if (t == 4) return uint160(0x000000000000000000636F6e736F6c652e6c6f67); - } - uint256 y = r >> 32; - if (t == 5) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, r) - codecopy(0x00, mod(and(y, 0xffff), add(codesize(), 0x20)), 0x20) - result := mload(0x00) - } - return result; - } - if (t == 6) { - /// @solidity memory-safe-assembly - assembly { - calldatacopy(0x00, mod(and(y, 0xffff), add(calldatasize(), 0x20)), 0x20) - result := mload(0x00) - } - return result; - } - if (t == 7) { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - returndatacopy(m, 0x00, returndatasize()) - result := mload(add(m, mod(and(y, 0xffff), add(returndatasize(), 0x20)))) - } - return result; - } - if (t == 8) { - /// @solidity memory-safe-assembly - assembly { - result := sload(and(y, 0xff)) - } - return result; - } - if (t == 9) { - /// @solidity memory-safe-assembly - assembly { - result := mload(mod(y, add(mload(0x40), 0x40))) - } - return result; - } - result = __getSigner(_randomPrivateKey()); - } - - /// @dev Returns a pseudorandom hashed address. - /// The result may have dirty upper 96 bits. - /// This function will not return an existing contract. - /// This function will not return a precompile address. - /// This function will not return a zero address. - /// This function may return a previously returned result. - function _randomHashedAddress() internal returns (address result) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - mstore(0x1f, and(sub(7, shr(252, r)), r)) - calldatacopy(0x00, 0x00, 0x24) - result := keccak256(0x00, 0x3f) - } - } - - /// @dev Returns a pseudorandom address. - function _randomUniqueHashedAddress(uint256 groupId) internal returns (address result) { - result = _randomUniqueHashedAddress(bytes32(groupId)); - } - - /// @dev Returns a pseudorandom address. - function _randomUniqueHashedAddress(bytes32 groupId) internal returns (address result) { - do { - result = _randomHashedAddress(); - } while (__markAsGenerated("address", groupId, uint160(result))); - } - - /// @dev Returns a pseudorandom address. - function _randomUniqueHashedAddress() internal returns (address result) { - result = _randomUniqueHashedAddress(""); - } - - /// @dev Private helper function for returning random bytes. - function __randomBytes(bool zeroRightPad) private returns (bytes memory result) { - uint256 r = _randomUniform(); - /// @solidity memory-safe-assembly - assembly { - let n := and(r, 0x1ffff) - let t := shr(24, r) - for {} 1 {} { - // With a 1/256 chance, just return the zero pointer as the result. - if iszero(and(t, 0xff0)) { - result := 0x60 - break - } - result := mload(0x40) - // With a 15/16 chance, set the length to be - // exponentially distributed in the range [0,255] (inclusive). - if shr(252, r) { n := shr(and(t, 0x7), byte(5, r)) } - // Store some fixed word at the start of the string. - // We want this function to sometimes return duplicates. - mstore(add(result, 0x20), xor(calldataload(0x00), _TESTPLUS_RANDOMNESS_SLOT)) - // With a 1/2 chance, copy the contract code to the start and end. - if iszero(and(t, 0x1000)) { - // Copy to the start. - if iszero(and(t, 0x2000)) { codecopy(result, byte(1, r), codesize()) } - // Copy to the end. - codecopy(add(result, n), byte(2, r), 0x40) - } - // With a 1/16 chance, randomize the start and end. - if iszero(and(t, 0xf0000)) { - let y := mulmod(r, _LPRNG_MULTIPLIER, _LPRNG_MODULO) - mstore(add(result, 0x20), y) - mstore(add(result, n), xor(r, y)) - } - // With a 1/256 chance, make the result entirely zero bytes. - if iszero(byte(4, r)) { codecopy(result, codesize(), add(n, 0x20)) } - // Skip the zero-right-padding if not required. - if iszero(zeroRightPad) { - mstore(0x40, add(n, add(0x40, result))) // Allocate memory. - mstore(result, n) // Store the length. - break - } - mstore(add(add(result, 0x20), n), 0) // Zeroize the word after the result. - mstore(0x40, add(n, add(0x60, result))) // Allocate memory. - mstore(result, n) // Store the length. - break - } - } - } - - /// @dev Returns a random bytes string from 0 to 131071 bytes long. - /// This random bytes string may NOT be zero-right-padded. - /// This is intentional for memory robustness testing. - /// This function may return a previously returned result. - function _randomBytes() internal returns (bytes memory result) { - result = __randomBytes(false); - } - - /// @dev Returns a random bytes string from 0 to 131071 bytes long. - /// This function may return a previously returned result. - function _randomBytesZeroRightPadded() internal returns (bytes memory result) { - result = __randomBytes(true); - } - - /// @dev Truncate the bytes to `n` bytes. - /// Returns the result for function chaining. - function _truncateBytes(bytes memory b, uint256 n) - internal - pure - returns (bytes memory result) - { - /// @solidity memory-safe-assembly - assembly { - if gt(mload(b), n) { mstore(b, n) } - result := b - } - } - - /// @dev Wraps a functions such that allocated memory will be freed at the end of its scope. - modifier tempMemory() { - uint256 m = _freeMemoryPointer(); - _; - _setFreeMemoryPointer(m); - } - - /// @dev Returns the free memory pointer. - function _freeMemoryPointer() internal pure returns (uint256 result) { - /// @solidity memory-safe-assembly - assembly { - result := mload(0x40) - } - } - - /// @dev Sets the free memory pointer. - function _setFreeMemoryPointer(uint256 m) internal pure { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, m) - } - } - - /// @dev Increments the free memory pointer by a world. - function _incrementFreeMemoryPointer() internal pure { - uint256 word = 0x20; - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, add(mload(0x40), word)) - } - } - - /// @dev Adapted from `bound`: - /// https://github.com/foundry-rs/forge-std/blob/ff4bf7db008d096ea5a657f2c20516182252a3ed/src/StdUtils.sol#L10 - /// Differentially fuzzed tested against the original implementation. - function _hem(uint256 x, uint256 min, uint256 max) - internal - pure - virtual - returns (uint256 result) - { - require(min <= max, "Max is less than min."); - /// @solidity memory-safe-assembly - assembly { - // prettier-ignore - for {} 1 {} { - // If `x` is between `min` and `max`, return `x` directly. - // This is to ensure that dictionary values - // do not get shifted if the min is nonzero. - // More info: https://github.com/foundry-rs/forge-std/issues/188 - if iszero(or(lt(x, min), gt(x, max))) { - result := x - break - } - let size := add(sub(max, min), 1) - if lt(gt(x, 3), gt(size, x)) { - result := add(min, x) - break - } - if lt(lt(x, not(3)), gt(size, not(x))) { - result := sub(max, not(x)) - break - } - // Otherwise, wrap x into the range [min, max], - // i.e. the range is inclusive. - if iszero(lt(x, max)) { - let d := sub(x, max) - let r := mod(d, size) - if iszero(r) { - result := max - break - } - result := sub(add(min, r), 1) - break - } - let d := sub(min, x) - let r := mod(d, size) - if iszero(r) { - result := min - break - } - result := add(sub(max, r), 1) - break - } - } - } - - /// @dev Etches bytecode onto the target. - function __etch(address target, bytes memory bytecode) private { - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - mstore(m, 0xb4d6c782) // `etch(address,bytes)`. - mstore(add(m, 0x20), target) - mstore(add(m, 0x40), 0x40) - let n := mload(bytecode) - mstore(add(m, 0x60), n) - // prettier-ignore - for { let i := 0 } lt(i, n) { i := add(0x20, i) } { - mstore(add(add(m, 0x80), i), mload(add(add(bytecode, 0x20), i))) - } - pop(call(gas(), _VM_ADDRESS, 0, add(m, 0x1c), add(n, 0x64), 0x00, 0x00)) - } - } - - /// @dev Returns if the `target` has code. - function __hasCode(address target) private view returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := iszero(iszero(extcodesize(target))) - } - } - - /// @dev Deploys a contract via Nick's factory for testing. - function _nicksCreate2(uint256 payableAmount, bytes32 salt, bytes memory initializationCode) - internal - returns (address deploymentAddress) - { - address f = _NICKS_FACTORY; - if (!__hasCode(f)) __etch(f, _NICKS_FACTORY_BYTECODE); - /// @solidity memory-safe-assembly - assembly { - let n := mload(initializationCode) - mstore(initializationCode, salt) - if iszero(call(gas(), f, payableAmount, initializationCode, add(n, 0x20), 0x00, 0x20)) { - returndatacopy(initializationCode, 0x00, returndatasize()) - revert(initializationCode, returndatasize()) - } - mstore(initializationCode, n) // Restore the length. - deploymentAddress := shr(96, mload(0x00)) - } - } - - /// @dev Deploys a contract via 0age's immutable create 2 factory for testing. - function _safeCreate2(uint256 payableAmount, bytes32 salt, bytes memory initializationCode) - internal - returns (address deploymentAddress) - { - address f = _IMMUTABLE_CREATE2_FACTORY; - if (!__hasCode(f)) __etch(f, _IMMUTABLE_CREATE2_FACTORY_BYTECODE); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) - let n := mload(initializationCode) - mstore(m, 0x64e03087) // `safeCreate2(bytes32,bytes)`. - mstore(add(m, 0x20), salt) - mstore(add(m, 0x40), 0x40) - mstore(add(m, 0x60), n) - // prettier-ignore - for { let i := 0 } lt(i, n) { i := add(i, 0x20) } { - mstore(add(add(m, 0x80), i), mload(add(add(initializationCode, 0x20), i))) - } - if iszero(call(gas(), f, payableAmount, add(m, 0x1c), add(n, 0x64), m, 0x20)) { - returndatacopy(m, 0x00, returndatasize()) - revert(m, returndatasize()) - } - deploymentAddress := mload(m) - } - } - - /// @dev Deploys a contract via 0age's immutable create 2 factory for testing. - function _safeCreate2(bytes32 salt, bytes memory initializationCode) - internal - returns (address deploymentAddress) - { - deploymentAddress = _safeCreate2(0, salt, initializationCode); - } - - /// @dev This function will make forge's gas output display the approximate codesize of - /// the test contract as the amount of gas burnt. Useful for quick guess checking if - /// certain optimizations actually compiles to similar bytecode. - function test__codesize() external view { - /// @solidity memory-safe-assembly - assembly { - // If the caller is the contract itself (i.e. recursive call), burn all the gas. - if eq(caller(), address()) { invalid() } - mstore(0x00, 0xf09ff470) // Store the function selector of `test__codesize()`. - pop(staticcall(codesize(), address(), 0x1c, 0x04, 0x00, 0x00)) - } - } -} diff --git a/grouperBot/lib/solady/test/utils/forge-std/Script.sol b/grouperBot/lib/solady/test/utils/forge-std/Script.sol deleted file mode 100644 index 2be2bbd..0000000 --- a/grouperBot/lib/solady/test/utils/forge-std/Script.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -import "./Vm.sol"; - -abstract contract Script { - bool public IS_SCRIPT = true; - - /// @dev `address(bytes20(uint160(uint256(keccak256("hevm cheat code")))))`. - Vm public constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); -} diff --git a/grouperBot/lib/solady/test/utils/forge-std/Test.sol b/grouperBot/lib/solady/test/utils/forge-std/Test.sol deleted file mode 100644 index fa4c6e4..0000000 --- a/grouperBot/lib/solady/test/utils/forge-std/Test.sol +++ /dev/null @@ -1,792 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -import "./Script.sol"; - -abstract contract Test is Script { - bool private __failed; - - function failed() public view returns (bool) { - if (__failed) { - return __failed; - } else { - return vm.load(address(vm), bytes32("failed")) != bytes32(0); - } - } - - function fail() internal virtual { - vm.store(address(vm), bytes32("failed"), bytes32(uint256(1))); - __failed = true; - } - - // We intentionally do NOT mark these functions as pure, - // so that importing this file into codebases built with old forge-std - // won't trigger the compiler warning 2018. - // - // For performance, wherever possible, we do Solidity comparisons and - // only make vm call if we know know the assert fails, - // as preparing calls definitely costs more compute than doing - // just the Solidity comparisons. - - function assertTrue(bool data) internal virtual { - if (!data) vm.assertTrue(data); - } - - function assertTrue(bool data, string memory err) internal virtual { - if (!data) vm.assertTrue(data, err); - } - - function assertFalse(bool data) internal virtual { - if (data) vm.assertFalse(data); - } - - function assertFalse(bool data, string memory err) internal virtual { - if (data) vm.assertFalse(data, err); - } - - function assertEq(bool left, bool right) internal virtual { - if (left != right) vm.assertEq(left, right); - } - - function assertEq(bool left, bool right, string memory err) internal virtual { - if (left != right) vm.assertEq(left, right, err); - } - - function assertEq(uint256 left, uint256 right) internal virtual { - if (left != right) vm.assertEq(left, right); - } - - function assertEq(uint256 left, uint256 right, string memory err) internal virtual { - if (left != right) vm.assertEq(left, right, err); - } - - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal virtual { - if (left != right) vm.assertEqDecimal(left, right, decimals); - } - - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left != right) vm.assertEqDecimal(left, right, decimals, err); - } - - function assertEq(int256 left, int256 right) internal virtual { - if (left != right) vm.assertEq(left, right); - } - - function assertEq(int256 left, int256 right, string memory err) internal virtual { - if (left != right) vm.assertEq(left, right, err); - } - - function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal virtual { - if (left != right) vm.assertEqDecimal(left, right, decimals); - } - - function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left != right) vm.assertEqDecimal(left, right, decimals, err); - } - - function assertEq(address left, address right) internal virtual { - if (left != right) vm.assertEq(left, right); - } - - function assertEq(address left, address right, string memory err) internal virtual { - if (left != right) vm.assertEq(left, right, err); - } - - function assertEq(bytes32 left, bytes32 right) internal virtual { - if (left != right) vm.assertEq(left, right); - } - - function assertEq(bytes32 left, bytes32 right, string memory err) internal virtual { - if (left != right) vm.assertEq(left, right, err); - } - - function assertEq(string memory left, string memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(string memory left, string memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(bytes memory left, bytes memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(bytes memory left, bytes memory right, string memory err) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(bool[] memory left, bool[] memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(bool[] memory left, bool[] memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(uint256[] memory left, uint256[] memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(uint256[] memory left, uint256[] memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(int256[] memory left, int256[] memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(int256[] memory left, int256[] memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(address[] memory left, address[] memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(address[] memory left, address[] memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(bytes32[] memory left, bytes32[] memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(bytes32[] memory left, bytes32[] memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(string[] memory left, string[] memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(string[] memory left, string[] memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertEq(bytes[] memory left, bytes[] memory right) internal virtual { - if (!__eq(left, right)) vm.assertEq(left, right); - } - - function assertEq(bytes[] memory left, bytes[] memory right, string memory err) - internal - virtual - { - if (!__eq(left, right)) vm.assertEq(left, right, err); - } - - function assertNotEq(bool left, bool right) internal virtual { - if (left == right) vm.assertNotEq(left, right); - } - - function assertNotEq(bool left, bool right, string memory err) internal virtual { - if (left == right) vm.assertNotEq(left, right, err); - } - - function assertNotEq(uint256 left, uint256 right) internal virtual { - if (left == right) vm.assertNotEq(left, right); - } - - function assertNotEq(uint256 left, uint256 right, string memory err) internal virtual { - if (left == right) vm.assertNotEq(left, right, err); - } - - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) internal virtual { - if (left == right) vm.assertNotEqDecimal(left, right, decimals); - } - - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left == right) vm.assertNotEqDecimal(left, right, decimals, err); - } - - function assertNotEq(int256 left, int256 right) internal virtual { - if (left == right) vm.assertNotEq(left, right); - } - - function assertNotEq(int256 left, int256 right, string memory err) internal virtual { - if (left == right) vm.assertNotEq(left, right, err); - } - - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) internal virtual { - if (left == right) vm.assertNotEqDecimal(left, right, decimals); - } - - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left == right) vm.assertNotEqDecimal(left, right, decimals, err); - } - - function assertNotEq(address left, address right) internal virtual { - if (left == right) vm.assertNotEq(left, right); - } - - function assertNotEq(address left, address right, string memory err) internal virtual { - if (left == right) vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes32 left, bytes32 right) internal virtual { - if (left == right) vm.assertNotEq(left, right); - } - - function assertNotEq(bytes32 left, bytes32 right, string memory err) internal virtual { - if (left == right) vm.assertNotEq(left, right, err); - } - - function assertNotEq(string memory left, string memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(string memory left, string memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes memory left, bytes memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(bytes memory left, bytes memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(bool[] memory left, bool[] memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(bool[] memory left, bool[] memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(uint256[] memory left, uint256[] memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(uint256[] memory left, uint256[] memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(int256[] memory left, int256[] memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(int256[] memory left, int256[] memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(address[] memory left, address[] memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(address[] memory left, address[] memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes32[] memory left, bytes32[] memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(bytes32[] memory left, bytes32[] memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(string[] memory left, string[] memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(string[] memory left, string[] memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertNotEq(bytes[] memory left, bytes[] memory right) internal virtual { - if (__eq(left, right)) vm.assertNotEq(left, right); - } - - function assertNotEq(bytes[] memory left, bytes[] memory right, string memory err) - internal - virtual - { - if (__eq(left, right)) vm.assertNotEq(left, right, err); - } - - function assertLt(uint256 left, uint256 right) internal virtual { - if (left >= right) vm.assertLt(left, right); - } - - function assertLt(uint256 left, uint256 right, string memory err) internal virtual { - if (left >= right) vm.assertLt(left, right, err); - } - - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) internal virtual { - if (left >= right) vm.assertLtDecimal(left, right, decimals); - } - - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left >= right) vm.assertLtDecimal(left, right, decimals, err); - } - - function assertLt(int256 left, int256 right) internal virtual { - if (left >= right) vm.assertLt(left, right); - } - - function assertLt(int256 left, int256 right, string memory err) internal virtual { - if (left >= right) vm.assertLt(left, right, err); - } - - function assertLtDecimal(int256 left, int256 right, uint256 decimals) internal virtual { - if (left >= right) vm.assertLtDecimal(left, right, decimals); - } - - function assertLtDecimal(int256 left, int256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left >= right) vm.assertLtDecimal(left, right, decimals, err); - } - - function assertGt(uint256 left, uint256 right) internal virtual { - if (left <= right) vm.assertGt(left, right); - } - - function assertGt(uint256 left, uint256 right, string memory err) internal virtual { - if (left <= right) vm.assertGt(left, right, err); - } - - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) internal virtual { - if (left <= right) vm.assertGtDecimal(left, right, decimals); - } - - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left <= right) vm.assertGtDecimal(left, right, decimals, err); - } - - function assertGt(int256 left, int256 right) internal virtual { - if (left <= right) vm.assertGt(left, right); - } - - function assertGt(int256 left, int256 right, string memory err) internal virtual { - if (left <= right) vm.assertGt(left, right, err); - } - - function assertGtDecimal(int256 left, int256 right, uint256 decimals) internal virtual { - if (left <= right) vm.assertGtDecimal(left, right, decimals); - } - - function assertGtDecimal(int256 left, int256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left <= right) vm.assertGtDecimal(left, right, decimals, err); - } - - function assertLe(uint256 left, uint256 right) internal virtual { - if (left > right) vm.assertLe(left, right); - } - - function assertLe(uint256 left, uint256 right, string memory err) internal virtual { - if (left > right) vm.assertLe(left, right, err); - } - - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) internal virtual { - if (left > right) vm.assertLeDecimal(left, right, decimals); - } - - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left > right) vm.assertLeDecimal(left, right, decimals, err); - } - - function assertLe(int256 left, int256 right) internal virtual { - if (left > right) vm.assertLe(left, right); - } - - function assertLe(int256 left, int256 right, string memory err) internal virtual { - if (left > right) vm.assertLe(left, right, err); - } - - function assertLeDecimal(int256 left, int256 right, uint256 decimals) internal virtual { - if (left > right) vm.assertLeDecimal(left, right, decimals); - } - - function assertLeDecimal(int256 left, int256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left > right) vm.assertLeDecimal(left, right, decimals, err); - } - - function assertGe(uint256 left, uint256 right) internal virtual { - if (left < right) vm.assertGe(left, right); - } - - function assertGe(uint256 left, uint256 right, string memory err) internal virtual { - if (left < right) vm.assertGe(left, right, err); - } - - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) internal virtual { - if (left < right) vm.assertGeDecimal(left, right, decimals); - } - - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left < right) vm.assertGeDecimal(left, right, decimals, err); - } - - function assertGe(int256 left, int256 right) internal virtual { - if (left < right) vm.assertGe(left, right); - } - - function assertGe(int256 left, int256 right, string memory err) internal virtual { - if (left < right) vm.assertGe(left, right, err); - } - - function assertGeDecimal(int256 left, int256 right, uint256 decimals) internal virtual { - if (left < right) vm.assertGeDecimal(left, right, decimals); - } - - function assertGeDecimal(int256 left, int256 right, uint256 decimals, string memory err) - internal - virtual - { - if (left < right) vm.assertGeDecimal(left, right, decimals, err); - } - - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) internal virtual { - vm.assertApproxEqAbs(left, right, maxDelta); - } - - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string memory err) - internal - virtual - { - vm.assertApproxEqAbs(left, right, maxDelta, err); - } - - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals - ) internal virtual { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); - } - - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals, - string memory err - ) internal virtual { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); - } - - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) internal virtual { - vm.assertApproxEqAbs(left, right, maxDelta); - } - - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string memory err) - internal - virtual - { - vm.assertApproxEqAbs(left, right, maxDelta, err); - } - - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) - internal - virtual - { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); - } - - function assertApproxEqAbsDecimal( - int256 left, - int256 right, - uint256 maxDelta, - uint256 decimals, - string memory err - ) internal virtual { - vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); - } - - function assertApproxEqRel( - uint256 left, - uint256 right, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta); - } - - function assertApproxEqRel( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta, err); - } - - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); - } - - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); - } - - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) - internal - virtual - { - vm.assertApproxEqRel(left, right, maxPercentDelta); - } - - function assertApproxEqRel( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal virtual { - vm.assertApproxEqRel(left, right, maxPercentDelta, err); - } - - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); - } - - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal virtual { - vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); - } - - function __eq(bool[] memory left, bool[] memory right) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(left) - if eq(n, mload(right)) { - returndatacopy(returndatasize(), returndatasize(), shr(128, n)) - result := 1 - let d := sub(right, left) - for { n := add(left, shl(5, n)) } iszero(eq(left, n)) {} { - left := add(left, 0x20) - result := and(result, eq(iszero(mload(left)), iszero(mload(add(left, d))))) - } - } - } - } - - function __eq(address[] memory left, address[] memory right) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(left) - if eq(n, mload(right)) { - returndatacopy(returndatasize(), returndatasize(), shr(128, n)) - result := 1 - let d := sub(right, left) - for { n := add(left, shl(5, n)) } iszero(eq(left, n)) {} { - left := add(left, 0x20) - result := and(result, eq(shl(96, mload(left)), shl(96, mload(add(left, d))))) - } - } - } - } - - function __eq(bytes32[] memory left, bytes32[] memory right) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(left, shl(5, add(1, mload(left)))) - result := eq(keccak256(right, shl(5, add(1, mload(right)))), result) - } - } - - function __eq(int256[] memory left, int256[] memory right) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(left, shl(5, add(1, mload(left)))) - result := eq(keccak256(right, shl(5, add(1, mload(right)))), result) - } - } - - function __eq(uint256[] memory left, uint256[] memory right) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(left, shl(5, add(1, mload(left)))) - result := eq(keccak256(right, shl(5, add(1, mload(right)))), result) - } - } - - function __eq(string[] memory left, string[] memory right) - internal - pure - returns (bool result) - { - /// @solidity memory-safe-assembly - assembly { - let n := mload(left) - if eq(n, mload(right)) { - returndatacopy(returndatasize(), returndatasize(), shr(128, n)) - result := 1 - let d := sub(right, left) - for { n := add(left, shl(5, n)) } iszero(eq(left, n)) {} { - left := add(left, 0x20) - let l := mload(left) - l := keccak256(l, add(0x20, mload(l))) - let r := mload(add(left, d)) - r := keccak256(r, add(0x20, mload(r))) - result := and(result, eq(l, r)) - } - } - } - } - - function __eq(bytes[] memory left, bytes[] memory right) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - let n := mload(left) - if eq(n, mload(right)) { - returndatacopy(returndatasize(), returndatasize(), shr(128, n)) - result := 1 - let d := sub(right, left) - for { n := add(left, shl(5, n)) } iszero(eq(left, n)) {} { - left := add(left, 0x20) - let l := mload(left) - l := keccak256(l, add(0x20, mload(l))) - let r := mload(add(left, d)) - r := keccak256(r, add(0x20, mload(r))) - result := and(result, eq(l, r)) - } - } - } - } - - function __eq(string memory left, string memory right) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(left, add(0x20, mload(left))) - result := eq(keccak256(right, add(0x20, mload(right))), result) - } - } - - function __eq(bytes memory left, bytes memory right) internal pure returns (bool result) { - /// @solidity memory-safe-assembly - assembly { - result := keccak256(left, add(0x20, mload(left))) - result := eq(keccak256(right, add(0x20, mload(right))), result) - } - } -} - -library stdError { - bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); - bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); - bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); - bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); - bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); - bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); - bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); - bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); - bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); - // DEPRECATED: Use Vm's `expectRevert` without any arguments instead - bytes public constant lowLevelError = bytes(""); // `0x` -} diff --git a/grouperBot/lib/solady/test/utils/forge-std/Vm.sol b/grouperBot/lib/solady/test/utils/forge-std/Vm.sol deleted file mode 100644 index dc644b9..0000000 --- a/grouperBot/lib/solady/test/utils/forge-std/Vm.sol +++ /dev/null @@ -1,1994 +0,0 @@ -// Automatically @generated by scripts/vm.py. Do not modify manually. - -// SPDX-License-Identifier: MIT OR Apache-2.0 -pragma solidity >=0.6.2 <0.9.0; -pragma experimental ABIEncoderV2; - -/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may -/// result in Script simulations differing from on-chain execution. It is recommended to only use -/// these cheats in scripts. -interface VmSafe { - /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. - enum CallerMode { - // No caller modification is currently active. - None, - // A one time broadcast triggered by a `vm.broadcast()` call is currently active. - Broadcast, - // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active. - RecurrentBroadcast, - // A one time prank triggered by a `vm.prank()` call is currently active. - Prank, - // A recurrent prank triggered by a `vm.startPrank()` call is currently active. - RecurrentPrank - } - - /// The kind of account access that occurred. - enum AccountAccessKind { - // The account was called. - Call, - // The account was called via delegatecall. - DelegateCall, - // The account was called via callcode. - CallCode, - // The account was called via staticcall. - StaticCall, - // The account was created. - Create, - // The account was selfdestructed. - SelfDestruct, - // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess). - Resume, - // The account's balance was read. - Balance, - // The account's codesize was read. - Extcodesize, - // The account's codehash was read. - Extcodehash, - // The account's code was copied. - Extcodecopy - } - - /// An Ethereum log. Returned by `getRecordedLogs`. - struct Log { - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The address of the log's emitter. - address emitter; - } - - /// An RPC URL and its alias. Returned by `rpcUrlStructs`. - struct Rpc { - // The alias of the RPC URL. - string key; - // The RPC URL. - string url; - } - - /// An RPC log object. Returned by `eth_getLogs`. - struct EthGetLogs { - // The address of the log's emitter. - address emitter; - // The topics of the log, including the signature, if any. - bytes32[] topics; - // The raw data of the log. - bytes data; - // The block hash. - bytes32 blockHash; - // The block number. - uint64 blockNumber; - // The transaction hash. - bytes32 transactionHash; - // The transaction index in the block. - uint64 transactionIndex; - // The log index. - uint256 logIndex; - // Whether the log was removed. - bool removed; - } - - /// A single entry in a directory listing. Returned by `readDir`. - struct DirEntry { - // The error message, if any. - string errorMessage; - // The path of the entry. - string path; - // The depth of the entry. - uint64 depth; - // Whether the entry is a directory. - bool isDir; - // Whether the entry is a symlink. - bool isSymlink; - } - - /// Metadata information about a file. - /// This structure is returned from the `fsMetadata` function and represents known - /// metadata about a file such as its permissions, size, modification - /// times, etc. - struct FsMetadata { - // True if this metadata is for a directory. - bool isDir; - // True if this metadata is for a symlink. - bool isSymlink; - // The size of the file, in bytes, this metadata is for. - uint256 length; - // True if this metadata is for a readonly (unwritable) file. - bool readOnly; - // The last modification time listed in this metadata. - uint256 modified; - // The last access time of this metadata. - uint256 accessed; - // The creation time listed in this metadata. - uint256 created; - } - - /// A wallet with a public and private key. - struct Wallet { - // The wallet's address. - address addr; - // The wallet's public key `X`. - uint256 publicKeyX; - // The wallet's public key `Y`. - uint256 publicKeyY; - // The wallet's private key. - uint256 privateKey; - } - - /// The result of a `tryFfi` call. - struct FfiResult { - // The exit code of the call. - int32 exitCode; - // The optionally hex-decoded `stdout` data. - bytes stdout; - // The `stderr` data. - bytes stderr; - } - - /// Information on the chain and fork. - struct ChainInfo { - // The fork identifier. Set to zero if no fork is active. - uint256 forkId; - // The chain ID of the current fork. - uint256 chainId; - } - - /// The result of a `stopAndReturnStateDiff` call. - struct AccountAccess { - // The chain and fork the access occurred. - ChainInfo chainInfo; - // The kind of account access that determines what the account is. - // If kind is Call, DelegateCall, StaticCall or CallCode, then the account is the callee. - // If kind is Create, then the account is the newly created account. - // If kind is SelfDestruct, then the account is the selfdestruct recipient. - // If kind is a Resume, then account represents a account context that has resumed. - AccountAccessKind kind; - // The account that was accessed. - // It's either the account created, callee or a selfdestruct recipient for CREATE, CALL or SELFDESTRUCT. - address account; - // What accessed the account. - address accessor; - // If the account was initialized or empty prior to the access. - // An account is considered initialized if it has code, a - // non-zero nonce, or a non-zero balance. - bool initialized; - // The previous balance of the accessed account. - uint256 oldBalance; - // The potential new balance of the accessed account. - // That is, all balance changes are recorded here, even if reverts occurred. - uint256 newBalance; - // Code of the account deployed by CREATE. - bytes deployedCode; - // Value passed along with the account access - uint256 value; - // Input data provided to the CREATE or CALL - bytes data; - // If this access reverted in either the current or parent context. - bool reverted; - // An ordered list of storage accesses made during an account access operation. - StorageAccess[] storageAccesses; - // Call depth traversed during the recording of state differences - uint64 depth; - } - - /// The storage accessed during an `AccountAccess`. - struct StorageAccess { - // The account whose storage was accessed. - address account; - // The slot that was accessed. - bytes32 slot; - // If the access was a write. - bool isWrite; - // The previous value of the slot. - bytes32 previousValue; - // The new value of the slot. - bytes32 newValue; - // If the access was reverted. - bool reverted; - } - - // ::::::: Environment ::::::: - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name) external view returns (address value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envAddress(string calldata name, string calldata delim) - external - view - returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBool(string calldata name, string calldata delim) - external - view - returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name) external view returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes32(string calldata name, string calldata delim) - external - view - returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name) external view returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envBytes(string calldata name, string calldata delim) - external - view - returns (bytes[] memory value); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name) external view returns (int256 value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envInt(string calldata name, string calldata delim) - external - view - returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `bool`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bool defaultValue) external view returns (bool value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, uint256 defaultValue) - external - view - returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) - external - view - returns (address[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) - external - view - returns (bytes32[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) - external - view - returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) - external - view - returns (bytes[] memory value); - - /// Gets the environment variable `name` and parses it as `int256`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, int256 defaultValue) - external - view - returns (int256 value); - - /// Gets the environment variable `name` and parses it as `address`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, address defaultValue) - external - view - returns (address value); - - /// Gets the environment variable `name` and parses it as `bytes32`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes32 defaultValue) - external - view - returns (bytes32 value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata defaultValue) - external - view - returns (string memory value); - - /// Gets the environment variable `name` and parses it as `bytes`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, bytes calldata defaultValue) - external - view - returns (bytes memory value); - - /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) - external - view - returns (bool[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) - external - view - returns (uint256[] memory value); - - /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. - /// Reverts if the variable could not be parsed. - /// Returns `defaultValue` if the variable was not found. - function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) - external - view - returns (int256[] memory value); - - /// Gets the environment variable `name` and parses it as `string`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name) external view returns (string memory value); - - /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envString(string calldata name, string calldata delim) - external - view - returns (string[] memory value); - - /// Gets the environment variable `name` and parses it as `uint256`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name) external view returns (uint256 value); - - /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. - /// Reverts if the variable was not found or could not be parsed. - function envUint(string calldata name, string calldata delim) - external - view - returns (uint256[] memory value); - - /// Sets environment variables. - function setEnv(string calldata name, string calldata value) external; - - // ::::::: EVM ::::::: - - /// Gets all accessed reads and write slot from a `vm.record` session, for a given address. - function accesses(address target) - external - returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); - - /// Gets the address for a given private key. - function addr(uint256 privateKey) external pure returns (address keyAddr); - - /// Gets all the logs according to specified filter. - function eth_getLogs( - uint256 fromBlock, - uint256 toBlock, - address target, - bytes32[] calldata topics - ) external returns (EthGetLogs[] memory logs); - - /// Gets the current `block.number`. - /// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockNumber() external view returns (uint256 height); - - /// Gets the current `block.timestamp`. - /// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction, - /// and as a result will get optimized out by the compiler. - /// See https://github.com/foundry-rs/foundry/issues/6180 - function getBlockTimestamp() external view returns (uint256 timestamp); - - /// Gets the map key and parent of a mapping at a given slot, for a given address. - function getMappingKeyAndParentOf(address target, bytes32 elementSlot) - external - returns (bool found, bytes32 key, bytes32 parent); - - /// Gets the number of elements in the mapping at the given slot, for a given address. - function getMappingLength(address target, bytes32 mappingSlot) - external - returns (uint256 length); - - /// Gets the elements at index idx of the mapping at the given slot, for a given address. The - /// index must be less than the length of the mapping (i.e. the number of keys in the mapping). - function getMappingSlotAt(address target, bytes32 mappingSlot, uint256 idx) - external - returns (bytes32 value); - - /// Gets the nonce of an account. - function getNonce(address account) external view returns (uint64 nonce); - - /// Gets all the recorded logs. - function getRecordedLogs() external returns (Log[] memory logs); - - /// Loads a storage slot from an address. - function load(address target, bytes32 slot) external view returns (bytes32 data); - - /// Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. - function pauseGasMetering() external; - - /// Records all storage reads and writes. - function record() external; - - /// Record all the transaction logs. - function recordLogs() external; - - /// Resumes gas metering (i.e. gas usage is counted again). Noop if already on. - function resumeGasMetering() external; - - /// Performs an Ethereum JSON-RPC request to the current fork URL. - function rpc(string calldata method, string calldata params) - external - returns (bytes memory data); - - /// Signs `digest` with `privateKey` using the secp256r1 curve. - function signP256(uint256 privateKey, bytes32 digest) - external - pure - returns (bytes32 r, bytes32 s); - - /// Signs `digest` with `privateKey` using the secp256k1 curve. - function sign(uint256 privateKey, bytes32 digest) - external - pure - returns (uint8 v, bytes32 r, bytes32 s); - - /// Starts recording all map SSTOREs for later retrieval. - function startMappingRecording() external; - - /// Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order, - /// along with the context of the calls - function startStateDiffRecording() external; - - /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. - function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); - - /// Stops recording all map SSTOREs for later retrieval and clears the recorded data. - function stopMappingRecording() external; - - // ::::::: Filesystem ::::::: - - /// Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. - /// `path` is relative to the project root. - function closeFile(string calldata path) external; - - /// Copies the contents of one file to another. This function will **overwrite** the contents of `to`. - /// On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`. - /// Both `from` and `to` are relative to the project root. - function copyFile(string calldata from, string calldata to) external returns (uint64 copied); - - /// Creates a new, empty directory at the provided path. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - User lacks permissions to modify `path`. - /// - A parent of the given path doesn't exist and `recursive` is false. - /// - `path` already exists and `recursive` is false. - /// `path` is relative to the project root. - function createDir(string calldata path, bool recursive) external; - - /// Returns true if the given path points to an existing entity, else returns false. - function exists(string calldata path) external returns (bool result); - - /// Performs a foreign function call via the terminal. - function ffi(string[] calldata commandInput) external returns (bytes memory result); - - /// Given a path, query the file system to get information about a file, directory, etc. - function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); - - /// Gets the creation bytecode from an artifact file. Takes in the relative path to the json file. - function getCode(string calldata artifactPath) - external - view - returns (bytes memory creationBytecode); - - /// Gets the deployed bytecode from an artifact file. Takes in the relative path to the json file. - function getDeployedCode(string calldata artifactPath) - external - view - returns (bytes memory runtimeBytecode); - - /// Returns true if the path exists on disk and is pointing at a directory, else returns false. - function isDir(string calldata path) external returns (bool result); - - /// Returns true if the path exists on disk and is pointing at a regular file, else returns false. - function isFile(string calldata path) external returns (bool result); - - /// Get the path of the current project root. - function projectRoot() external view returns (string memory path); - - /// Prompts the user for a string value in the terminal. - function prompt(string calldata promptText) external returns (string memory input); - - /// Prompts the user for a hidden string value in the terminal. - function promptSecret(string calldata promptText) external returns (string memory input); - - /// Reads the directory at the given path recursively, up to `maxDepth`. - /// `maxDepth` defaults to 1, meaning only the direct children of the given directory will be returned. - /// Follows symbolic links if `followLinks` is true. - function readDir(string calldata path) external view returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth) - external - view - returns (DirEntry[] memory entries); - - /// See `readDir(string)`. - function readDir(string calldata path, uint64 maxDepth, bool followLinks) - external - view - returns (DirEntry[] memory entries); - - /// Reads the entire content of file to string. `path` is relative to the project root. - function readFile(string calldata path) external view returns (string memory data); - - /// Reads the entire content of file as binary. `path` is relative to the project root. - function readFileBinary(string calldata path) external view returns (bytes memory data); - - /// Reads next line of file to string. - function readLine(string calldata path) external view returns (string memory line); - - /// Reads a symbolic link, returning the path that the link points to. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - `path` is not a symbolic link. - /// - `path` does not exist. - function readLink(string calldata linkPath) external view returns (string memory targetPath); - - /// Removes a directory at the provided path. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - `path` doesn't exist. - /// - `path` isn't a directory. - /// - User lacks permissions to modify `path`. - /// - The directory is not empty and `recursive` is false. - /// `path` is relative to the project root. - function removeDir(string calldata path, bool recursive) external; - - /// Removes a file from the filesystem. - /// This cheatcode will revert in the following situations, but is not limited to just these cases: - /// - `path` points to a directory. - /// - The file doesn't exist. - /// - The user lacks permissions to remove the file. - /// `path` is relative to the project root. - function removeFile(string calldata path) external; - - /// Performs a foreign function call via terminal and returns the exit code, stdout, and stderr. - function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result); - - /// Returns the time since unix epoch in milliseconds. - function unixTime() external returns (uint256 milliseconds); - - /// Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. - /// `path` is relative to the project root. - function writeFile(string calldata path, string calldata data) external; - - /// Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. - /// `path` is relative to the project root. - function writeFileBinary(string calldata path, bytes calldata data) external; - - /// Writes line to file, creating a file if it does not exist. - /// `path` is relative to the project root. - function writeLine(string calldata path, string calldata data) external; - - // ::::::: JSON ::::::: - - /// Checks if `key` exists in a JSON object - /// `keyExists` is being deprecated in favor of `keyExistsJson`. It will be removed in future versions. - function keyExists(string calldata json, string calldata key) external view returns (bool); - - /// Checks if `key` exists in a JSON object. - function keyExistsJson(string calldata json, string calldata key) - external - view - returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `address`. - function parseJsonAddress(string calldata json, string calldata key) - external - pure - returns (address); - - /// Parses a string of JSON data at `key` and coerces it to `address[]`. - function parseJsonAddressArray(string calldata json, string calldata key) - external - pure - returns (address[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bool`. - function parseJsonBool(string calldata json, string calldata key) - external - pure - returns (bool); - - /// Parses a string of JSON data at `key` and coerces it to `bool[]`. - function parseJsonBoolArray(string calldata json, string calldata key) - external - pure - returns (bool[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes`. - function parseJsonBytes(string calldata json, string calldata key) - external - pure - returns (bytes memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32`. - function parseJsonBytes32(string calldata json, string calldata key) - external - pure - returns (bytes32); - - /// Parses a string of JSON data at `key` and coerces it to `bytes32[]`. - function parseJsonBytes32Array(string calldata json, string calldata key) - external - pure - returns (bytes32[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `bytes[]`. - function parseJsonBytesArray(string calldata json, string calldata key) - external - pure - returns (bytes[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `int256`. - function parseJsonInt(string calldata json, string calldata key) - external - pure - returns (int256); - - /// Parses a string of JSON data at `key` and coerces it to `int256[]`. - function parseJsonIntArray(string calldata json, string calldata key) - external - pure - returns (int256[] memory); - - /// Returns an array of all the keys in a JSON object. - function parseJsonKeys(string calldata json, string calldata key) - external - pure - returns (string[] memory keys); - - /// Parses a string of JSON data at `key` and coerces it to `string`. - function parseJsonString(string calldata json, string calldata key) - external - pure - returns (string memory); - - /// Parses a string of JSON data at `key` and coerces it to `string[]`. - function parseJsonStringArray(string calldata json, string calldata key) - external - pure - returns (string[] memory); - - /// Parses a string of JSON data at `key` and coerces it to `uint256`. - function parseJsonUint(string calldata json, string calldata key) - external - pure - returns (uint256); - - /// Parses a string of JSON data at `key` and coerces it to `uint256[]`. - function parseJsonUintArray(string calldata json, string calldata key) - external - pure - returns (uint256[] memory); - - /// ABI-encodes a JSON object. - function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); - - /// ABI-encodes a JSON object at `key`. - function parseJson(string calldata json, string calldata key) - external - pure - returns (bytes memory abiEncodedData); - - /// See `serializeJson`. - function serializeAddress(string calldata objectKey, string calldata valueKey, address value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeAddress( - string calldata objectKey, - string calldata valueKey, - address[] calldata values - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeBool(string calldata objectKey, string calldata valueKey, bool value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBool( - string calldata objectKey, - string calldata valueKey, - bool[] calldata values - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeBytes32( - string calldata objectKey, - string calldata valueKey, - bytes32[] calldata values - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeBytes( - string calldata objectKey, - string calldata valueKey, - bytes calldata value - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeBytes( - string calldata objectKey, - string calldata valueKey, - bytes[] calldata values - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeInt( - string calldata objectKey, - string calldata valueKey, - int256[] calldata values - ) external returns (string memory json); - - /// Serializes a key and value to a JSON object stored in-memory that can be later written to a file. - /// Returns the stringified version of the specific JSON file up to that moment. - function serializeJson(string calldata objectKey, string calldata value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeString( - string calldata objectKey, - string calldata valueKey, - string calldata value - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeString( - string calldata objectKey, - string calldata valueKey, - string[] calldata values - ) external returns (string memory json); - - /// See `serializeJson`. - function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - - /// See `serializeJson`. - function serializeUint( - string calldata objectKey, - string calldata valueKey, - uint256[] calldata values - ) external returns (string memory json); - - /// Write a serialized JSON object to a file. If the file exists, it will be overwritten. - function writeJson(string calldata json, string calldata path) external; - - /// Write a serialized JSON object to an **existing** JSON file, replacing a value with key = - /// This is useful to replace a specific value of a JSON file, without having to parse the entire thing. - function writeJson(string calldata json, string calldata path, string calldata valueKey) - external; - - // ::::::: Scripting ::::::: - - /// Using the address that calls the test contract, has the next call (at this call depth only) - /// create a transaction that can later be signed and sent onchain. - function broadcast() external; - - /// Has the next call (at this call depth only) create a transaction with the address provided - /// as the sender that can later be signed and sent onchain. - function broadcast(address signer) external; - - /// Has the next call (at this call depth only) create a transaction with the private key - /// provided as the sender that can later be signed and sent onchain. - function broadcast(uint256 privateKey) external; - - /// Using the address that calls the test contract, has all subsequent calls - /// (at this call depth only) create transactions that can later be signed and sent onchain. - function startBroadcast() external; - - /// Has all subsequent calls (at this call depth only) create transactions with the address - /// provided that can later be signed and sent onchain. - function startBroadcast(address signer) external; - - /// Has all subsequent calls (at this call depth only) create transactions with the private key - /// provided that can later be signed and sent onchain. - function startBroadcast(uint256 privateKey) external; - - /// Stops collecting onchain transactions. - function stopBroadcast() external; - - // ::::::: String ::::::: - - /// Parses the given `string` into an `address`. - function parseAddress(string calldata stringifiedValue) - external - pure - returns (address parsedValue); - - /// Parses the given `string` into a `bool`. - function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); - - /// Parses the given `string` into `bytes`. - function parseBytes(string calldata stringifiedValue) - external - pure - returns (bytes memory parsedValue); - - /// Parses the given `string` into a `bytes32`. - function parseBytes32(string calldata stringifiedValue) - external - pure - returns (bytes32 parsedValue); - - /// Parses the given `string` into a `int256`. - function parseInt(string calldata stringifiedValue) - external - pure - returns (int256 parsedValue); - - /// Parses the given `string` into a `uint256`. - function parseUint(string calldata stringifiedValue) - external - pure - returns (uint256 parsedValue); - - /// Replaces occurrences of `from` in the given `string` with `to`. - function replace(string calldata input, string calldata from, string calldata to) - external - pure - returns (string memory output); - - /// Splits the given `string` into an array of strings divided by the `delimiter`. - function split(string calldata input, string calldata delimiter) - external - pure - returns (string[] memory outputs); - - /// Converts the given `string` value to Lowercase. - function toLowercase(string calldata input) external pure returns (string memory output); - - /// Converts the given value to a `string`. - function toString(address value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes calldata value) - external - pure - returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bytes32 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(bool value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(uint256 value) external pure returns (string memory stringifiedValue); - - /// Converts the given value to a `string`. - function toString(int256 value) external pure returns (string memory stringifiedValue); - - /// Converts the given `string` value to Uppercase. - function toUppercase(string calldata input) external pure returns (string memory output); - - /// Trims leading and trailing whitespace from the given `string` value. - function trim(string calldata input) external pure returns (string memory output); - - // ::::::: Testing ::::::: - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals - ) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqAbsDecimal( - uint256 left, - uint256 right, - uint256 maxDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. - function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) - external - pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqAbsDecimal( - int256 left, - int256 right, - uint256 maxDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) external pure; - - /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. - /// Includes error message into revert string on failure. - function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string calldata error) - external - pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) external pure; - - /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. - /// Includes error message into revert string on failure. - function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string calldata error) - external - pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, - uint256 decimals - ) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqRelDecimal( - uint256 left, - uint256 right, - uint256 maxPercentDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, - uint256 decimals - ) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertApproxEqRelDecimal( - int256 left, - int256 right, - uint256 maxPercentDelta, - uint256 decimals, - string calldata error - ) external pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta) - external - pure; - - /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Includes error message into revert string on failure. - function assertApproxEqRel( - uint256 left, - uint256 right, - uint256 maxPercentDelta, - string calldata error - ) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) external pure; - - /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. - /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% - /// Includes error message into revert string on failure. - function assertApproxEqRel( - int256 left, - int256 right, - uint256 maxPercentDelta, - string calldata error - ) external pure; - - /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) - external - pure; - - /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. - function assertEqDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) - external - pure; - - /// Asserts that two `bool` values are equal. - function assertEq(bool left, bool right) external pure; - - /// Asserts that two `bool` values are equal and includes error message into revert string on failure. - function assertEq(bool left, bool right, string calldata error) external pure; - - /// Asserts that two `string` values are equal. - function assertEq(string calldata left, string calldata right) external pure; - - /// Asserts that two `string` values are equal and includes error message into revert string on failure. - function assertEq(string calldata left, string calldata right, string calldata error) - external - pure; - - /// Asserts that two `bytes` values are equal. - function assertEq(bytes calldata left, bytes calldata right) external pure; - - /// Asserts that two `bytes` values are equal and includes error message into revert string on failure. - function assertEq(bytes calldata left, bytes calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `bool` values are equal. - function assertEq(bool[] calldata left, bool[] calldata right) external pure; - - /// Asserts that two arrays of `bool` values are equal and includes error message into revert string on failure. - function assertEq(bool[] calldata left, bool[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `uint256 values are equal. - function assertEq(uint256[] calldata left, uint256[] calldata right) external pure; - - /// Asserts that two arrays of `uint256` values are equal and includes error message into revert string on failure. - function assertEq(uint256[] calldata left, uint256[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `int256` values are equal. - function assertEq(int256[] calldata left, int256[] calldata right) external pure; - - /// Asserts that two arrays of `int256` values are equal and includes error message into revert string on failure. - function assertEq(int256[] calldata left, int256[] calldata right, string calldata error) - external - pure; - - /// Asserts that two `uint256` values are equal. - function assertEq(uint256 left, uint256 right) external pure; - - /// Asserts that two arrays of `address` values are equal. - function assertEq(address[] calldata left, address[] calldata right) external pure; - - /// Asserts that two arrays of `address` values are equal and includes error message into revert string on failure. - function assertEq(address[] calldata left, address[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `bytes32` values are equal. - function assertEq(bytes32[] calldata left, bytes32[] calldata right) external pure; - - /// Asserts that two arrays of `bytes32` values are equal and includes error message into revert string on failure. - function assertEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `string` values are equal. - function assertEq(string[] calldata left, string[] calldata right) external pure; - - /// Asserts that two arrays of `string` values are equal and includes error message into revert string on failure. - function assertEq(string[] calldata left, string[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `bytes` values are equal. - function assertEq(bytes[] calldata left, bytes[] calldata right) external pure; - - /// Asserts that two arrays of `bytes` values are equal and includes error message into revert string on failure. - function assertEq(bytes[] calldata left, bytes[] calldata right, string calldata error) - external - pure; - - /// Asserts that two `uint256` values are equal and includes error message into revert string on failure. - function assertEq(uint256 left, uint256 right, string calldata error) external pure; - - /// Asserts that two `int256` values are equal. - function assertEq(int256 left, int256 right) external pure; - - /// Asserts that two `int256` values are equal and includes error message into revert string on failure. - function assertEq(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `address` values are equal. - function assertEq(address left, address right) external pure; - - /// Asserts that two `address` values are equal and includes error message into revert string on failure. - function assertEq(address left, address right, string calldata error) external pure; - - /// Asserts that two `bytes32` values are equal. - function assertEq(bytes32 left, bytes32 right) external pure; - - /// Asserts that two `bytes32` values are equal and includes error message into revert string on failure. - function assertEq(bytes32 left, bytes32 right, string calldata error) external pure; - - /// Asserts that the given condition is false. - function assertFalse(bool condition) external pure; - - /// Asserts that the given condition is false and includes error message into revert string on failure. - function assertFalse(bool condition, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. - function assertGeDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - function assertGe(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than or equal to second. - /// Includes error message into revert string on failure. - function assertGe(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - function assertGe(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be greater than or equal to second. - /// Includes error message into revert string on failure. - function assertGe(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. - function assertGtDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertGtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - function assertGt(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be greater than second. - /// Includes error message into revert string on failure. - function assertGt(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - function assertGt(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be greater than second. - /// Includes error message into revert string on failure. - function assertGt(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. - function assertLeDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - function assertLe(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be less than or equal to second. - /// Includes error message into revert string on failure. - function assertLe(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - function assertLe(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be less than or equal to second. - /// Includes error message into revert string on failure. - function assertLe(int256 left, int256 right, string calldata error) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. - function assertLtDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Formats values with decimals in failure message. Includes error message into revert string on failure. - function assertLtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) - external - pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - function assertLt(uint256 left, uint256 right) external pure; - - /// Compares two `uint256` values. Expects first value to be less than second. - /// Includes error message into revert string on failure. - function assertLt(uint256 left, uint256 right, string calldata error) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - function assertLt(int256 left, int256 right) external pure; - - /// Compares two `int256` values. Expects first value to be less than second. - /// Includes error message into revert string on failure. - function assertLt(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. - function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; - - /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertNotEqDecimal( - uint256 left, - uint256 right, - uint256 decimals, - string calldata error - ) external pure; - - /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) external pure; - - /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. - /// Includes error message into revert string on failure. - function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) - external - pure; - - /// Asserts that two `bool` values are not equal. - function assertNotEq(bool left, bool right) external pure; - - /// Asserts that two `bool` values are not equal and includes error message into revert string on failure. - function assertNotEq(bool left, bool right, string calldata error) external pure; - - /// Asserts that two `string` values are not equal. - function assertNotEq(string calldata left, string calldata right) external pure; - - /// Asserts that two `string` values are not equal and includes error message into revert string on failure. - function assertNotEq(string calldata left, string calldata right, string calldata error) - external - pure; - - /// Asserts that two `bytes` values are not equal. - function assertNotEq(bytes calldata left, bytes calldata right) external pure; - - /// Asserts that two `bytes` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes calldata left, bytes calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `bool` values are not equal. - function assertNotEq(bool[] calldata left, bool[] calldata right) external pure; - - /// Asserts that two arrays of `bool` values are not equal and includes error message into revert string on failure. - function assertNotEq(bool[] calldata left, bool[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `uint256` values are not equal. - function assertNotEq(uint256[] calldata left, uint256[] calldata right) external pure; - - /// Asserts that two arrays of `uint256` values are not equal and includes error message into revert string on failure. - function assertNotEq(uint256[] calldata left, uint256[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `int256` values are not equal. - function assertNotEq(int256[] calldata left, int256[] calldata right) external pure; - - /// Asserts that two arrays of `int256` values are not equal and includes error message into revert string on failure. - function assertNotEq(int256[] calldata left, int256[] calldata right, string calldata error) - external - pure; - - /// Asserts that two `uint256` values are not equal. - function assertNotEq(uint256 left, uint256 right) external pure; - - /// Asserts that two arrays of `address` values are not equal. - function assertNotEq(address[] calldata left, address[] calldata right) external pure; - - /// Asserts that two arrays of `address` values are not equal and includes error message into revert string on failure. - function assertNotEq(address[] calldata left, address[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `bytes32` values are not equal. - function assertNotEq(bytes32[] calldata left, bytes32[] calldata right) external pure; - - /// Asserts that two arrays of `bytes32` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `string` values are not equal. - function assertNotEq(string[] calldata left, string[] calldata right) external pure; - - /// Asserts that two arrays of `string` values are not equal and includes error message into revert string on failure. - function assertNotEq(string[] calldata left, string[] calldata right, string calldata error) - external - pure; - - /// Asserts that two arrays of `bytes` values are not equal. - function assertNotEq(bytes[] calldata left, bytes[] calldata right) external pure; - - /// Asserts that two arrays of `bytes` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes[] calldata left, bytes[] calldata right, string calldata error) - external - pure; - - /// Asserts that two `uint256` values are not equal and includes error message into revert string on failure. - function assertNotEq(uint256 left, uint256 right, string calldata error) external pure; - - /// Asserts that two `int256` values are not equal. - function assertNotEq(int256 left, int256 right) external pure; - - /// Asserts that two `int256` values are not equal and includes error message into revert string on failure. - function assertNotEq(int256 left, int256 right, string calldata error) external pure; - - /// Asserts that two `address` values are not equal. - function assertNotEq(address left, address right) external pure; - - /// Asserts that two `address` values are not equal and includes error message into revert string on failure. - function assertNotEq(address left, address right, string calldata error) external pure; - - /// Asserts that two `bytes32` values are not equal. - function assertNotEq(bytes32 left, bytes32 right) external pure; - - /// Asserts that two `bytes32` values are not equal and includes error message into revert string on failure. - function assertNotEq(bytes32 left, bytes32 right, string calldata error) external pure; - - /// Asserts that the given condition is true. - function assertTrue(bool condition) external pure; - - /// Asserts that the given condition is true and includes error message into revert string on failure. - function assertTrue(bool condition, string calldata error) external pure; - - /// If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool condition) external pure; - - /// Writes a breakpoint to jump to in the debugger. - function breakpoint(string calldata char) external; - - /// Writes a conditional breakpoint to jump to in the debugger. - function breakpoint(string calldata char, bool value) external; - - /// Returns the RPC url for the given alias. - function rpcUrl(string calldata rpcAlias) external view returns (string memory json); - - /// Returns all rpc urls and their aliases as structs. - function rpcUrlStructs() external view returns (Rpc[] memory urls); - - /// Returns all rpc urls and their aliases `[alias, url][]`. - function rpcUrls() external view returns (string[2][] memory urls); - - /// Suspends execution of the main thread for `duration` milliseconds. - function sleep(uint256 duration) external; - - // ::::::: Toml ::::::: - - /// Checks if `key` exists in a TOML table. - function keyExistsToml(string calldata toml, string calldata key) - external - view - returns (bool); - - /// Parses a string of TOML data at `key` and coerces it to `address`. - function parseTomlAddress(string calldata toml, string calldata key) - external - pure - returns (address); - - /// Parses a string of TOML data at `key` and coerces it to `address[]`. - function parseTomlAddressArray(string calldata toml, string calldata key) - external - pure - returns (address[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bool`. - function parseTomlBool(string calldata toml, string calldata key) - external - pure - returns (bool); - - /// Parses a string of TOML data at `key` and coerces it to `bool[]`. - function parseTomlBoolArray(string calldata toml, string calldata key) - external - pure - returns (bool[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes`. - function parseTomlBytes(string calldata toml, string calldata key) - external - pure - returns (bytes memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes32`. - function parseTomlBytes32(string calldata toml, string calldata key) - external - pure - returns (bytes32); - - /// Parses a string of TOML data at `key` and coerces it to `bytes32[]`. - function parseTomlBytes32Array(string calldata toml, string calldata key) - external - pure - returns (bytes32[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `bytes[]`. - function parseTomlBytesArray(string calldata toml, string calldata key) - external - pure - returns (bytes[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `int256`. - function parseTomlInt(string calldata toml, string calldata key) - external - pure - returns (int256); - - /// Parses a string of TOML data at `key` and coerces it to `int256[]`. - function parseTomlIntArray(string calldata toml, string calldata key) - external - pure - returns (int256[] memory); - - /// Returns an array of all the keys in a TOML table. - function parseTomlKeys(string calldata toml, string calldata key) - external - pure - returns (string[] memory keys); - - /// Parses a string of TOML data at `key` and coerces it to `string`. - function parseTomlString(string calldata toml, string calldata key) - external - pure - returns (string memory); - - /// Parses a string of TOML data at `key` and coerces it to `string[]`. - function parseTomlStringArray(string calldata toml, string calldata key) - external - pure - returns (string[] memory); - - /// Parses a string of TOML data at `key` and coerces it to `uint256`. - function parseTomlUint(string calldata toml, string calldata key) - external - pure - returns (uint256); - - /// Parses a string of TOML data at `key` and coerces it to `uint256[]`. - function parseTomlUintArray(string calldata toml, string calldata key) - external - pure - returns (uint256[] memory); - - /// ABI-encodes a TOML table. - function parseToml(string calldata toml) external pure returns (bytes memory abiEncodedData); - - /// ABI-encodes a TOML table at `key`. - function parseToml(string calldata toml, string calldata key) - external - pure - returns (bytes memory abiEncodedData); - - /// Takes serialized JSON, converts to TOML and write a serialized TOML to a file. - function writeToml(string calldata json, string calldata path) external; - - /// Takes serialized JSON, converts to TOML and write a serialized TOML table to an **existing** TOML file, replacing a value with key = - /// This is useful to replace a specific value of a TOML file, without having to parse the entire thing. - function writeToml(string calldata json, string calldata path, string calldata valueKey) - external; - - // ::::::: Utilities ::::::: - - /// Compute the address of a contract created with CREATE2 using the given CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer) - external - pure - returns (address); - - /// Compute the address of a contract created with CREATE2 using the default CREATE2 deployer. - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) - external - pure - returns (address); - - /// Compute the address a contract will be deployed at for a given deployer address and nonce. - function computeCreateAddress(address deployer, uint256 nonce) - external - pure - returns (address); - - /// Derives a private key from the name, labels the account with that name, and returns the wallet. - function createWallet(string calldata walletLabel) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key and returns the wallet. - function createWallet(uint256 privateKey) external returns (Wallet memory wallet); - - /// Generates a wallet from the private key, labels the account with that name, and returns the wallet. - function createWallet(uint256 privateKey, string calldata walletLabel) - external - returns (Wallet memory wallet); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) - /// at the derivation path `m/44'/60'/0'/0/{index}`. - function deriveKey(string calldata mnemonic, uint32 index) - external - pure - returns (uint256 privateKey); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) - /// at `{derivationPath}{index}`. - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) - external - pure - returns (uint256 privateKey); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language - /// at the derivation path `m/44'/60'/0'/0/{index}`. - function deriveKey(string calldata mnemonic, uint32 index, string calldata language) - external - pure - returns (uint256 privateKey); - - /// Derive a private key from a provided mnenomic string (or mnenomic file path) in the specified language - /// at `{derivationPath}{index}`. - function deriveKey( - string calldata mnemonic, - string calldata derivationPath, - uint32 index, - string calldata language - ) external pure returns (uint256 privateKey); - - /// Derives secp256r1 public key from the provided `privateKey`. - function publicKeyP256(uint256 privateKey) - external - pure - returns (uint256 publicKeyX, uint256 publicKeyY); - - /// Gets the label for the specified address. - function getLabel(address account) external view returns (string memory currentLabel); - - /// Get a `Wallet`'s nonce. - function getNonce(Wallet calldata wallet) external returns (uint64 nonce); - - /// Labels an address in call traces. - function label(address account, string calldata newLabel) external; - - /// Adds a private key to the local forge wallet and returns the address. - function rememberKey(uint256 privateKey) external returns (address keyAddr); - - /// Signs data with a `Wallet`. - function sign(Wallet calldata wallet, bytes32 digest) - external - returns (uint8 v, bytes32 r, bytes32 s); - - /// Encodes a `bytes` value to a base64url string. - function toBase64URL(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64url string. - function toBase64URL(string calldata data) external pure returns (string memory); - - /// Encodes a `bytes` value to a base64 string. - function toBase64(bytes calldata data) external pure returns (string memory); - - /// Encodes a `string` value to a base64 string. - function toBase64(string calldata data) external pure returns (string memory); -} - -/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used -/// in tests, but it is not recommended to use these cheats in scripts. -interface Vm is VmSafe { - // ::::::: EVM ::::::: - - /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. - function activeFork() external view returns (uint256 forkId); - - /// In forking mode, explicitly grant the given address cheatcode access. - function allowCheatcodes(address account) external; - - /// Sets `block.chainid`. - function chainId(uint256 newChainId) external; - - /// Clears all mocked calls. - function clearMockedCalls() external; - - /// Sets `block.coinbase`. - function coinbase(address newCoinbase) external; - - /// Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork. - function createFork(string calldata urlOrAlias) external returns (uint256 forkId); - - /// Creates a new fork with the given endpoint and block and returns the identifier of the fork. - function createFork(string calldata urlOrAlias, uint256 blockNumber) - external - returns (uint256 forkId); - - /// Creates a new fork with the given endpoint and at the block the given transaction was mined in, - /// replays all transaction mined in the block before the transaction, and returns the identifier of the fork. - function createFork(string calldata urlOrAlias, bytes32 txHash) - external - returns (uint256 forkId); - - /// Creates and also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); - - /// Creates and also selects a new fork with the given endpoint and block and returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) - external - returns (uint256 forkId); - - /// Creates and also selects new fork with the given endpoint and at the block the given transaction was mined in, - /// replays all transaction mined in the block before the transaction, returns the identifier of the fork. - function createSelectFork(string calldata urlOrAlias, bytes32 txHash) - external - returns (uint256 forkId); - - /// Sets an address' balance. - function deal(address account, uint256 newBalance) external; - - /// Removes the snapshot with the given ID created by `snapshot`. - /// Takes the snapshot ID to delete. - /// Returns `true` if the snapshot was successfully deleted. - /// Returns `false` if the snapshot does not exist. - function deleteSnapshot(uint256 snapshotId) external returns (bool success); - - /// Removes _all_ snapshots previously created by `snapshot`. - function deleteSnapshots() external; - - /// Sets `block.difficulty`. - /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead. - /// Reverts if used on unsupported EVM versions. - function difficulty(uint256 newDifficulty) external; - - /// Dump a genesis JSON file's `allocs` to disk. - function dumpState(string calldata pathToStateJson) external; - - /// Sets an address' code. - function etch(address target, bytes calldata newRuntimeBytecode) external; - - /// Sets `block.basefee`. - function fee(uint256 newBasefee) external; - - /// Returns true if the account is marked as persistent. - function isPersistent(address account) external view returns (bool persistent); - - /// Load a genesis JSON file's `allocs` into the in-memory revm state. - function loadAllocs(string calldata pathToAllocsJson) external; - - /// Marks that the account(s) should use persistent storage across fork swaps in a multifork setup - /// Meaning, changes made to the state of this account will be kept when switching forks. - function makePersistent(address account) external; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1) external; - - /// See `makePersistent(address)`. - function makePersistent(address account0, address account1, address account2) external; - - /// See `makePersistent(address)`. - function makePersistent(address[] calldata accounts) external; - - /// Reverts a call to an address with specified revert data. - function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) - external; - - /// Reverts a call to an address with a specific `msg.value`, with specified revert data. - function mockCallRevert( - address callee, - uint256 msgValue, - bytes calldata data, - bytes calldata revertData - ) external; - - /// Mocks a call to an address, returning specified data. - /// Calldata can either be strict or a partial match, e.g. if you only - /// pass a Solidity selector to the expected calldata, then the entire Solidity - /// function will be mocked. - function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; - - /// Mocks a call to an address with a specific `msg.value`, returning specified data. - /// Calldata match takes precedence over `msg.value` in case of ambiguity. - function mockCall( - address callee, - uint256 msgValue, - bytes calldata data, - bytes calldata returnData - ) external; - - /// Sets the *next* call's `msg.sender` to be the input address. - function prank(address msgSender) external; - - /// Sets the *next* call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. - function prank(address msgSender, address txOrigin) external; - - /// Sets `block.prevrandao`. - /// Not available on EVM versions before Paris. Use `difficulty` instead. - /// If used on unsupported EVM versions it will revert. - function prevrandao(bytes32 newPrevrandao) external; - - /// Reads the current `msg.sender` and `tx.origin` from state and reports if there is any active caller modification. - function readCallers() - external - returns (CallerMode callerMode, address msgSender, address txOrigin); - - /// Resets the nonce of an account to 0 for EOAs and 1 for contract accounts. - function resetNonce(address account) external; - - /// Revert the state of the EVM to a previous snapshot - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted. - /// Returns `false` if the snapshot does not exist. - /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteSnapshot`. - function revertTo(uint256 snapshotId) external returns (bool success); - - /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots - /// Takes the snapshot ID to revert to. - /// Returns `true` if the snapshot was successfully reverted and deleted. - /// Returns `false` if the snapshot does not exist. - function revertToAndDelete(uint256 snapshotId) external returns (bool success); - - /// Revokes persistent status from the address, previously added via `makePersistent`. - function revokePersistent(address account) external; - - /// See `revokePersistent(address)`. - function revokePersistent(address[] calldata accounts) external; - - /// Sets `block.height`. - function roll(uint256 newHeight) external; - - /// Updates the currently active fork to given block number - /// This is similar to `roll` but for the currently active fork. - function rollFork(uint256 blockNumber) external; - - /// Updates the currently active fork to given transaction. This will `rollFork` with the number - /// of the block the transaction was mined in and replays all transaction mined before it in the block. - function rollFork(bytes32 txHash) external; - - /// Updates the given fork to given block number. - function rollFork(uint256 forkId, uint256 blockNumber) external; - - /// Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block. - function rollFork(uint256 forkId, bytes32 txHash) external; - - /// Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256 forkId) external; - - /// Sets the nonce of an account. Must be higher than the current nonce of the account. - function setNonce(address account, uint64 newNonce) external; - - /// Sets the nonce of an account to an arbitrary value. - function setNonceUnsafe(address account, uint64 newNonce) external; - - /// Snapshot the current state of the evm. - /// Returns the ID of the snapshot that was created. - /// To revert a snapshot use `revertTo`. - function snapshot() external returns (uint256 snapshotId); - - /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called. - function startPrank(address msgSender) external; - - /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. - function startPrank(address msgSender, address txOrigin) external; - - /// Resets subsequent calls' `msg.sender` to be `address(this)`. - function stopPrank() external; - - /// Stores a value to an address' storage slot. - function store(address target, bytes32 slot, bytes32 value) external; - - /// Fetches the given transaction from the active fork and executes it on the current state. - function transact(bytes32 txHash) external; - - /// Fetches the given transaction from the given fork and executes it on the current state. - function transact(uint256 forkId, bytes32 txHash) external; - - /// Sets `tx.gasprice`. - function txGasPrice(uint256 newGasPrice) external; - - /// Sets `block.timestamp`. - function warp(uint256 newTimestamp) external; - - // ::::::: Testing ::::::: - - /// Expect a call to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) - external; - - /// Expect given number of calls to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. - function expectCallMinGas( - address callee, - uint256 msgValue, - uint64 minGas, - bytes calldata data, - uint64 count - ) external; - - /// Expects a call to an address with the specified calldata. - /// Calldata can either be a strict or a partial match. - function expectCall(address callee, bytes calldata data) external; - - /// Expects given number of calls to an address with the specified calldata. - function expectCall(address callee, bytes calldata data, uint64 count) external; - - /// Expects a call to an address with the specified `msg.value` and calldata. - function expectCall(address callee, uint256 msgValue, bytes calldata data) external; - - /// Expects given number of calls to an address with the specified `msg.value` and calldata. - function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) - external; - - /// Expect a call to an address with the specified `msg.value`, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) - external; - - /// Expects given number of calls to an address with the specified `msg.value`, gas, and calldata. - function expectCall( - address callee, - uint256 msgValue, - uint64 gas, - bytes calldata data, - uint64 count - ) external; - - /// Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.). - /// Call this function, then emit an event, then call a function. Internally after the call, we check if - /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans). - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) - external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit( - bool checkTopic1, - bool checkTopic2, - bool checkTopic3, - bool checkData, - address emitter - ) external; - - /// Prepare an expected log with all topic and data checks enabled. - /// Call this function, then emit an event, then call a function. Internally after the call, we check if - /// logs were emitted in the expected order with the expected topics and data. - function expectEmit() external; - - /// Same as the previous method, but also checks supplied address against emitting contract. - function expectEmit(address emitter) external; - - /// Expects an error on next call with any revert data. - function expectRevert() external; - - /// Expects an error on next call that starts with the revert data. - function expectRevert(bytes4 revertData) external; - - /// Expects an error on next call that exactly matches the revert data. - function expectRevert(bytes calldata revertData) external; - - /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other - /// memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. - function expectSafeMemory(uint64 min, uint64 max) external; - - /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. - /// If any other memory is written to, the test will fail. Can be called multiple times to add more ranges - /// to the set. - function expectSafeMemoryCall(uint64 min, uint64 max) external; - - /// Marks a test as skipped. Must be called at the top of the test. - function skip(bool skipTest) external; - - /// Stops all safe memory expectation in the current subcontext. - function stopExpectSafeMemory() external; - - /// Sets the blockhash for a given block number. - function setBlockhash(uint256 blockNumber, bytes32 blockHash) external; -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockCallContextChecker.sol b/grouperBot/lib/solady/test/utils/mocks/MockCallContextChecker.sol deleted file mode 100644 index 93b3cf9..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockCallContextChecker.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {MockUUPSImplementation} from "./MockUUPSImplementation.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockCallContextChecker is MockUUPSImplementation { - uint256 public x; - - function checkOnlyProxy() public view returns (bool) { - _checkOnlyProxy(); - return true; - } - - function checkNotDelegated() public view returns (bool) { - _checkNotDelegated(); - return true; - } - - function checkOnlyEIP7702Authority() public view returns (bool) { - _checkOnlyEIP7702Authority(); - return true; - } - - function setX(uint256 newX) public { - x = newX; - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockCd.sol b/grouperBot/lib/solady/test/utils/mocks/MockCd.sol deleted file mode 100644 index 8dbb4d7..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockCd.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {LibZip} from "../../../src/utils/LibZip.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockCd { - error Hash(bytes32 h); - - bytes32 public dataHash; - bytes32 public numbersHash; - uint256 public lastCallvalue; - address public lastCaller; - - function storeDataHash(bytes calldata data, bool success) - external - payable - returns (bytes32 result) - { - result = keccak256(data); - if (!success) { - revert Hash(result); - } - dataHash = result; - lastCallvalue = msg.value; - lastCaller = msg.sender; - } - - function storeNumbersHash(uint256[] calldata numbers, bool success) - external - payable - returns (bytes32 result) - { - result = keccak256(abi.encode(numbers)); - if (!success) { - revert Hash(result); - } - numbersHash = result; - lastCallvalue = msg.value; - lastCaller = msg.sender; - } - - receive() external payable { - LibZip.cdFallback(); - } - - fallback() external payable { - LibZip.cdFallback(); - } -} - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockCdFallbackDecompressor { - receive() external payable { - _interceptCdFallback(); - LibZip.cdFallback(); - } - - fallback() external payable { - _interceptCdFallback(); - LibZip.cdFallback(); - } - - function _interceptCdFallback() internal { - assembly { - if iszero(calldatasize()) { - mstore(0x00, keccak256(0x00, 0x00)) - return(0x00, 0x20) - } - if sload(0) { - calldatacopy(0x00, 0x00, calldatasize()) - mstore(0x00, keccak256(0x00, calldatasize())) - return(0x00, 0x20) - } - sstore(0, 1) - } - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockEIP712.sol b/grouperBot/lib/solady/test/utils/mocks/MockEIP712.sol deleted file mode 100644 index 821da9c..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockEIP712.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "../../../src/utils/EIP712.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockEIP712 is EIP712 { - function _domainNameAndVersion() - internal - pure - override - returns (string memory name, string memory version) - { - name = "Milady"; - version = "1"; - } - - function hashTypedData(bytes32 structHash) external view returns (bytes32) { - return _hashTypedData(structHash); - } - - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparator(); - } - - function hashTypedDataSansChainId(bytes32 structHash) external view returns (bytes32) { - return _hashTypedDataSansChainId(structHash); - } - - function hashTypedDataSansChainIdAndVerifyingContract(bytes32 structHash) - external - view - returns (bytes32) - { - return _hashTypedDataSansChainIdAndVerifyingContract(structHash); - } - - function hashTypedDataSansVerifyingContract(bytes32 structHash) - external - view - returns (bytes32) - { - return _hashTypedDataSansVerifyingContract(structHash); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockEIP712Dynamic.sol b/grouperBot/lib/solady/test/utils/mocks/MockEIP712Dynamic.sol deleted file mode 100644 index d040a7d..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockEIP712Dynamic.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "../../../src/utils/EIP712.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockEIP712Dynamic is EIP712 { - string private _name; - string private _version; - - constructor(string memory name, string memory version) { - _name = name; - _version = version; - } - - function setDomainNameAndVersion(string memory name, string memory version) public { - _name = name; - _version = version; - } - - function _domainNameAndVersion() - internal - view - override - returns (string memory name, string memory version) - { - name = _name; - version = _version; - } - - function _domainNameAndVersionMayChange() internal pure override returns (bool) { - return true; - } - - function hashTypedData(bytes32 structHash) external view returns (bytes32) { - return _hashTypedData(structHash); - } - - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparator(); - } - - function hashTypedDataSansChainId(bytes32 structHash) external view returns (bytes32) { - return _hashTypedDataSansChainId(structHash); - } - - function hashTypedDataSansChainIdAndVerifyingContract(bytes32 structHash) - external - view - returns (bytes32) - { - return _hashTypedDataSansChainIdAndVerifyingContract(structHash); - } - - function hashTypedDataSansVerifyingContract(bytes32 structHash) - external - view - returns (bytes32) - { - return _hashTypedDataSansVerifyingContract(structHash); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC1155.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC1155.sol deleted file mode 100644 index 5f85d80..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC1155.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC1155} from "../../../src/tokens/ERC1155.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC1155 is ERC1155, Brutalizer { - bytes32 public lastDataHash; - - function uri(uint256) public pure virtual override returns (string memory) {} - - function mint(address to, uint256 id, uint256 amount, bytes memory data) public virtual { - _mint(_brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function batchMint( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - _batchMint(_brutalized(to), ids, amounts, data); - lastDataHash = keccak256(data); - } - - function burn(address from, uint256 id, uint256 amount) public virtual { - _burn(_brutalized(msg.sender), _brutalized(from), id, amount); - } - - function uncheckedBurn(address from, uint256 id, uint256 amount) public virtual { - _burn(_brutalized(from), id, amount); - } - - function batchBurn(address from, uint256[] memory ids, uint256[] memory amounts) - public - virtual - { - _batchBurn(_brutalized(msg.sender), _brutalized(from), ids, amounts); - } - - function uncheckedBatchBurn(address from, uint256[] memory ids, uint256[] memory amounts) - public - virtual - { - _batchBurn(_brutalized(from), ids, amounts); - } - - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) public virtual override { - super.safeTransferFrom(_brutalized(from), _brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function directSafeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual { - _safeTransfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function uncheckedSafeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual { - _safeTransfer(_brutalized(address(0)), _brutalized(from), _brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) public virtual override { - super.safeBatchTransferFrom(_brutalized(from), _brutalized(to), ids, amounts, data); - lastDataHash = keccak256(data); - } - - function directSafeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - _safeBatchTransfer( - _brutalized(msg.sender), _brutalized(from), _brutalized(to), ids, amounts, data - ); - lastDataHash = keccak256(data); - } - - function uncheckedSafeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - _safeBatchTransfer( - _brutalized(address(0)), _brutalized(from), _brutalized(to), ids, amounts, data - ); - lastDataHash = keccak256(data); - } - - function directSetApprovalForAll(address operator, bool approved) public virtual { - _setApprovalForAll(_brutalized(msg.sender), _brutalized(operator), approved); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC1271Malicious.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC1271Malicious.sol deleted file mode 100644 index 3428d1a..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC1271Malicious.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC1271Malicious { - function isValidSignature(bytes32, bytes calldata) external pure returns (bytes4) { - /// @solidity memory-safe-assembly - assembly { - mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - return(0, 32) - } - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC1271Wallet.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC1271Wallet.sol deleted file mode 100644 index 6b48a18..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC1271Wallet.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "../../../src/utils/ECDSA.sol"; - -/// @notice A generic interface for a contract which properly accepts ERC721 tokens. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) -abstract contract ERC721TokenReceiver { - function onERC721Received(address, address, uint256, bytes calldata) - external - virtual - returns (bytes4) - { - return ERC721TokenReceiver.onERC721Received.selector; - } -} - -/// @notice A generic interface for a contract which properly accepts ERC1155 tokens. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) -abstract contract ERC1155TokenReceiver { - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - external - virtual - returns (bytes4) - { - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual returns (bytes4) { - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC1271Wallet is ERC721TokenReceiver, ERC1155TokenReceiver { - address public signer; - bool public useSignaturePassthrough; - - constructor(address signer_) { - signer = signer_; - } - - function setSigner(address signer_) external { - signer = signer_; - } - - function isValidSignature(bytes32 hash, bytes calldata signature) - external - view - returns (bytes4) - { - if (useSignaturePassthrough) { - return keccak256(signature) == hash ? bytes4(0x1626ba7e) : bytes4(0); - } - return ECDSA.recover(hash, signature) == signer ? bytes4(0x1626ba7e) : bytes4(0); - } - - function setUseSignaturePassthrough(bool value) public { - useSignaturePassthrough = value; - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC20.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC20.sol deleted file mode 100644 index c4f9da1..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC20.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC20} from "../../../src/tokens/ERC20.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC20 is ERC20, Brutalizer { - string internal _name; - string internal _symbol; - uint8 internal _decimals; - bytes32 internal immutable _nameHash; - - constructor(string memory name_, string memory symbol_, uint8 decimals_) { - _name = name_; - _symbol = symbol_; - _decimals = decimals_; - _nameHash = keccak256(bytes(name_)); - } - - function _constantNameHash() internal view virtual override returns (bytes32) { - return _nameHash; - } - - function name() public view virtual override returns (string memory) { - return _name; - } - - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - function decimals() public view virtual override returns (uint8) { - return _decimals; - } - - function mint(address to, uint256 value) public virtual { - _mint(_brutalized(to), value); - } - - function burn(address from, uint256 value) public virtual { - _burn(_brutalized(from), value); - } - - function directTransfer(address from, address to, uint256 amount) public virtual { - _transfer(_brutalized(from), _brutalized(to), amount); - } - - function directSpendAllowance(address owner, address spender, uint256 amount) public virtual { - _spendAllowance(_brutalized(owner), _brutalized(spender), amount); - } - - function transfer(address to, uint256 amount) public virtual override returns (bool) { - return super.transfer(_brutalized(to), amount); - } - - function transferFrom(address from, address to, uint256 amount) - public - virtual - override - returns (bool) - { - return super.transferFrom(_brutalized(from), _brutalized(to), amount); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC20ForPermit2.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC20ForPermit2.sol deleted file mode 100644 index db2ba6e..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC20ForPermit2.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {MockERC20} from "./MockERC20.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC20ForPermit2 is MockERC20 { - constructor(string memory name_, string memory symbol_, uint8 decimals_) - MockERC20(name_, symbol_, decimals_) - {} - - function _givePermit2InfiniteAllowance() internal view virtual override returns (bool) { - return true; - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC20LikeUSDT.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC20LikeUSDT.sol deleted file mode 100644 index 2089ddf..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC20LikeUSDT.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {MockERC20} from "./MockERC20.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC20LikeUSDT is MockERC20 { - constructor() MockERC20("Tether USD", "USDT", 6) {} - - // Replicates USDT (0xdAC17F958D2ee523a2206206994597C13D831ec7) approval behavior. - function approve(address spender, uint256 amount) public virtual override returns (bool) { - require(amount == 0 || allowance(msg.sender, spender) == 0, "USDT approval failure"); - return super.approve(spender, amount); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC20Votes.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC20Votes.sol deleted file mode 100644 index 0a7fd4d..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC20Votes.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC20, ERC20Votes} from "../../../src/tokens/ERC20Votes.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC20Votes is ERC20Votes, Brutalizer { - function name() public view virtual override returns (string memory) { - return "name"; - } - - function symbol() public view virtual override returns (string memory) { - return "symbol"; - } - - function mint(address to, uint256 value) public virtual { - _mint(to, value); - } - - function burn(address from, uint256 value) public virtual { - _burn(from, value); - } - - function directTransfer(address from, address to, uint256 amount) public virtual { - _transfer(from, to, amount); - } - - function directSpendAllowance(address owner, address spender, uint256 amount) public virtual { - _spendAllowance(owner, spender, amount); - } - - function directDelegate(address delegator, address delegatee) public { - _delegate(delegator, delegatee); - } - - function directIncrementNonce(address owner) public { - _incrementNonce(owner); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC2981.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC2981.sol deleted file mode 100644 index af2b394..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC2981.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC2981} from "../../../src/tokens/ERC2981.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC2981 is ERC2981, Brutalizer { - function feeDenominator() external pure returns (uint256) { - return _feeDenominator(); - } - - function setDefaultRoyalty(address receiver, uint96 feeNumerator) external { - _setDefaultRoyalty(_brutalized(receiver), _brutalizedUint96(feeNumerator)); - } - - function deleteDefaultRoyalty() external { - _deleteDefaultRoyalty(); - } - - function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external { - _setTokenRoyalty(tokenId, _brutalized(receiver), _brutalizedUint96(feeNumerator)); - } - - function resetTokenRoyalty(uint256 tokenId) external { - _resetTokenRoyalty(tokenId); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC4337.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC4337.sol deleted file mode 100644 index ca90e80..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC4337.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC4337} from "../../../src/accounts/ERC4337.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC4337 is ERC4337, Brutalizer { - function withdrawDepositTo(address to, uint256 amount) public payable virtual override { - super.withdrawDepositTo(_brutalized(to), amount); - } - - function executeBatch(uint256 filler, Call[] calldata calls) - public - payable - virtual - onlyEntryPointOrOwner - returns (bytes[] memory results) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, add(mload(0x40), mod(filler, 0x40))) - } - return super.executeBatch(calls); - } - - function _domainNameAndVersion() - internal - pure - override - returns (string memory, string memory) - { - return ("Milady", "1"); - } - - function hashTypedData(bytes32 structHash) external view returns (bytes32) { - return _hashTypedData(structHash); - } - - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparator(); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC4626.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC4626.sol deleted file mode 100644 index 82cd582..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC4626.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC20, ERC4626} from "../../../src/tokens/ERC4626.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC4626 is ERC4626 { - bool public immutable useVirtualShares; - uint8 public immutable decimalsOffset; - - address internal immutable _underlying; - uint8 internal immutable _decimals; - - string internal _name; - string internal _symbol; - - uint256 public beforeWithdrawHookCalledCounter; - uint256 public afterDepositHookCalledCounter; - - constructor( - address underlying_, - string memory name_, - string memory symbol_, - bool useVirtualShares_, - uint8 decimalsOffset_ - ) { - _underlying = underlying_; - - (bool success, uint8 result) = _tryGetAssetDecimals(underlying_); - _decimals = success ? result : _DEFAULT_UNDERLYING_DECIMALS; - - _name = name_; - _symbol = symbol_; - - useVirtualShares = useVirtualShares_; - decimalsOffset = decimalsOffset_; - } - - function asset() public view virtual override returns (address) { - return _underlying; - } - - function name() public view virtual override returns (string memory) { - return _name; - } - - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - function _useVirtualShares() internal view virtual override returns (bool) { - return useVirtualShares; - } - - function _underlyingDecimals() internal view virtual override returns (uint8) { - return _decimals; - } - - function _decimalsOffset() internal view virtual override returns (uint8) { - return decimalsOffset; - } - - function _beforeWithdraw(uint256, uint256) internal override { - unchecked { - ++beforeWithdrawHookCalledCounter; - } - } - - function _afterDeposit(uint256, uint256) internal override { - unchecked { - ++afterDepositHookCalledCounter; - } - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC6551.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC6551.sol deleted file mode 100644 index 4da4f64..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC6551.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC6551} from "../../../src/accounts/ERC6551.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC6551 is ERC6551, Brutalizer { - function executeBatch(uint256 filler, Call[] calldata calls, uint8 operation) - public - payable - virtual - returns (bytes[] memory results) - { - /// @solidity memory-safe-assembly - assembly { - mstore(0x40, add(mload(0x40), mod(filler, 0x40))) - } - return super.executeBatch(calls, operation); - } - - function _domainNameAndVersion() - internal - pure - override - returns (string memory, string memory) - { - return ("Milady", "1"); - } - - function hashTypedData(bytes32 structHash) external view returns (bytes32) { - return _hashTypedData(structHash); - } - - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparator(); - } - - function mockId() public pure virtual returns (string memory) { - return "1"; - } - - function somethingThatUpdatesState(bytes calldata) public { - _updateState(); - } - - function clearState() public { - /// @solidity memory-safe-assembly - assembly { - sstore(_ERC6551_STATE_SLOT, 0) - } - } -} - -contract MockERC6551V2 is MockERC6551 { - function mockId() public pure virtual override(MockERC6551) returns (string memory) { - return "2"; - } - - function _updateState() internal virtual override(ERC6551) { - bytes32 newState = keccak256(abi.encode(state(), msg.data)); - /// @solidity memory-safe-assembly - assembly { - sstore(_ERC6551_STATE_SLOT, newState) - } - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC6551Registry.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC6551Registry.sol deleted file mode 100644 index adf981d..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC6551Registry.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC6551Registry { - function createAccount( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) external returns (address) { - assembly { - // Memory Layout: - // ---- - // 0x00 0xff (1 byte) - // 0x01 registry (address) (20 bytes) - // 0x15 salt (bytes32) (32 bytes) - // 0x35 Bytecode Hash (bytes32) (32 bytes) - // ---- - // 0x55 ERC-1167 Constructor + Header (20 bytes) - // 0x69 implementation (address) (20 bytes) - // 0x5D ERC-1167 Footer (15 bytes) - // 0x8C salt (uint256) (32 bytes) - // 0xAC chainId (uint256) (32 bytes) - // 0xCC tokenContract (address) (32 bytes) - // 0xEC tokenId (uint256) (32 bytes) - - // Silence unused variable warnings - pop(chainId) - - // Copy bytecode + constant data to memory - calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId - mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer - mstore(0x5d, implementation) // implementation - mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header - - // Copy create2 computation data to memory - mstore8(0x00, 0xff) // 0xFF - mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytedcode) - mstore(0x01, shl(96, address())) // registry address - mstore(0x15, salt) // salt - - // Compute account address - let computed := keccak256(0x00, 0x55) - - // If the account has not yet been deployed - if iszero(extcodesize(computed)) { - // Deploy account contract - let deployed := create2(0, 0x55, 0xb7, salt) - - // Revert if the deployment fails - if iszero(deployed) { - mstore(0x00, 0x20188a59) // `AccountCreationFailed()` - revert(0x1c, 0x04) - } - - // Store account address in memory before salt and chainId - mstore(0x6c, deployed) - - // Emit the ERC6551AccountCreated event - log4( - 0x6c, - 0x60, - // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)` - 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722, - implementation, - tokenContract, - tokenId - ) - - // Return the account address - return(0x6c, 0x20) - } - - // Otherwise, return the computed account address - mstore(0x00, shr(96, shl(96, computed))) - return(0x00, 0x20) - } - } - - function account( - address implementation, - bytes32 salt, - uint256 chainId, - address tokenContract, - uint256 tokenId - ) external view returns (address) { - assembly { - // Silence unused variable warnings - pop(chainId) - pop(tokenContract) - pop(tokenId) - - // Copy bytecode + constant data to memory - calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId - mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer - mstore(0x5d, implementation) // implementation - mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header - - // Copy create2 computation data to memory - mstore8(0x00, 0xff) // 0xFF - mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytedcode) - mstore(0x01, shl(96, address())) // registry address - mstore(0x15, salt) // salt - - // Store computed account address in memory - mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55)))) - - // Return computed account address - return(0x00, 0x20) - } - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC6909.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC6909.sol deleted file mode 100644 index 9d5df37..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC6909.sol +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC6909} from "../../../src/tokens/ERC6909.sol"; -import {LibString} from "../../../src/utils/LibString.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC6909 is ERC6909, Brutalizer { - error TokenDoesNotExist(); - - function name(uint256) public view virtual override returns (string memory) { - return "Solady Token"; - } - - function symbol(uint256) public view virtual override returns (string memory) { - return "ST"; - } - - function tokenURI(uint256 id) public view virtual override returns (string memory) { - return string(abi.encodePacked("http://solady.org/", LibString.toString(id))); - } - - function mint(address to, uint256 id, uint256 amount) public payable virtual { - _mint(_brutalized(to), id, amount); - } - - function burn(address from, uint256 id, uint256 amount) public payable virtual { - _burn(_brutalized(from), id, amount); - } - - function approve(address spender, uint256 id, uint256 amount) - public - payable - virtual - override - returns (bool) - { - return super.approve(_brutalized(spender), id, amount); - } - - function setOperator(address owner, bool approved) - public - payable - virtual - override - returns (bool) - { - /// @solidity memory-safe-assembly - assembly { - approved := mul(gas(), approved) - } - return super.setOperator(_brutalized(owner), approved); - } - - function transfer(address to, uint256 id, uint256 amount) - public - payable - virtual - override - returns (bool) - { - return super.transfer(_brutalized(to), id, amount); - } - - function transferFrom(address from, address to, uint256 id, uint256 amount) - public - payable - virtual - override - returns (bool) - { - return super.transferFrom(_brutalized(from), _brutalized(to), id, amount); - } - - function directTransferFrom(address by, address from, address to, uint256 id, uint256 amount) - public - payable - virtual - { - _transfer(_brutalized(by), _brutalized(from), _brutalized(to), id, amount); - } - - function directSetOperator(address owner, address operator, bool approved) - public - payable - virtual - { - /// @solidity memory-safe-assembly - assembly { - approved := mul(gas(), approved) - } - _setOperator(owner, operator, approved); - } - - function directApprove(address owner, address spender, uint256 id, uint256 amount) - public - payable - virtual - { - _approve(owner, spender, id, amount); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC721.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC721.sol deleted file mode 100644 index 1600586..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC721.sol +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC721} from "../../../src/tokens/ERC721.sol"; -import {LibString} from "../../../src/utils/LibString.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC721 is ERC721, Brutalizer { - function name() public view virtual override returns (string memory) { - return "TEST NFT"; - } - - function symbol() public view virtual override returns (string memory) { - return "TEST"; - } - - function tokenURI(uint256 id) public view virtual override returns (string memory) { - if (!_exists(id)) revert TokenDoesNotExist(); - return string(abi.encodePacked("https://remilio.org/remilio/json/", LibString.toString(id))); - } - - function exists(uint256 id) public view virtual returns (bool) { - return _exists(id); - } - - function mint(address to, uint256 id) public virtual { - _mint(_brutalized(to), id); - } - - function mintWithExtraDataUnchecked(address to, uint256 id, uint96 value) public virtual { - _mintAndSetExtraDataUnchecked(_brutalized(to), id, _brutalizedUint96(value)); - } - - function burn(uint256 id) public virtual { - _burn(msg.sender, id); - } - - function uncheckedBurn(uint256 id) public virtual { - _burn(id); - } - - function safeMint(address to, uint256 id) public virtual { - _safeMint(_brutalized(to), id); - } - - function safeMint(address to, uint256 id, bytes calldata data) public virtual { - _safeMint(_brutalized(to), id, data); - } - - function getExtraData(uint256 id) public view virtual returns (uint96) { - return _getExtraData(id); - } - - function setExtraData(uint256 id, uint96 value) public virtual { - _setExtraData(id, value); - } - - function getAux(address owner) public view virtual returns (uint224) { - return _getAux(_brutalized(owner)); - } - - function setAux(address owner, uint224 value) public virtual { - _setAux(_brutalized(owner), value); - } - - function approve(address account, uint256 id) public payable virtual override { - super.approve(_brutalized(account), id); - } - - function directApprove(address account, uint256 id) public virtual { - if (!_isApprovedOrOwner(_brutalized(msg.sender), id)) revert NotOwnerNorApproved(); - _approve(_brutalized(account), id); - } - - function setApprovalForAll(address operator, bool approved) public virtual override { - super.setApprovalForAll(_brutalized(operator), approved); - } - - function directSetApprovalForAll(address operator, bool approved) public virtual { - _setApprovalForAll(_brutalized(msg.sender), _brutalized(operator), approved); - } - - function transferFrom(address from, address to, uint256 id) public payable virtual override { - super.transferFrom(_brutalized(from), _brutalized(to), id); - } - - function uncheckedTransferFrom(address from, address to, uint256 id) public payable virtual { - _transfer(_brutalized(address(0)), _brutalized(from), _brutalized(to), id); - } - - function directTransferFrom(address from, address to, uint256 id) public virtual { - _transfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id); - } - - function safeTransferFrom(address from, address to, uint256 id) - public - payable - virtual - override - { - super.safeTransferFrom(_brutalized(from), _brutalized(to), id); - } - - function directSafeTransferFrom(address from, address to, uint256 id) public virtual { - _safeTransfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id); - } - - function safeTransferFrom(address from, address to, uint256 id, bytes calldata data) - public - payable - virtual - override - { - super.safeTransferFrom(_brutalized(from), _brutalized(to), id, data); - } - - function directSafeTransferFrom(address from, address to, uint256 id, bytes calldata data) - public - virtual - { - _safeTransfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id, data); - } - - function isApprovedOrOwner(address account, uint256 id) public view virtual returns (bool) { - return _isApprovedOrOwner(_brutalized(account), id); - } - - function directOwnerOf(uint256 id) public view virtual returns (address) { - if (!_exists(id)) revert TokenDoesNotExist(); - return _ownerOf(id); - } - - function directGetApproved(uint256 id) public view virtual returns (address) { - if (!_exists(id)) revert TokenDoesNotExist(); - return _getApproved(id); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockERC7821.sol b/grouperBot/lib/solady/test/utils/mocks/MockERC7821.sol deleted file mode 100644 index 7c8d228..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockERC7821.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC7821} from "../../../src/accounts/ERC7821.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC7821 is ERC7821, Brutalizer { - bytes public lastOpData; - - mapping(address => bool) public isAuthorizedCaller; - - error Unauthorized(); - - function _execute(bytes32, bytes calldata, Call[] calldata calls, bytes calldata opData) - internal - virtual - override - { - lastOpData = opData; - _execute(calls, bytes32(0)); - } - - function execute(bytes32 mode, bytes calldata executionData) public payable virtual override { - if (!isAuthorizedCaller[msg.sender]) revert Unauthorized(); - super.execute(mode, executionData); - } - - function executeDirect(Call[] calldata calls) public payable virtual { - _misalignFreeMemoryPointer(); - _brutalizeMemory(); - _execute(calls, bytes32(0)); - _checkMemory(); - } - - function setAuthorizedCaller(address target, bool status) public { - isAuthorizedCaller[target] = status; - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockETHRecipient.sol b/grouperBot/lib/solady/test/utils/mocks/MockETHRecipient.sol deleted file mode 100644 index b4012a7..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockETHRecipient.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockETHRecipient { - bool public immutable gasGriefUponReceiveETH; - - bool public immutable updateCounterUponReceiveETH; - - uint256 public counter; - - uint256 public garbage; - - constructor(bool updateCounterUponReceiveETH_, bool gasGriefUponReceiveETH_) { - updateCounterUponReceiveETH = updateCounterUponReceiveETH_; - gasGriefUponReceiveETH = gasGriefUponReceiveETH_; - } - - receive() external payable { - if (updateCounterUponReceiveETH) { - counter += 1; - } - if (gasGriefUponReceiveETH) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, timestamp()) - mstore(0x20, 0) - - for { let i := 0 } lt(i, 10) { i := add(i, 1) } { - let h := keccak256(0x00, 0x40) - mstore(0x00, sload(h)) - mstore(0x20, i) - sstore(add(h, 1), h) - } - sstore(garbage.slot, keccak256(0x00, 0x40)) - } - } - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockEntryPoint.sol b/grouperBot/lib/solady/test/utils/mocks/MockEntryPoint.sol deleted file mode 100644 index af2b8df..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockEntryPoint.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC4337} from "../../../src/accounts/ERC4337.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockEntryPoint { - mapping(address => uint256) public balanceOf; - - function depositTo(address to) public payable { - balanceOf[to] += msg.value; - } - - function withdrawTo(address to, uint256 amount) public payable { - balanceOf[msg.sender] -= amount; - (bool success,) = payable(to).call{value: amount}(""); - require(success); - } - - function validateUserOp( - address account, - ERC4337.PackedUserOperation memory userOp, - bytes32 userOpHash, - uint256 missingAccountFunds - ) public payable returns (uint256 validationData) { - validationData = - ERC4337(payable(account)).validateUserOp(userOp, userOpHash, missingAccountFunds); - } - - receive() external payable { - depositTo(msg.sender); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockEnumerableRoles.sol b/grouperBot/lib/solady/test/utils/mocks/MockEnumerableRoles.sol deleted file mode 100644 index 03bd701..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockEnumerableRoles.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {EnumerableRoles} from "../../../src/auth/EnumerableRoles.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockEnumerableRoles is EnumerableRoles, Brutalizer { - struct MockEnumerableRolesStorage { - uint256 maxRole; - bool maxRoleReverts; - address owner; - bool ownerReverts; - bytes allowedRolesEncoded; - uint256 allowedRole; - } - - event Yo(); - - MockEnumerableRolesStorage internal $; - - function setOwner(address value) public { - $.owner = value; - } - - function setOwnerReverts(bool value) public { - $.ownerReverts = value; - } - - function setMaxRole(uint256 value) public { - $.maxRole = value; - } - - function setMaxRoleReverts(bool value) public { - $.maxRoleReverts = value; - } - - function MAX_ROLE() public view returns (uint256) { - if ($.maxRoleReverts) revert(); - return $.maxRole; - } - - function owner() public view returns (address) { - if ($.ownerReverts) revert(); - return $.owner; - } - - function setRoleDirect(address holder, uint256 role, bool active) public { - _setRole(_brutalized(holder), role, active); - } - - function hasAnyRoles(address holder, bytes memory encodedRoles) public view returns (bool) { - return _hasAnyRoles(_brutalized(holder), encodedRoles); - } - - function setAllowedRolesEncoded(bytes memory value) public { - $.allowedRolesEncoded = value; - } - - function setAllowedRole(uint256 role) public { - $.allowedRole = role; - } - - function guardedByOnlyOwnerOrRoles() public onlyOwnerOrRoles($.allowedRolesEncoded) { - emit Yo(); - } - - function guardedByOnlyOwnerOrRole() public onlyOwnerOrRole($.allowedRole) { - emit Yo(); - } - - function guardedByOnlyRoles() public onlyRoles($.allowedRolesEncoded) { - emit Yo(); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockImplementation.sol b/grouperBot/lib/solady/test/utils/mocks/MockImplementation.sol deleted file mode 100644 index 59ba351..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockImplementation.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockImplementation { - error Fail(); - - mapping(uint256 => uint256) internal _values; - - function fails() external pure { - revert Fail(); - } - - function succeeds(uint256 a) external pure returns (uint256) { - return a; - } - - function setValue(uint256 key, uint256 value) external payable { - _values[key] = value; - } - - function getValue(uint256 key) external view returns (uint256) { - return _values[key]; - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockInitializable.sol b/grouperBot/lib/solady/test/utils/mocks/MockInitializable.sol deleted file mode 100644 index 0cba983..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockInitializable.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Initializable} from "../../../src/utils/Initializable.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockInitializable is Initializable { - uint256 public x; - uint256 public y; - - struct Args { - uint256 x; - uint64 version; - bool disableInitializers; - bool initializeMulti; - bool checkOnlyDuringInitializing; - bool recurse; - } - - constructor(Args memory a) { - if (a.initializeMulti) { - require(_getInitializedVersion() == 0, "The version should be zero."); - require(!_isInitializing(), "Initializing should be false."); - initialize(a); - require(_getInitializedVersion() == 1, "The version should be one."); - require(!_isInitializing(), "Initializing should be false."); - initialize(a); - require(_getInitializedVersion() == 1, "The version should be one."); - require(!_isInitializing(), "Initializing should be false."); - } - if (a.disableInitializers) { - _disableInitializers(); - } - } - - function initialize(Args memory a) public initializer { - x = a.x; - if (a.checkOnlyDuringInitializing) { - onlyDuringInitializing(); - } - if (a.recurse) { - a.recurse = false; - if (a.x & 1 == 0) initialize(a); - else reinitialize(a); - } - } - - function reinitialize(Args memory a) public reinitializer(a.version) { - x = a.x; - if (a.checkOnlyDuringInitializing) { - onlyDuringInitializing(); - } - if (a.recurse) { - a.recurse = false; - if (a.x & 1 == 0) initialize(a); - else reinitialize(a); - } - } - - function version() external view returns (uint64) { - return _getInitializedVersion(); - } - - function isInitializing() external view returns (bool) { - return _isInitializing(); - } - - function onlyDuringInitializing() public onlyInitializing { - require(_getInitializedVersion() != 0, "The version should not be zero."); - require(_isInitializing(), "Initializing should be true."); - unchecked { - ++y; - } - } - - function disableInitializers() public { - _disableInitializers(); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockLifebuoy.sol b/grouperBot/lib/solady/test/utils/mocks/MockLifebuoy.sol deleted file mode 100644 index c01c4b4..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockLifebuoy.sol +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Ownable} from "../../../src/auth/Ownable.sol"; -import {Lifebuoy} from "../../../src/utils/Lifebuoy.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockLifebuoy is Lifebuoy, Brutalizer { - constructor() payable {} - - function rescueETH(address to, uint256 amount) public payable virtual override { - _brutalizeScratchSpace(); - super.rescueETH(_brutalized(to), amount); - _checkMemory(); - } - - function rescueERC20(address token, address to, uint256 amount) - public - payable - virtual - override - { - _brutalizeScratchSpace(); - super.rescueERC20(_brutalized(token), _brutalized(to), amount); - _checkMemory(); - } - - function rescueERC721(address token, address to, uint256 tokenId) - public - payable - virtual - override - { - _brutalizeScratchSpace(); - super.rescueERC721(_brutalized(token), _brutalized(to), tokenId); - _checkMemory(); - } - - function rescueERC1155( - address token, - address to, - uint256 tokenId, - uint256 amount, - bytes calldata data - ) public payable virtual override { - _brutalizeScratchSpace(); - super.rescueERC1155(_brutalized(token), _brutalized(to), tokenId, amount, data); - _checkMemory(); - } - - function rescueERC6909(address token, address to, uint256 tokenId, uint256 amount) - public - payable - virtual - override - { - _brutalizeScratchSpace(); - super.rescueERC6909(_brutalized(token), _brutalized(to), tokenId, amount); - _checkMemory(); - } - - function onERC1155Received(address, address, uint256, uint256, bytes calldata) - external - virtual - returns (bytes4) - { - return MockLifebuoy.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual returns (bytes4) { - return MockLifebuoy.onERC1155BatchReceived.selector; - } -} - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockLifebuoyOwned is MockLifebuoy, Ownable { - constructor(address owner_) payable { - _initializeOwner(owner_); - } - - function initializeOwner(address owner_) external { - _initializeOwner(owner_); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockMulticallable.sol b/grouperBot/lib/solady/test/utils/mocks/MockMulticallable.sol deleted file mode 100644 index 133398e..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockMulticallable.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Multicallable} from "../../../src/utils/Multicallable.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockMulticallable is Multicallable, Brutalizer { - error CustomError(); - - struct Tuple { - uint256 a; - uint256 b; - } - - function revertsWithString(string memory e) external pure { - revert(e); - } - - function revertsWithCustomError() external pure { - revert CustomError(); - } - - function revertsWithNothing() external pure { - revert(); - } - - function returnsTuple(uint256 a, uint256 b) external pure returns (Tuple memory tuple) { - tuple = Tuple({a: a, b: b}); - } - - function returnsString(string calldata s) external pure returns (string memory) { - return s; - } - - function returnsRandomizedString(string calldata s) external pure returns (string memory) { - /// @solidity memory-safe-assembly - assembly { - let m := add(mload(0x40), 0x20) - calldatacopy(m, s.offset, s.length) - mstore(0x20, keccak256(m, s.length)) - let v := keccak256(m, add(s.length, 1)) - let n := and(mload(0x20), 0x1ff) - mstore(0x00, 0) - for { let i := 0 } lt(i, n) {} { - mstore(add(m, i), v) - mstore(0x00, add(1, mload(0x00))) - i := add(i, and(keccak256(0x00, 0x40), 0x3f)) - } - mstore(m, n) - mstore(sub(m, 0x20), 0x20) - return(sub(m, 0x20), add(n, 0x60)) - } - } - - uint256 public paid; - - function pay() external payable { - paid += msg.value; - } - - function returnsSender() external view returns (address) { - return msg.sender; - } - - function multicallBrutalized(bytes[] calldata data) public returns (bytes[] memory results) { - _brutalizeMemory(); - results = _multicallResultsToBytesArray(_multicall(data)); - _checkMemory(); - } - - function multicallOriginal(bytes[] calldata data) - public - payable - returns (bytes[] memory results) - { - unchecked { - results = new bytes[](data.length); - for (uint256 i = 0; i < data.length; i++) { - (bool success, bytes memory result) = address(this).delegatecall(data[i]); - if (!success) { - // Next 5 lines from https://ethereum.stackexchange.com/a/83577 - if (result.length < 68) revert(); - /// @solidity memory-safe-assembly - assembly { - result := add(result, 0x04) - } - revert(abi.decode(result, (string))); - } - results[i] = result; - } - } - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockOwnable.sol b/grouperBot/lib/solady/test/utils/mocks/MockOwnable.sol deleted file mode 100644 index 350efa4..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockOwnable.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Ownable} from "../../../src/auth/Ownable.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockOwnable is Ownable, Brutalizer { - bool public flag; - - constructor() payable { - _initializeOwner(msg.sender); - } - - function initializeOwnerDirect(address newOwner) public payable { - _initializeOwner(_brutalized(newOwner)); - } - - function setOwnerDirect(address newOwner) public payable { - _setOwner(_brutalized(newOwner)); - } - - function completeOwnershipHandover(address pendingOwner) public payable virtual override { - super.completeOwnershipHandover(_brutalized(pendingOwner)); - } - - function transferOwnership(address newOwner) public payable virtual override { - super.transferOwnership(_brutalized(newOwner)); - } - - function ownershipHandoverExpiresAt(address pendingOwner) - public - view - virtual - override - returns (uint256 result) - { - result = super.ownershipHandoverExpiresAt(_brutalized(pendingOwner)); - } - - function ownershipHandoverValidFor() public view returns (uint64 result) { - result = _ownershipHandoverValidFor(); - /// @solidity memory-safe-assembly - assembly { - // Some acrobatics to make the brutalized bits pseudorandomly - // different with every call. - mstore(0x00, or(calldataload(0), mload(0x40))) - mstore(0x20, or(caller(), mload(0x00))) - // Just brutalize the upper unused bits of the result to see if it causes any issue. - result := or(shl(64, keccak256(0x00, 0x40)), result) - mstore(0x40, add(0x20, mload(0x40))) - mstore(0x00, result) - } - } - - function updateFlagWithOnlyOwner() public payable onlyOwner { - flag = true; - } -} - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockOwnableBytecodeSizer is Ownable { - constructor() payable { - initialize(); - } - - function initialize() public payable { - _initializeOwner(msg.sender); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockOwnableRoles.sol b/grouperBot/lib/solady/test/utils/mocks/MockOwnableRoles.sol deleted file mode 100644 index 03668e9..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockOwnableRoles.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Ownable, OwnableRoles} from "../../../src/auth/OwnableRoles.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockOwnableRoles is OwnableRoles, Brutalizer { - bool public flag; - - constructor() payable { - _initializeOwner(msg.sender); - } - - function initializeOwnerDirect(address newOwner) public payable { - _initializeOwner(_brutalized(newOwner)); - } - - function setOwnerDirect(address newOwner) public payable { - _setOwner(_brutalized(newOwner)); - } - - function setRolesDirect(address user, uint256 roles) public payable { - _setRoles(_brutalized(user), roles); - } - - function grantRolesDirect(address user, uint256 roles) public payable { - _grantRoles(_brutalized(user), roles); - } - - function removeRolesDirect(address user, uint256 roles) public payable { - _removeRoles(_brutalized(user), roles); - } - - function grantRoles(address user, uint256 roles) public payable virtual override { - super.grantRoles(_brutalized(user), roles); - } - - function revokeRoles(address user, uint256 roles) public payable virtual override { - super.revokeRoles(_brutalized(user), roles); - } - - function completeOwnershipHandover(address pendingOwner) public payable virtual override { - super.completeOwnershipHandover(_brutalized(pendingOwner)); - } - - function transferOwnership(address newOwner) public payable virtual override { - super.transferOwnership(_brutalized(newOwner)); - } - - function rolesOf(address user) public view virtual override returns (uint256 result) { - result = super.rolesOf(_brutalized(user)); - } - - function ownershipHandoverExpiresAt(address pendingOwner) - public - view - virtual - override - returns (uint256 result) - { - result = super.ownershipHandoverExpiresAt(_brutalized(pendingOwner)); - } - - function ownershipHandoverValidFor() public view returns (uint64 result) { - result = _ownershipHandoverValidFor(); - /// @solidity memory-safe-assembly - assembly { - // Some acrobatics to make the brutalized bits pseudorandomly - // different with every call. - mstore(0x00, or(calldataload(0), mload(0x40))) - mstore(0x20, or(caller(), mload(0x00))) - // Just brutalize the upper unused bits of the result to see if it causes any issue. - result := or(shl(64, keccak256(0x00, 0x40)), result) - mstore(0x40, add(0x20, mload(0x40))) - mstore(0x00, result) - } - } - - function updateFlagWithOnlyOwner() public payable onlyOwner { - flag = true; - } - - function updateFlagWithOnlyRoles(uint256 roles) public payable onlyRoles(roles) { - flag = true; - } - - function updateFlagWithOnlyOwnerOrRoles(uint256 roles) public payable onlyOwnerOrRoles(roles) { - flag = true; - } - - function updateFlagWithOnlyRolesOrOwner(uint256 roles) public payable onlyRolesOrOwner(roles) { - flag = true; - } - - function rolesFromOrdinals(uint8[] memory ordinals) public pure returns (uint256 roles) { - roles = _rolesFromOrdinals(ordinals); - } - - function ordinalsFromRoles(uint256 roles) public pure returns (uint8[] memory ordinals) { - ordinals = _ordinalsFromRoles(roles); - } - - function _checkedBool(bool value) private pure returns (bool result) { - result = value; - bool resultIsOneOrZero; - /// @solidity memory-safe-assembly - assembly { - // We wanna check if the result is either 1 or 0, - // to make sure we practice good assembly politeness. - resultIsOneOrZero := lt(result, 2) - } - if (!resultIsOneOrZero) result = !result; - } -} - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockOwnableRolesBytecodeSizer is OwnableRoles { - constructor() payable { - initialize(); - } - - function initialize() public payable { - _initializeOwner(msg.sender); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockReceiver.sol b/grouperBot/lib/solady/test/utils/mocks/MockReceiver.sol deleted file mode 100644 index 77cd523..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockReceiver.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {Receiver} from "../../../src/accounts/Receiver.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockReceiver is Receiver {} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockReentrancyGuard.sol b/grouperBot/lib/solady/test/utils/mocks/MockReentrancyGuard.sol deleted file mode 100644 index 156f238..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockReentrancyGuard.sol +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ReentrancyGuard} from "../../../src/utils/ReentrancyGuard.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockReentrancyGuard is ReentrancyGuard { - /// @dev SEE: `ReentrancyGuard`. - uint256 public constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268; - - uint256 public enterTimes; - - // Mocks - - function isReentrancyGuardLocked() public view returns (bool locked) { - /// @solidity memory-safe-assembly - assembly { - if eq(sload(_REENTRANCY_GUARD_SLOT), address()) { locked := true } - } - } - - function callUnguardedToGuarded() public { - callbackTargetGuarded(); - } - - function callUnguardedToUnguarded() public { - callbackTargetUnguarded(); - } - - function callGuardedToGuarded() public nonReentrant { - callbackTargetGuarded(); - } - - function callGuardedToUnguarded() public nonReentrant { - callbackTargetUnguarded(); - } - - function callGuardedToReadGuarded() public nonReentrant { - readCallbackTargetGuarded(); - } - - function callUnguardedToReadGuarded() public { - readCallbackTargetGuarded(); - } - - // Targets - - /// @dev Callback target without a reentrancy guard. - function callbackTargetUnguarded() public { - enterTimes++; - } - - /// @dev Callback target with a reentrancy guard. - function callbackTargetGuarded() public nonReentrant { - enterTimes++; - } - - /// @dev Callback target with a non-read reentrancy guard. - function readCallbackTargetGuarded() public nonReadReentrant { - enterTimes++; - } - - // Recursion - - function countUnguardedDirectRecursive(uint256 recursion) public { - _recurseDirect(false, recursion); - } - - function countGuardedDirectRecursive(uint256 recursion) public nonReentrant { - _recurseDirect(true, recursion); - } - - function countUnguardedIndirectRecursive(uint256 recursion) public { - _recurseIndirect(false, recursion); - } - - function countGuardedIndirectRecursive(uint256 recursion) public nonReentrant { - _recurseIndirect(true, recursion); - } - - function countAndCall(ReentrancyAttack attacker) public nonReentrant { - enterTimes++; - attacker.callSender(bytes4(keccak256("callbackTargetGuarded()"))); - } - - // Helpers - - function _recurseDirect(bool guarded, uint256 recursion) private { - if (recursion > 0) { - enterTimes++; - - if (guarded) { - countGuardedDirectRecursive(recursion - 1); - } else { - countUnguardedDirectRecursive(recursion - 1); - } - } - } - - function _recurseIndirect(bool guarded, uint256 recursion) private { - if (recursion > 0) { - enterTimes++; - - (bool success, bytes memory data) = address(this).call( - abi.encodeWithSignature( - guarded - ? "countGuardedIndirectRecursive(uint256)" - : "countUnguardedIndirectRecursive(uint256)", - recursion - 1 - ) - ); - - if (!success) { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, data), mload(data)) - } - } - } - } -} - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract ReentrancyAttack { - /// @dev Reverts on a failed reentrancy attack. - error ReentrancyAttackFailed(); - - /// @dev Call the msg.sender with the given data to perform a reentrancy attack. - function callSender(bytes4 data) external { - (bool success,) = msg.sender.call(abi.encodeWithSelector(data)); - - if (!success) revert ReentrancyAttackFailed(); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockReentrancyGuardTransient.sol b/grouperBot/lib/solady/test/utils/mocks/MockReentrancyGuardTransient.sol deleted file mode 100644 index 18d6430..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockReentrancyGuardTransient.sol +++ /dev/null @@ -1,146 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import {ReentrancyGuardTransient} from "../../../src/utils/ReentrancyGuardTransient.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockReentrancyGuardTransient is ReentrancyGuardTransient { - /// @dev SEE: `ReentrancyGuardTransient`. - uint256 public constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268; - - uint256 public enterTimes; - - bool public transientOnlyOnMainnet; - - // Mocks - - function isReentrancyGuardLocked() public view returns (bool locked) { - /// @solidity memory-safe-assembly - assembly { - if tload(_REENTRANCY_GUARD_SLOT) { locked := true } - } - } - - function callUnguardedToGuarded() public { - callbackTargetGuarded(); - } - - function callUnguardedToUnguarded() public { - callbackTargetUnguarded(); - } - - function callGuardedToGuarded() public nonReentrant { - callbackTargetGuarded(); - } - - function callGuardedToUnguarded() public nonReentrant { - callbackTargetUnguarded(); - } - - function callGuardedToReadGuarded() public nonReentrant { - readCallbackTargetGuarded(); - } - - function callUnguardedToReadGuarded() public { - readCallbackTargetGuarded(); - } - - function setTransientOnlyOnMainnet(bool value) public { - transientOnlyOnMainnet = value; - } - - function _useTransientReentrancyGuardOnlyOnMainnet() internal view override returns (bool) { - return transientOnlyOnMainnet; - } - - // Targets - - /// @dev Callback target without a reentrancy guard. - function callbackTargetUnguarded() public { - enterTimes++; - } - - /// @dev Callback target with a reentrancy guard. - function callbackTargetGuarded() public nonReentrant { - enterTimes++; - } - - /// @dev Callback target with a non-read reentrancy guard. - function readCallbackTargetGuarded() public nonReadReentrant { - enterTimes++; - } - - // Recursion - - function countUnguardedDirectRecursive(uint256 recursion) public { - _recurseDirect(false, recursion); - } - - function countGuardedDirectRecursive(uint256 recursion) public nonReentrant { - _recurseDirect(true, recursion); - } - - function countUnguardedIndirectRecursive(uint256 recursion) public { - _recurseIndirect(false, recursion); - } - - function countGuardedIndirectRecursive(uint256 recursion) public nonReentrant { - _recurseIndirect(true, recursion); - } - - function countAndCall(ReentrancyAttack attacker) public nonReentrant { - enterTimes++; - attacker.callSender(bytes4(keccak256("callbackTargetGuarded()"))); - } - - // Helpers - - function _recurseDirect(bool guarded, uint256 recursion) private { - if (recursion > 0) { - enterTimes++; - - if (guarded) { - countGuardedDirectRecursive(recursion - 1); - } else { - countUnguardedDirectRecursive(recursion - 1); - } - } - } - - function _recurseIndirect(bool guarded, uint256 recursion) private { - if (recursion > 0) { - enterTimes++; - - (bool success, bytes memory data) = address(this).call( - abi.encodeWithSignature( - guarded - ? "countGuardedIndirectRecursive(uint256)" - : "countUnguardedIndirectRecursive(uint256)", - recursion - 1 - ) - ); - - if (!success) { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, data), mload(data)) - } - } - } - } -} - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract ReentrancyAttack { - /// @dev Reverts on a failed reentrancy attack. - error ReentrancyAttackFailed(); - - /// @dev Call the msg.sender with the given data to perform a reentrancy attack. - function callSender(bytes4 data) external { - (bool success,) = msg.sender.call(abi.encodeWithSelector(data)); - - if (!success) revert ReentrancyAttackFailed(); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockTimedRoles.sol b/grouperBot/lib/solady/test/utils/mocks/MockTimedRoles.sol deleted file mode 100644 index b178bd2..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockTimedRoles.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {TimedRoles} from "../../../src/auth/TimedRoles.sol"; -import {EnumerableRoles} from "../../../src/auth/EnumerableRoles.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockTimedRoles is TimedRoles, EnumerableRoles, Brutalizer { - struct MockTimedRolesStorage { - uint256 maxTimedRole; - bool maxTimedRoleReverts; - address owner; - bool ownerReverts; - bytes allowedTimedRolesEncoded; - uint256 allowedTimedRole; - } - - event Yo(); - - MockTimedRolesStorage internal $; - - function setOwner(address value) public { - $.owner = value; - } - - function setOwnerReverts(bool value) public { - $.ownerReverts = value; - } - - function setMaxTimedRole(uint256 value) public { - $.maxTimedRole = value; - } - - function setMaxTimedRoleReverts(bool value) public { - $.maxTimedRoleReverts = value; - } - - function MAX_TIMED_ROLE() public view returns (uint256) { - if ($.maxTimedRoleReverts) revert(); - return $.maxTimedRole; - } - - function owner() public view returns (address) { - if ($.ownerReverts) revert(); - return $.owner; - } - - function setTimedRoleDirect(address holder, uint256 timedRole, uint40 start, uint40 end) - public - { - _setTimedRole(_brutalized(holder), timedRole, start, end); - } - - function hasAnyTimedRoles(address holder, bytes memory encodedTimedRoles) - public - view - returns (bool) - { - return _hasAnyTimedRoles(_brutalized(holder), encodedTimedRoles); - } - - function setAllowedTimedRolesEncoded(bytes memory value) public { - $.allowedTimedRolesEncoded = value; - } - - function setAllowedTimedRole(uint256 timedRole) public { - $.allowedTimedRole = timedRole; - } - - function guardedByOnlyOwnerOrTimedRoles() - public - onlyOwnerOrTimedRoles($.allowedTimedRolesEncoded) - { - emit Yo(); - } - - function guardedByOnlyOwnerOrTimedRole() public onlyOwnerOrTimedRole($.allowedTimedRole) { - emit Yo(); - } - - function guardedByOnlyTimedRoles() public onlyTimedRoles($.allowedTimedRolesEncoded) { - emit Yo(); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/MockUUPSImplementation.sol b/grouperBot/lib/solady/test/utils/mocks/MockUUPSImplementation.sol deleted file mode 100644 index 0d379f0..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/MockUUPSImplementation.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {UUPSUpgradeable} from "../../../src/utils/UUPSUpgradeable.sol"; -import {Brutalizer} from "../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockUUPSImplementation is UUPSUpgradeable, Brutalizer { - uint256 public value; - - address public owner; - - error Unauthorized(); - - error CustomError(address owner_); - - function initialize(address owner_) public { - owner = owner_; - } - - modifier onlyOwner() { - if (msg.sender != owner) revert Unauthorized(); - _; - } - - function _authorizeUpgrade(address) internal override onlyOwner {} - - function revertWithError() public view { - revert CustomError(owner); - } - - function setValue(uint256 val_) public { - value = val_; - } - - function upgradeToAndCall(address newImplementation, bytes calldata data) - public - payable - override - { - super.upgradeToAndCall(_brutalized(newImplementation), data); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/ext/zksync/MockERC1155.sol b/grouperBot/lib/solady/test/utils/mocks/ext/zksync/MockERC1155.sol deleted file mode 100644 index a90ce6e..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/ext/zksync/MockERC1155.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC1155} from "../../../../../src/tokens/ext/zksync/ERC1155.sol"; -import {Brutalizer} from "../../../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC1155 is ERC1155, Brutalizer { - bytes32 public lastDataHash; - - function uri(uint256) public pure virtual override returns (string memory) {} - - function mint(address to, uint256 id, uint256 amount, bytes memory data) public virtual { - _mint(_brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function batchMint( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - _batchMint(_brutalized(to), ids, amounts, data); - lastDataHash = keccak256(data); - } - - function burn(address from, uint256 id, uint256 amount) public virtual { - _burn(_brutalized(msg.sender), _brutalized(from), id, amount); - } - - function uncheckedBurn(address from, uint256 id, uint256 amount) public virtual { - _burn(_brutalized(from), id, amount); - } - - function batchBurn(address from, uint256[] memory ids, uint256[] memory amounts) - public - virtual - { - _batchBurn(_brutalized(msg.sender), _brutalized(from), ids, amounts); - } - - function uncheckedBatchBurn(address from, uint256[] memory ids, uint256[] memory amounts) - public - virtual - { - _batchBurn(_brutalized(from), ids, amounts); - } - - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) public virtual override { - super.safeTransferFrom(_brutalized(from), _brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function directSafeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual { - _safeTransfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function uncheckedSafeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual { - _safeTransfer(_brutalized(address(0)), _brutalized(from), _brutalized(to), id, amount, data); - lastDataHash = keccak256(data); - } - - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) public virtual override { - super.safeBatchTransferFrom(_brutalized(from), _brutalized(to), ids, amounts, data); - lastDataHash = keccak256(data); - } - - function directSafeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - _safeBatchTransfer( - _brutalized(msg.sender), _brutalized(from), _brutalized(to), ids, amounts, data - ); - lastDataHash = keccak256(data); - } - - function uncheckedSafeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - _safeBatchTransfer( - _brutalized(address(0)), _brutalized(from), _brutalized(to), ids, amounts, data - ); - lastDataHash = keccak256(data); - } - - function directSetApprovalForAll(address operator, bool approved) public virtual { - _setApprovalForAll(_brutalized(msg.sender), _brutalized(operator), approved); - } -} diff --git a/grouperBot/lib/solady/test/utils/mocks/ext/zksync/MockERC721.sol b/grouperBot/lib/solady/test/utils/mocks/ext/zksync/MockERC721.sol deleted file mode 100644 index 610534f..0000000 --- a/grouperBot/lib/solady/test/utils/mocks/ext/zksync/MockERC721.sol +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import {ERC721} from "../../../../../src/tokens/ext/zksync/ERC721.sol"; -import {LibString} from "../../../../../src/utils/LibString.sol"; -import {Brutalizer} from "../../../Brutalizer.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC721 is ERC721, Brutalizer { - function name() public view virtual override returns (string memory) { - return "TEST NFT"; - } - - function symbol() public view virtual override returns (string memory) { - return "TEST"; - } - - function tokenURI(uint256 id) public view virtual override returns (string memory) { - if (!_exists(id)) revert TokenDoesNotExist(); - return string(abi.encodePacked("https://remilio.org/remilio/json/", LibString.toString(id))); - } - - function exists(uint256 id) public view virtual returns (bool) { - return _exists(id); - } - - function mint(address to, uint256 id) public virtual { - _mint(_brutalized(to), id); - } - - function mintWithExtraDataUnchecked(address to, uint256 id, uint96 value) public virtual { - _mintAndSetExtraDataUnchecked(_brutalized(to), id, _brutalizedUint96(value)); - } - - function burn(uint256 id) public virtual { - _burn(msg.sender, id); - } - - function uncheckedBurn(uint256 id) public virtual { - _burn(id); - } - - function safeMint(address to, uint256 id) public virtual { - _safeMint(_brutalized(to), id); - } - - function safeMint(address to, uint256 id, bytes calldata data) public virtual { - _safeMint(_brutalized(to), id, data); - } - - function getExtraData(uint256 id) public view virtual returns (uint96) { - return _getExtraData(id); - } - - function setExtraData(uint256 id, uint96 value) public virtual { - _setExtraData(id, value); - } - - function getAux(address owner) public view virtual returns (uint224) { - return _getAux(_brutalized(owner)); - } - - function setAux(address owner, uint224 value) public virtual { - _setAux(_brutalized(owner), value); - } - - function approve(address account, uint256 id) public payable virtual override { - super.approve(_brutalized(account), id); - } - - function directApprove(address account, uint256 id) public virtual { - if (!_isApprovedOrOwner(_brutalized(msg.sender), id)) revert NotOwnerNorApproved(); - _approve(_brutalized(account), id); - } - - function setApprovalForAll(address operator, bool approved) public virtual override { - super.setApprovalForAll(_brutalized(operator), approved); - } - - function directSetApprovalForAll(address operator, bool approved) public virtual { - _setApprovalForAll(_brutalized(msg.sender), _brutalized(operator), approved); - } - - function transferFrom(address from, address to, uint256 id) public payable virtual override { - super.transferFrom(_brutalized(from), _brutalized(to), id); - } - - function uncheckedTransferFrom(address from, address to, uint256 id) public payable virtual { - _transfer(_brutalized(address(0)), _brutalized(from), _brutalized(to), id); - } - - function directTransferFrom(address from, address to, uint256 id) public virtual { - _transfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id); - } - - function safeTransferFrom(address from, address to, uint256 id) - public - payable - virtual - override - { - super.safeTransferFrom(_brutalized(from), _brutalized(to), id); - } - - function directSafeTransferFrom(address from, address to, uint256 id) public virtual { - _safeTransfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id); - } - - function safeTransferFrom(address from, address to, uint256 id, bytes calldata data) - public - payable - virtual - override - { - super.safeTransferFrom(_brutalized(from), _brutalized(to), id, data); - } - - function directSafeTransferFrom(address from, address to, uint256 id, bytes calldata data) - public - virtual - { - _safeTransfer(_brutalized(msg.sender), _brutalized(from), _brutalized(to), id, data); - } - - function isApprovedOrOwner(address account, uint256 id) public view virtual returns (bool) { - return _isApprovedOrOwner(_brutalized(account), id); - } - - function directOwnerOf(uint256 id) public view virtual returns (address) { - if (!_exists(id)) revert TokenDoesNotExist(); - return _ownerOf(id); - } - - function directGetApproved(uint256 id) public view virtual returns (address) { - if (!_exists(id)) revert TokenDoesNotExist(); - return _getApproved(id); - } -} diff --git a/grouperBot/lib/solady/test/utils/weird-tokens/MissingReturnToken.sol b/grouperBot/lib/solady/test/utils/weird-tokens/MissingReturnToken.sol deleted file mode 100644 index e07d8bd..0000000 --- a/grouperBot/lib/solady/test/utils/weird-tokens/MissingReturnToken.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract MissingReturnToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "MissingReturnToken"; - - string public constant symbol = "MRT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - } - - function transfer(address to, uint256 amount) public virtual { - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - } - - function transferFrom(address from, address to, uint256 amount) public virtual { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) { - allowance[from][msg.sender] = allowed - amount; - } - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - } -} diff --git a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsFalseToken.sol b/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsFalseToken.sol deleted file mode 100644 index 8dd01de..0000000 --- a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsFalseToken.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract ReturnsFalseToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsFalseToken"; - - string public constant symbol = "RFT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual returns (bool) { - return false; - } - - function transfer(address, uint256) public virtual returns (bool) { - return false; - } - - function transferFrom(address, address, uint256) public virtual returns (bool) { - return false; - } -} diff --git a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsRawBytesToken.sol b/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsRawBytesToken.sol deleted file mode 100644 index 6525990..0000000 --- a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsRawBytesToken.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract ReturnsRawBytesToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsRawBytesToken"; - - string public constant symbol = "RGT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - MOCK STORAGE - //////////////////////////////////////////////////////////////*/ - - bytes rawBytes; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - bytes memory _rawBytes = rawBytes; - - /// @solidity memory-safe-assembly - assembly { - return(add(_rawBytes, 32), mload(_rawBytes)) - } - } - - function transfer(address to, uint256 amount) public virtual { - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - bytes memory _rawBytes = rawBytes; - - /// @solidity memory-safe-assembly - assembly { - return(add(_rawBytes, 32), mload(_rawBytes)) - } - } - - function transferFrom(address from, address to, uint256 amount) public virtual { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) { - allowance[from][msg.sender] = allowed - amount; - } - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - - bytes memory _rawBytes = rawBytes; - - /// @solidity memory-safe-assembly - assembly { - return(add(_rawBytes, 32), mload(_rawBytes)) - } - } - - /*/////////////////////////////////////////////////////////////// - MOCK LOGIC - //////////////////////////////////////////////////////////////*/ - - function setRawBytes(bytes memory _rawBytes) public virtual { - rawBytes = _rawBytes; - } -} diff --git a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTooLittleToken.sol b/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTooLittleToken.sol deleted file mode 100644 index 2c624c1..0000000 --- a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTooLittleToken.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract ReturnsTooLittleToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsTooLittleToken"; - - string public constant symbol = "RTLT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) - return(0, 8) - } - } - - function transfer(address, uint256) public virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) - return(0, 8) - } - } - - function transferFrom(address, address, uint256) public virtual { - /// @solidity memory-safe-assembly - assembly { - mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) - return(0, 8) - } - } -} diff --git a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTooMuchToken.sol b/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTooMuchToken.sol deleted file mode 100644 index 97d16b1..0000000 --- a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTooMuchToken.sol +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract ReturnsTooMuchToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsTooMuchToken"; - - string public constant symbol = "RTMT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - /// @solidity memory-safe-assembly - assembly { - mstore(0, 1) - return(0, 4096) - } - } - - function transfer(address to, uint256 amount) public virtual { - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - /// @solidity memory-safe-assembly - assembly { - mstore(0, 1) - return(0, 4096) - } - } - - function transferFrom(address from, address to, uint256 amount) public virtual { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) { - allowance[from][msg.sender] = allowed - amount; - } - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - - /// @solidity memory-safe-assembly - assembly { - mstore(0, 1) - return(0, 4096) - } - } -} diff --git a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTwoToken.sol b/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTwoToken.sol deleted file mode 100644 index fb88d0d..0000000 --- a/grouperBot/lib/solady/test/utils/weird-tokens/ReturnsTwoToken.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract ReturnsTwoToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsFalseToken"; - - string public constant symbol = "RTT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual returns (uint256) { - return 2; - } - - function transfer(address, uint256) public virtual returns (uint256) { - return 2; - } - - function transferFrom(address, address, uint256) public virtual returns (uint256) { - return 2; - } -} diff --git a/grouperBot/lib/solady/test/utils/weird-tokens/RevertingToken.sol b/grouperBot/lib/solady/test/utils/weird-tokens/RevertingToken.sol deleted file mode 100644 index 17aca18..0000000 --- a/grouperBot/lib/solady/test/utils/weird-tokens/RevertingToken.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -contract RevertingToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "RevertingToken"; - - string public constant symbol = "RT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual { - revert(); - } - - function transfer(address, uint256) public virtual { - revert(); - } - - function transferFrom(address, address, uint256) public virtual { - revert(); - } -} diff --git a/grouperBot/script/add_liquidity.s.sol b/grouperBot/script/add_liquidity.s.sol deleted file mode 100644 index 2aafd5c..0000000 --- a/grouperBot/script/add_liquidity.s.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {Constants} from "./constant.s.sol"; -import {Setup} from "./setup.s.sol"; - -/// @notice Add liquidity to the pool: [mock erc20, usdc] -contract AddLiquidity is Setup, Script { - function run() public { - vm.startBroadcast(deployerPrivateKey); - - uint256 usdcAmount = 100_000000; - uint256 mockTokenAmount = 100_000000000000000000; - - // 1. approve the tokens - Constants.USDC_ADDR.approve(address(Constants.ROUTER_ADDR), usdcAmount); - Constants.MOCK_ERC20_ADDR.approve(address(Constants.ROUTER_ADDR), mockTokenAmount); - - console.log("usdcAmount:", usdcAmount); - console.log("mockTokenAmount:", mockTokenAmount); - console.log("successfully approved"); - - // 2. add liquidity to the pool - Constants.ROUTER_ADDR - .addLiquidity( - address(Constants.USDC_ADDR), - address(Constants.MOCK_ERC20_ADDR), - usdcAmount, - mockTokenAmount, - 0, - 0, - deployer, - block.timestamp + 365 days - ); - console.log("successfully added liquidity!"); - - // 3. print the reserves - (uint256 reserve0, uint256 reserve1,) = Constants.MOCK_POOL_ADDR.getReserves(); - console.log("reserve0:", reserve0); - console.log("reserve1:", reserve1); - - vm.stopBroadcast(); - } -} diff --git a/grouperBot/script/constant.s.sol b/grouperBot/script/constant.s.sol deleted file mode 100644 index 2f6c5f4..0000000 --- a/grouperBot/script/constant.s.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; - -import {IUniswapV2Router02} from "../src/interfaces/IUniswapV2Router02.sol"; -import {IERC20} from "../src/interfaces/IERC20.sol"; -import {IUniswapV2Factory} from "../src/interfaces/IUniswapV2Factory.sol"; -import {IUniswapV2Pair} from "../src/interfaces/IUniswapV2Pair.sol"; -import {GrouperBot} from "../src/GrouperBot.sol"; - -/// @notice Constants for the script -library Constants { - IERC20 public constant USDC_ADDR = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); - IUniswapV2Router02 public constant ROUTER_ADDR = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); - IUniswapV2Factory public constant FACTORY_ADDR = IUniswapV2Factory(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); - - IERC20 public constant MOCK_ERC20_ADDR = IERC20(0x2d493cde51adc74D4494b3dC146759cF32957A23); - IUniswapV2Pair public constant MOCK_POOL_ADDR = IUniswapV2Pair(0xCE1Db75Bc9AaAFCB4c8f85c2605163B8d762B52f); - GrouperBot public constant BOT_ADDR = GrouperBot(payable(0x7fAB7AEAB965240986e42729210Cf6E9Fdf26A5f)); -} diff --git a/grouperBot/script/deploy_bot.s.sol b/grouperBot/script/deploy_bot.s.sol deleted file mode 100644 index ccd1060..0000000 --- a/grouperBot/script/deploy_bot.s.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {GrouperBot} from "../src/GrouperBot.sol"; -import {Setup} from "./setup.s.sol"; - -/// @notice Deploy the grouper bot -contract DeployGrouperBot is Setup, Script { - function run() public { - vm.startBroadcast(deployerPrivateKey); - - GrouperBot grouperBot = new GrouperBot(); - console.log("GrouperBot deployed to:", address(grouperBot)); - - vm.stopBroadcast(); - } -} diff --git a/grouperBot/script/deploy_pool.s.sol b/grouperBot/script/deploy_pool.s.sol deleted file mode 100644 index 99f27b1..0000000 --- a/grouperBot/script/deploy_pool.s.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {MockERC20} from "../test/mockERC20.t.sol"; -import {Setup} from "./setup.s.sol"; -import {Constants} from "./constant.s.sol"; - -/// @notice Deploy a pool in ethereum for testing: [mock erc20, usdc] -contract DeployPool is Setup, Script { - function run() public { - vm.startBroadcast(deployerPrivateKey); - - MockERC20 mockToken = new MockERC20("MockToken", "MTK", 18); - console.log("MockToken address:", address(mockToken)); - console.log("USDC address:", address(Constants.USDC_ADDR)); - - Constants.FACTORY_ADDR.createPair(address(Constants.USDC_ADDR), address(mockToken)); - console.log( - "Pool address:", address(Constants.FACTORY_ADDR.getPair(address(Constants.USDC_ADDR), address(mockToken))) - ); - - vm.stopBroadcast(); - } -} diff --git a/grouperBot/script/setup.s.sol b/grouperBot/script/setup.s.sol deleted file mode 100644 index 41ec54b..0000000 --- a/grouperBot/script/setup.s.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; - -/// @notice Setup the environment -contract Setup { - uint256 public deployerPrivateKey = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; - address public deployer = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; -} diff --git a/grouperBot/script/swap.s.sol b/grouperBot/script/swap.s.sol deleted file mode 100644 index 3434a2c..0000000 --- a/grouperBot/script/swap.s.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; - -import {Script} from "forge-std/Script.sol"; -import {console} from "forge-std/console.sol"; - -import {Constants} from "./constant.s.sol"; -import {Setup} from "./setup.s.sol"; - -/// @notice Swap the tokens: usdc -> mock erc20 -contract Swap is Setup, Script { - function run() public { - vm.startBroadcast(deployerPrivateKey); - - uint256 usdcAmount = 100_000000; - - // 1. approve the tokens - Constants.USDC_ADDR.approve(address(Constants.BOT_ADDR), type(uint256).max); - Constants.MOCK_ERC20_ADDR.approve(address(Constants.BOT_ADDR), type(uint256).max); - - // 2. swap the tokens - (, uint256 actualAmountOut) = Constants.BOT_ADDR - .v2SwapWithCaller( - address(Constants.MOCK_POOL_ADDR), - address(Constants.USDC_ADDR), - usdcAmount, - address(Constants.MOCK_ERC20_ADDR) - ); - - console.log(); - console.log("amount in: ", usdcAmount); - console.log("amount out:", actualAmountOut); - - console.log("successfully swapped!"); - - vm.stopBroadcast(); - } -} diff --git a/grouperBot/src/Errors.sol b/grouperBot/src/Errors.sol deleted file mode 100644 index bafb406..0000000 --- a/grouperBot/src/Errors.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -library Errors { - string public constant NO_ETHER_ALLOWED = "No ether allowed"; // 'No ether allowed' - string public constant INSUFFICIENT_INPUT_AMOUNT = "UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT"; // 'The caller must be the pool admin' - string public constant INSUFFICIENT_LIQUIDITY = "UniswapV2Library: INSUFFICIENT_LIQUIDITY"; // 'The caller must be the pool admin' -} diff --git a/grouperBot/src/GrouperBot.sol b/grouperBot/src/GrouperBot.sol deleted file mode 100644 index dfb08e5..0000000 --- a/grouperBot/src/GrouperBot.sol +++ /dev/null @@ -1,144 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {Ownable} from "solady/auth/Ownable.sol"; -import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol"; - -import {IUniswapV2Pair} from "./interfaces/IUniswapV2Pair.sol"; -import {IUniswapV2Router02} from "./interfaces/IUniswapV2Router02.sol"; -import {IERC20} from "./interfaces/IERC20.sol"; -import {Errors} from "./Errors.sol"; - -/// @notice The bot, for actually swap and simulate the swap -/// @dev Version 1 -/// @dev The dex we support now: uniswap-v2 -contract GrouperBot is Ownable { - using SafeTransferLib for address; - - constructor() Ownable() { - _initializeOwner(msg.sender); - } - - string public constant VERSION = "1"; - - /// @notice Do a uniswap-v2 swap - /// @dev We consider if the token is taxed or not - /// @dev We utilize the asset in this contract - function v2Swap(address targetPair_, address inputToken_, uint256 amountIn_, address outputToken_) - public - onlyOwner - returns (uint256 theoreticalAmountOut, uint256 actualAmountOut) - { - (theoreticalAmountOut, actualAmountOut) = _v2Swap(targetPair_, inputToken_, amountIn_, outputToken_); - } - - /// @notice Do a uniswap-v2 swap - /// @dev We consider if the token is taxed or not - /// @dev We utilize the asset from caller. Caller will give the amountIn and get the amountOut - function v2SwapWithCaller(address targetPair_, address inputToken_, uint256 amountIn_, address outputToken_) - public - onlyOwner - returns (uint256 theoreticalAmountOut, uint256 actualAmountOut) - { - // Transfer the input token to the contract - inputToken_.safeTransferFrom(msg.sender, address(this), amountIn_); - - (theoreticalAmountOut, actualAmountOut) = _v2Swap(targetPair_, inputToken_, amountIn_, outputToken_); - - // Send back to the msg.msg.sender - outputToken_.safeTransfer(msg.sender, actualAmountOut); - } - - function _v2Swap(address targetPair_, address inputToken_, uint256 amountIn_, address outputToken_) - internal - returns (uint256 theoreticalAmountOut, uint256 actualAmountOut) - { - // Check if you can transfer the token - // Some honeypot tokens won't allow you to transfer tokens - inputToken_.safeTransfer(targetPair_, amountIn_); - - uint256 reserveIn; - uint256 reserveOut; - - { - (uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(targetPair_).getReserves(); - - if (inputToken_ < outputToken_) { - reserveIn = reserve0; - reserveOut = reserve1; - } else { - reserveIn = reserve1; - reserveOut = reserve0; - } - } - - // Calculate the amount out you are supposed to get if the token isn't taxed - uint256 actualAmountIn = IERC20(inputToken_).balanceOf(targetPair_) - reserveIn; - theoreticalAmountOut = this.getAmountOut(actualAmountIn, reserveIn, reserveOut); - - // If the token is taxed, you won't receive amountOut back, and the swap will revert - uint256 outBalanceBefore = IERC20(outputToken_).balanceOf(address(this)); - - (uint256 amount0Out, uint256 amount1Out) = - inputToken_ < outputToken_ ? (uint256(0), theoreticalAmountOut) : (theoreticalAmountOut, uint256(0)); - IUniswapV2Pair(targetPair_).swap(amount0Out, amount1Out, address(this), new bytes(0)); - - // Check the real balance of outputToken after the swap - actualAmountOut = IERC20(outputToken_).balanceOf(address(this)) - outBalanceBefore; - } - - /// @notice Risk evaluation of a token - /// @dev We should apply 2 `v2SimulateSwap`: - /// - first: `inputToken` -> `outputToken` - /// - second: `outputToken` -> `inputToken` - /// To test whether we could sell the token and whether the token has a high tax - function v2SimulateSwap(address targetPair_, address inputToken_, uint256 amountIn_, address outputToken_) - external - onlyOwner - returns (bool isProfit, uint256 diff) - { - uint256 tokenInBalanceBefore = IERC20(inputToken_).balanceOf(address(this)); - - // 1. Swap `inputToken` -> `outputToken` - (, uint256 actualAmountOut) = v2Swap(targetPair_, inputToken_, amountIn_, outputToken_); - - // 2. Swap `outputToken` -> `inputToken` - v2Swap(targetPair_, outputToken_, actualAmountOut, inputToken_); - - uint256 tokenInBalanceAfter = IERC20(inputToken_).balanceOf(address(this)); - if (tokenInBalanceAfter > tokenInBalanceBefore) { - // should not happen in most of the time - isProfit = true; - diff = tokenInBalanceAfter - tokenInBalanceBefore; - } else { - isProfit = false; - diff = tokenInBalanceBefore - tokenInBalanceAfter; - } - } - - /// @notice Helper function to calculate the amount out - function getAmountOut(uint256 amountIn_, uint256 reserveIn_, uint256 reserveOut_) - external - pure - returns (uint256 amountOut) - { - require(amountIn_ > 0, Errors.INSUFFICIENT_INPUT_AMOUNT); - require(reserveIn_ > 0 && reserveOut_ > 0, Errors.INSUFFICIENT_LIQUIDITY); - uint256 amountInWithFee = amountIn_ * 997; - uint256 numerator = amountInWithFee * reserveOut_; - uint256 denominator = reserveIn_ * 1000 + amountInWithFee; - amountOut = numerator / denominator; - } - - /// @notice Withdraw a token from the contract - /// @dev Only owner could withdraw token - /// @param token_ The token to withdraw - /// @param amount_ The amount to withdraw - function withdrawToken(address token_, uint256 amount_) external onlyOwner { - token_.safeTransfer(msg.sender, amount_); - } - - receive() external payable { - revert(Errors.NO_ETHER_ALLOWED); - } -} diff --git a/grouperBot/src/interfaces/IERC20.sol b/grouperBot/src/interfaces/IERC20.sol deleted file mode 100644 index eb9bd11..0000000 --- a/grouperBot/src/interfaces/IERC20.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) - -pragma solidity ^0.8.0; - -interface IERC20 { - event Transfer(address indexed from, address indexed to, uint256 value); - event Approval(address indexed owner, address indexed spender, uint256 value); - - function totalSupply() external view returns (uint256); - - function balanceOf(address account) external view returns (uint256); - - function transfer(address to, uint256 value) external returns (bool); - - function allowance(address owner, address spender) external view returns (uint256); - - function approve(address spender, uint256 value) external returns (bool); - - function transferFrom(address from, address to, uint256 value) external returns (bool); - - function decimals() external view returns (uint8); -} diff --git a/grouperBot/src/interfaces/IUniswapV2Factory.sol b/grouperBot/src/interfaces/IUniswapV2Factory.sol deleted file mode 100644 index 7609bb2..0000000 --- a/grouperBot/src/interfaces/IUniswapV2Factory.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -interface IUniswapV2Factory { - event PairCreated(address indexed token0, address indexed token1, address pair, uint256); - - function allPairs(uint256) external view returns (address); - - function allPairsLength() external view returns (uint256); - - function createPair(address tokenA, address tokenB) external returns (address pair); - - function feeTo() external view returns (address); - - function feeToSetter() external view returns (address); - - function getPair(address, address) external view returns (address); - - function setFeeTo(address _feeTo) external; - - function setFeeToSetter(address _feeToSetter) external; -} diff --git a/grouperBot/src/interfaces/IUniswapV2Pair.sol b/grouperBot/src/interfaces/IUniswapV2Pair.sol deleted file mode 100644 index 57bfe0f..0000000 --- a/grouperBot/src/interfaces/IUniswapV2Pair.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) - -pragma solidity ^0.8.0; - -interface IUniswapV2Pair { - event Approval(address indexed owner, address indexed spender, uint256 value); - event Transfer(address indexed from, address indexed to, uint256 value); - - function name() external pure returns (string memory); - - function symbol() external pure returns (string memory); - - function decimals() external pure returns (uint8); - - function totalSupply() external view returns (uint256); - - function balanceOf(address owner) external view returns (uint256); - - function allowance(address owner, address spender) external view returns (uint256); - - function approve(address spender, uint256 value) external returns (bool); - - function transfer(address to, uint256 value) external returns (bool); - - function transferFrom(address from, address to, uint256 value) external returns (bool); - - function DOMAIN_SEPARATOR() external view returns (bytes32); - - function PERMIT_TYPEHASH() external pure returns (bytes32); - - function nonces(address owner) external view returns (uint256); - - function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) - external; - - event Mint(address indexed sender, uint256 amount0, uint256 amount1); - event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); - event Swap( - address indexed sender, - uint256 amount0In, - uint256 amount1In, - uint256 amount0Out, - uint256 amount1Out, - address indexed to - ); - event Sync(uint112 reserve0, uint112 reserve1); - - function MINIMUM_LIQUIDITY() external pure returns (uint256); - - function factory() external view returns (address); - - function token0() external view returns (address); - - function token1() external view returns (address); - - function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); - - function price0CumulativeLast() external view returns (uint256); - - function price1CumulativeLast() external view returns (uint256); - - function kLast() external view returns (uint256); - - function mint(address to) external returns (uint256 liquidity); - - function burn(address to) external returns (uint256 amount0, uint256 amount1); - - function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; - - function skim(address to) external; - - function sync() external; - - function initialize(address, address) external; -} diff --git a/grouperBot/src/interfaces/IUniswapV2Router01.sol b/grouperBot/src/interfaces/IUniswapV2Router01.sol deleted file mode 100644 index bed158c..0000000 --- a/grouperBot/src/interfaces/IUniswapV2Router01.sol +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -interface IUniswapV2Router01 { - function factory() external pure returns (address); - - function WETH() external pure returns (address); - - function addLiquidity( - address tokenA, - address tokenB, - uint256 amountADesired, - uint256 amountBDesired, - uint256 amountAMin, - uint256 amountBMin, - address to, - uint256 deadline - ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity); - - function addLiquidityETH( - address token, - uint256 amountTokenDesired, - uint256 amountTokenMin, - uint256 amountETHMin, - address to, - uint256 deadline - ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity); - - function removeLiquidity( - address tokenA, - address tokenB, - uint256 liquidity, - uint256 amountAMin, - uint256 amountBMin, - address to, - uint256 deadline - ) external returns (uint256 amountA, uint256 amountB); - - function removeLiquidityETH( - address token, - uint256 liquidity, - uint256 amountTokenMin, - uint256 amountETHMin, - address to, - uint256 deadline - ) external returns (uint256 amountToken, uint256 amountETH); - - function removeLiquidityWithPermit( - address tokenA, - address tokenB, - uint256 liquidity, - uint256 amountAMin, - uint256 amountBMin, - address to, - uint256 deadline, - bool approveMax, - uint8 v, - bytes32 r, - bytes32 s - ) external returns (uint256 amountA, uint256 amountB); - - function removeLiquidityETHWithPermit( - address token, - uint256 liquidity, - uint256 amountTokenMin, - uint256 amountETHMin, - address to, - uint256 deadline, - bool approveMax, - uint8 v, - bytes32 r, - bytes32 s - ) external returns (uint256 amountToken, uint256 amountETH); - - function swapExactTokensForTokens( - uint256 amountIn, - uint256 amountOutMin, - address[] calldata path, - address to, - uint256 deadline - ) external returns (uint256[] memory amounts); - - function swapTokensForExactTokens( - uint256 amountOut, - uint256 amountInMax, - address[] calldata path, - address to, - uint256 deadline - ) external returns (uint256[] memory amounts); - - function swapExactETHForTokens(uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) - external - payable - returns (uint256[] memory amounts); - - function swapTokensForExactETH( - uint256 amountOut, - uint256 amountInMax, - address[] calldata path, - address to, - uint256 deadline - ) external returns (uint256[] memory amounts); - - function swapExactTokensForETH( - uint256 amountIn, - uint256 amountOutMin, - address[] calldata path, - address to, - uint256 deadline - ) external returns (uint256[] memory amounts); - - function swapETHForExactTokens(uint256 amountOut, address[] calldata path, address to, uint256 deadline) - external - payable - returns (uint256[] memory amounts); - - function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) external pure returns (uint256 amountB); - - function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut) - external - pure - returns (uint256 amountOut); - - function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut) - external - pure - returns (uint256 amountIn); - - function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); - - function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); -} diff --git a/grouperBot/src/interfaces/IUniswapV2Router02.sol b/grouperBot/src/interfaces/IUniswapV2Router02.sol deleted file mode 100644 index 5cd3a3e..0000000 --- a/grouperBot/src/interfaces/IUniswapV2Router02.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "./IUniswapV2Router01.sol"; - -interface IUniswapV2Router02 is IUniswapV2Router01 { - function removeLiquidityETHSupportingFeeOnTransferTokens( - address token, - uint256 liquidity, - uint256 amountTokenMin, - uint256 amountETHMin, - address to, - uint256 deadline - ) external returns (uint256 amountETH); - - function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( - address token, - uint256 liquidity, - uint256 amountTokenMin, - uint256 amountETHMin, - address to, - uint256 deadline, - bool approveMax, - uint8 v, - bytes32 r, - bytes32 s - ) external returns (uint256 amountETH); - - function swapExactTokensForTokensSupportingFeeOnTransferTokens( - uint256 amountIn, - uint256 amountOutMin, - address[] calldata path, - address to, - uint256 deadline - ) external; - - function swapExactETHForTokensSupportingFeeOnTransferTokens( - uint256 amountOutMin, - address[] calldata path, - address to, - uint256 deadline - ) external payable; - - function swapExactTokensForETHSupportingFeeOnTransferTokens( - uint256 amountIn, - uint256 amountOutMin, - address[] calldata path, - address to, - uint256 deadline - ) external; -} diff --git a/grouperBot/test/GrouperBot.t.sol b/grouperBot/test/GrouperBot.t.sol deleted file mode 100644 index 7305f19..0000000 --- a/grouperBot/test/GrouperBot.t.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; -import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol"; - -import {GrouperBot} from "../src/GrouperBot.sol"; -import {IUniswapV2Pair} from "../src/interfaces/IUniswapV2Pair.sol"; -import {IERC20} from "../src/interfaces/IERC20.sol"; - -contract GrouperBotTest is Test { - using SafeTransferLib for address; - - IERC20 public usdc = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); // token0 - IERC20 public usdt = IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7); // token1 - IUniswapV2Pair public usdt_usdc_pool = IUniswapV2Pair(0x3041CbD36888bECc7bbCBc0045E3B1f144466f5f); - GrouperBot public grouperBot; - - function setUp() public { - string memory RPC_URL = vm.envString("ETH_MAINNET_RPC"); - vm.createSelectFork(RPC_URL, 23_500_000); - - // deploy contract - grouperBot = new GrouperBot(); - - // give some tokens so that we can swap - deal(address(usdt), address(grouperBot), 100 * 10 ** usdt.decimals()); - // clear state - deal(address(usdt), address(this), 0); - } - - /// @notice Do 2 swaps: token0 -> token1 -> token0 to check whether we could sell token1 - function test_v2Swap() public { - emit log_named_decimal_uint("usdt balance", usdt.balanceOf(address(grouperBot)), usdt.decimals()); - - console.log(); - console.log("1st swap: USDT -> USDC"); - - // 1. swap - (, uint256 actualAmountOut) = - grouperBot.v2Swap(address(usdt_usdc_pool), address(usdt), 100 * 10 ** usdt.decimals(), address(usdc)); - emit log_named_decimal_uint("usdc amountOut", actualAmountOut, usdc.decimals()); - - console.log(); - console.log("2nd swap: USDC -> USDT"); - - // 2. swap - (, actualAmountOut) = grouperBot.v2Swap(address(usdt_usdc_pool), address(usdc), actualAmountOut, address(usdt)); - emit log_named_decimal_uint("usdt amountOut", actualAmountOut, usdt.decimals()); - - console.log(); - emit log_named_decimal_uint("usdt balance", usdt.balanceOf(address(grouperBot)), usdt.decimals()); - } - - function test_v2SimulateSwap() public { - (, uint256 diff) = grouperBot.v2SimulateSwap( - address(usdt_usdc_pool), address(usdt), 100 * 10 ** usdt.decimals(), address(usdc) - ); - emit log_named_decimal_uint("diff", uint256(diff), usdt.decimals()); - } - - function test_withdrawToken() public { - emit log_named_decimal_uint("usdt balance", usdt.balanceOf(address(this)), usdt.decimals()); - - // non-owner could not withdraw token - uint256 amount = usdt.balanceOf(address(grouperBot)); - vm.prank(address(1)); - vm.expectRevert(); - grouperBot.withdrawToken(address(usdt), amount); - - // owner could withdraw token - vm.prank(address(this)); - grouperBot.withdrawToken(address(usdt), amount); - emit log_named_decimal_uint("usdt balance", usdt.balanceOf(address(this)), usdt.decimals()); - } -} diff --git a/grouperBot/test/mockERC20.t.sol b/grouperBot/test/mockERC20.t.sol deleted file mode 100644 index 78910f8..0000000 --- a/grouperBot/test/mockERC20.t.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.28; - -import {ERC20} from "solady/tokens/ERC20.sol"; - -/// @dev WARNING! This mock is strictly intended for testing purposes only. -/// Do NOT copy anything here into production code unless you really know what you are doing. -contract MockERC20 is ERC20 { - string internal _name; - string internal _symbol; - uint8 internal _decimals; - - constructor(string memory name_, string memory symbol_, uint8 decimals_) { - _name = name_; - _symbol = symbol_; - _decimals = decimals_; - - mint(msg.sender, 1_000_000 ether); - } - - function name() public view override returns (string memory) { - return _name; - } - - function symbol() public view override returns (string memory) { - return _symbol; - } - - function decimals() public view override returns (uint8) { - return _decimals; - } - - function mint(address to, uint256 amount) public { - _mint(to, amount); - } -}