8000 Permit2script extended by 0xDEnYO · Pull Request #1156 · lifinance/contracts · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Permit2script extended #1156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open

Permit2script extended #1156

wants to merge 33 commits into from

Conversation

0xDEnYO
Copy link
Contributor
@0xDEnYO 0xDEnYO commented May 21, 2025

Which Jira task belongs to this PR?

Why did I implement it this way?

Checklist before requesting a review

Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)

  • I have checked that any arbitrary calls to external contracts are validated and or restricted
  • I have checked that any privileged calls (i.e. storage modifications) are validated and or restricted
  • I have ensured that any new contracts have had AT A MINIMUM 1 preliminary audit conducted on by <company/auditor>

Copy link
Contributor
coderabbitai bot commented May 21, 2025

Walkthrough

A new GitHub Actions workflow for verifying Permit2 contract bytecode on pull requests is introduced. Supporting this, new Solidity scripts and a Bash verification script are added, along with enhancements to shell helper functions. These changes enable automated, network-specific Permit2 bytecode validation using Foundry and custom scripts.

Changes

File(s) Change Summary
.github/workflows/verifyPermit2Bytecode.yml Adds a GitHub Actions workflow to verify Permit2 bytecode on PRs, conditionally running checks and scripts if relevant config changes are detected.
script/helperFunctions.sh Updates the function declaration style for checkNetworksJsonFilePath and adds readJsonValueFromConfigFile for robust JSON config value extraction with error handling.
script/utils/permit2/Permit2Check.s.sol Introduces a Solidity contract Permit2Check for comparing deployed contract bytecode with expected bytecode, providing error signaling on mismatch.
script/utils/permit2/Permit2Code.s.sol Adds a Solidity script Permit2Code to deploy Permit2 contract code in a simulated environment and retrieve its runtime bytecode for comparison.
script/utils/permit2/verifyPermit2Bytecode.sh Adds a Bash script to automate the process of retrieving Permit2 addresses, extracting expected bytecode, and verifying deployed bytecode on a specified network using Foundry scripts.

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch permit2scriptExtended
  • Post Copyable Unit Tests in Comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@lifi-action-bot lifi-action-bot marked this pull request as draft May 21, 2025 05:41
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🔭 Outside diff range comments (1)
script/helperFunctions.sh (1)

2015-2026: ⚠️ Potential issue

Missing explicit success return in checkNetworksJsonFilePath
The function uses if…elif tests and returns 1 on failure, but on the success path the last evaluated test ([[ ! -s … ]]) will return non-zero, causing the function to signal failure even when the file is valid. Add an explicit return 0 after the fi to ensure a zero exit code on success.

Apply this diff:

 function checkNetworksJsonFilePath() {
   if [[ -z "$NETWORKS_JSON_FILE_PATH" ]]; then
     error "NETWORKS_JSON_FILE_PATH is not set. Please check your configuration."
     return 1
   elif [[ ! -f "$NETWORKS_JSON_FILE_PATH" ]]; then
     error "NETWORKS_JSON_FILE_PATH does not point to a valid file: $NETWORKS_JSON_FILE_PATH"
     return 1
   elif [[ ! -s "$NETWORKS_JSON_FILE_PATH" ]]; then
     error "NETWORKS_JSON_FILE_PATH file is empty: $NETWORKS_JSON_FILE_PATH"
     return 1
   fi
+  return 0
 }
🧹 Nitpick comments (19)
script/helperFunctions.sh (1)

2927-2950: Inconsistent error handling & duplication in readJsonValueFromConfigFile
This new helper duplicates the behavior of the existing getValueFromJSONFile (near line 3413) and uses exit to abort the entire script, whereas most other helpers use error/return. Consider refactoring to reuse getValueFromJSONFile (or at least adopt the same error-handling style) and replace exit 1 with return 1 to avoid unintended script termination.

A possible refactor:

-readJsonValueFromConfigFile() {
-  local CONFIG_FILE_NAME="$1"
-  local KEY="$2"
-  local CONFIG_FILE_PATH="config/$CONFIG_FILE_NAME"
-
-  if [ ! -f "$CONFIG_FILE_PATH" ]; then
-    echo "[ERROR] Config file not found: $CONFIG_FILE_PATH" >&2
-    exit 1
-  fi
-
-  local VALUE
-  VALUE=$(jq -r "$KEY // empty" "$CONFIG_FILE_PATH")
-
-  if [ -z "$VALUE" ]; then
-    echo "[ERROR] Key '$KEY' not found or is empty in $CONFIG_FILE_PATH" >&2
-    exit 1
-  fi
-
-  echo "$VALUE"
-}
+readJsonValueFromConfigFile() {
+  local CONFIG_FILE_NAME="$1"
+  local KEY="$2"
+  local CONFIG_FILE_PATH="config/$CONFIG_FILE_NAME"
+
+  # delegate to existing helper
+  getValueFromJSONFile "$CONFIG_FILE_PATH" "$KEY" \
+    || { error "Failed to read '$KEY' from $CONFIG_FILE_PATH"; return 1; }
+}
script/utils/permit2/Permit2Code.s.sol (3)

13-15: Cheat-code side-effects not reverted
vm.chainId(chainid) mutates the global cheat-code state for subsequent scripts in the same process.
Consider restoring the original chain id after the deployment to avoid surprising side-effects when this helper is called from other scripts.


41-42: Unchecked low-level call gas / value
permit2Deployer.call(permit2CreationCalldata) forwards all remaining gas and zero value.
If the deployer expects a specific gas stipend or value, the call can silently fail.
Consider using call{value: 0, gas: SOME_GAS_LIMIT} or at least documenting why forwarding all gas is safe.


6-6: Duplicate hard-coded PERMIT2 constant
The same address constant is declared in multiple files (Permit2Code, Permit2Check).
Moving it to a dedicated library/contract (e.g., Permit2Constants.sol) avoids divergence in future edits.

script/utils/permit2/Permit2Check.s.sol (2)

13-16: Function should be view
checkCode only performs EXTCODEHASH look-ups and has no side-effects.
Marking it external view (or at least view) communicates intent and allows static-analysis tools to reason about purity.

-    function checkCode(address target, bytes memory expected) public virtual {
+    function checkCode(address target, bytes memory expected) public view virtual {

18-20: Gas optimisation – hash once
Calling checkCode(bytes) currently re-hashes expected when delegating to the address-aware overload.
Cache the hash once to save gas in on-chain usage (if ever used on-chain).

config/permit2Proxy.json (1)

9-9: Inconsistent casing for blast address
blast entry is lowercase (…22d473…) whereas others are checksummed.
While solidity is case-insensitive, checksum casing helps catch typos during reviews.

script/utils/permit2/verifyPermit2Bytecode.sh (6)

1-6: Use a portable shebang and robust sourcing paths.
Switch to #!/usr/bin/env bash for portability and resolve helper scripts relative to this script’s directory to avoid failures when invoked from other working directories.

-#!/bin/bash
+#!/usr/bin/env bash
+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-source script/helperFunctions.sh
-source script/config.sh
+source "$DIR/../../helperFunctions.sh"
+source "$DIR/../../config.sh"

16-20: Redirect error messages to stderr and standardize the prefix.
Currently errors go to stdout and use [error]. Use >&2 and a consistent [ERROR] tag:

- if [ -z "$RPC_URL" ]; then
-   echo "[error] Could not find RPC URL for network '$NETWORK' in .en
8000
v"
+ if [ -z "$RPC_URL" ]; then
+   echo "[ERROR] Could not find RPC URL for network '$NETWORK' in .env" >&2
    exit 1
 fi

22-26: Standardize error handling for missing chain ID.
Apply the same stderr redirection and [ERROR] prefix here:

- if [ -z "$CHAIN_ID" ]; then
-   echo "[error] Could not find chainId for network '$NETWORK' in networks.json"
+ if [ -z "$CHAIN_ID" ]; then
+   echo "[ERROR] Could not find chainId for network '$NETWORK' in networks.json" >&2
    exit 1
 fi

29-36: Eliminate the redundant empty-address check.
readJsonValueFromConfigFile already exits on missing/empty keys. The subsequent if [ -z "$ADDRESS" ] block will never run. Consider removing lines 33–36 or adjust the helper to return empty for custom handling here.


39-42: Validate that bytecode was retrieved before proceeding.
If forge script Permit2Code fails or the grep/sed pipeline doesn’t match, $CODE will be empty. Add a guard:

if [ -z "$CODE" ]; then
  echo "[ERROR] Failed to retrieve expected bytecode for chain ID $CHAIN_ID" >&2
  exit 1
fi

44-46: Check for Foundry’s forge binary before invoking.
Ensure forge is on PATH to give a clear error if it’s missing:

if ! command -v forge &>/dev/null; then
  echo "[ERROR] 'forge' not found. Install Foundry (e.g., via 'foundryup')." >&2
  exit 1
fi
forge script Permit2Check --sig "checkCode(address,bytes)" "$ADDRESS" "$CODE" --rpc-url "$RPC_URL" -vvvv
.github/workflows/verifyPermit2Bytecode.yml (6)

7-10: Trigger the workflow only on relevant file changes using paths.
You can avoid an initial file-change detection step by adding a paths filter:

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths:
      - config/permit2Proxy.json

This ensures the job runs only when the target config file is modified.


29-30: Quote $GITHUB_ENV in redirections.
Wrap the file-path variable in quotes to prevent globbing/word splitting:

- echo "CONTINUE=true" >> $GITHUB_ENV
+ echo "CONTINUE=true" >> "$GITHUB_ENV"
- echo "CONTINUE=false" >> $GITHUB_ENV
+ echo "CONTINUE=false" >> "$GITHUB_ENV"

42-43: Quote the refspec path in git show.
Guard against special characters by quoting the file path:

- if git show origin/main:config/permit2Proxy.json > /dev/null 2>&1; then
+ if git show origin/main:"config/permit2Proxy.json" > /dev/null 2>&1; then
-   OLD_ADDRESSES=$(git show origin/main:config/permit2Proxy.json | jq 'keys')
+   OLD_ADDRESSES=$(git show origin/main:"config/permit2Proxy.json" | jq 'keys')

49-49: Quote the config file path when calling jq.

- NEW_ADDRESSES=$(jq 'keys' config/permit2Proxy.json)
+ NEW_ADDRESSES=$(jq 'keys' "config/permit2Proxy.json")

60-60: Quote $ADDED_NETWORKS when piping to jq.

- echo "added_networks=$(echo $ADDED_NETWORKS | jq -c .)" >> "$GITHUB_ENV"
+ echo "added_networks=$(echo "$ADDED_NETWORKS" | jq -c .)" >> "$GITHUB_ENV"

76-76: Quote $added_networks in the loop to prevent splitting.

- for NETWORK in $(echo $added_networks | jq -r '.[]'); do
+ for NETWORK in $(echo "$added_networks" | jq -r '.[]'); do

Alternatively, read into an array to handle arbitrary values safely.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 1797b84 and b505b89.

📒 Files selected for processing (6)
  • .github/workflows/verifyPermit2Bytecode.yml (1 hunks)
  • config/permit2Proxy.json (1 hunks)
  • script/helperFunctions.sh (2 hunks)
  • script/utils/permit2/Permit2Check.s.sol (1 hunks)
  • script/utils/permit2/Permit2Code.s.sol (1 hunks)
  • script/utils/permit2/verifyPermit2Bytecode.sh (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
script/utils/permit2/verifyPermit2Bytecode.sh (1)
script/helperFunctions.sh (3)
  • getRPCUrl (2770-2779)
  • getChainId (2891-2908)
  • readJsonValueFromConfigFile (2927-2950)
🪛 actionlint (1.7.7)
.github/workflows/verifyPermit2Bytecode.yml

26-26: shellcheck reported issue in this script: SC2086:info:3:27: Double quote to prevent globbing and word splitting

(shellcheck)


26-26: shellcheck reported issue in this script: SC2086:info:6:28: Double quote to prevent globbing and word splitting

(shellcheck)


38-38: shellcheck reported issue in this script: SC2086:info:19:29: Double quote to prevent globbing and word splitting

(shellcheck)


38-38: shellcheck reported issue in this script: SC2086:info:22:31: Double quote to prevent globbing and word splitting

(shellcheck)


38-38: shellcheck reported issue in this script: SC2086:info:22:62: Double quote to prevent globbing and word splitting

(shellcheck)


73-73: shellcheck reported issue in this script: SC2086:info:3:23: Double quote to prevent globbing and word splitting

(shellcheck)

🔇 Additional comments (1)
config/permit2Proxy.json (1)

24-25: Potential incorrect Moonriver proxy address (…BA2 vs …BA3)
All other networks – including moonbeam – use the canonical Permit2 address 0x000000000022D473030F116dDEE9F6B43aC78BA3.
moonriver ends in BA2, which will cause the automated bytecode check to fail and, if deployed, break signature transfers on that chain.

Please confirm the correct Permit2 proxy for Moonriver.

@0xDEnYO 0xDEnYO marked this pull request as ready for review May 21, 2025 06:31
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
.github/workflows/verifyPermit2Bytecode.yml (2)

24-33: Quote $GITHUB_ENV in Redirections
To prevent word splitting or globbing, wrap $GITHUB_ENV in quotes when appending environment variables:

- echo "CONTINUE=true" >> $GITHUB_ENV
+ echo "CONTINUE=true" >> "$GITHUB_ENV"
- echo "CONTINUE=false" >> $GITHUB_ENV
+ echo "CONTINUE=false" >> "$GITHUB_ENV"
🧰 Tools
🪛 actionlint (1.7.7)

26-26: shellcheck reported issue in this script: SC2086:info:3:27: Double quote to prevent globbing and word splitting

(shellcheck)


26-26: shellcheck reported issue in this script: SC2086:info:6:28: Double quote to prevent globbing and word splitting

(shellcheck)


100-113: Enhance Verification Loop Robustness

  • Add set -euxo pipefail at the top of this block to catch failures and echo commands for easier debugging.
  • Quote the JSON array when iterating:
- for NETWORK in $(echo $CHANGED_NETWORKS | jq -r '.[]'); do
+ for NETWORK in $(echo "$CHANGED_NETWORKS" | jq -r '.[]'); do
  • Optionally, consider switching to a GitHub Actions matrix for parallel network checks and adding retries for flaky RPC calls.
🧰 Tools
🪛 actionlint (1.7.7)

102-102: shellcheck reported issue in this script: SC2086:info:3:23: Double quote to prevent globbing and word splitting

(shellcheck)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between b505b89 and caf71df.

📒 Files selected for processing (4)
  • .github/workflows/verifyPermit2Bytecode.yml (1 hunks)
  • config/permi 8000 t2Proxy.json (2 hunks)
  • script/helperFunctions.sh (2 hunks)
  • script/utils/permit2/verifyPermit2Bytecode.sh (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • config/permit2Proxy.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • script/utils/permit2/verifyPermit2Bytecode.sh
  • script/helperFunctions.sh
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/verifyPermit2Bytecode.yml

26-26: shellcheck reported issue in this script: SC2086:info:3:27: Double quote to prevent globbing and word splitting

(shellcheck)


26-26: shellcheck reported issue in this script: SC2086:info:6:28: Double quote to prevent globbing and word splitting

(shellcheck)


38-38: shellcheck reported issue in this script: SC2086:info:20:29: Double quote to prevent globbing and word splitting

(shellcheck)


38-38: shellcheck reported issue in this script: SC2086:info:27:48: Double quote to prevent globbing and word splitting

(shellcheck)


102-102: shellcheck reported issue in this script: SC2086:info:3:23: Double quote to prevent globbing and word splitting

(shellcheck)

🔇 Additional comments (8)
.github/workflows/verifyPermit2Bytecode.yml (8)

1-6: Workflow Purpose Confirmation
The Permit2 Bytecode Verifier is clearly documented at the top, outlining its intent to detect and verify newly added proxy addresses. This helps maintainers quickly understand the workflow.


7-13: Trigger and Permissions Configuration
The workflow is correctly set to run on relevant pull request events, and the contents: read permission is appropriately scoped for checking file diffs.


14-23: Repository Checkout Step
Using actions/checkout@v4 with fetch-depth: 0 ensures we have full commit history for diffs. This is best practice for change detection.


68-71: Foundry Installation
The use of foundry-rs/foundry-toolchain@v1.3.1 is appropriate to provide forge and cast for bytecode verification.


72-77: Bun Setup
Installing Bun via oven-sh/setup-bun@v1 with bun-version: latest correctly sets up the JavaScript runtime needed by subsequent scripts.


78-83: Dependencies Installation
bun install and forge install steps ensure all necessary tools and packages are available before running verification.


87-94: Fetch RPC Endpoints
Using the MONGODB_URI secret to retrieve RPC endpoints via bun fetch-rpcs is secure and reusable. Ensure the helper script does not log sensitive data.


95-99: Config File Preparation
Copying script/config.example.sh to script/config.sh is a straightforward way to bootstrap required environment variables for helper functions.

@reednaa
Copy link
Member
reednaa commented May 21, 2025

The previous raw output I used has an issue with reliability long term. I changed to the json output.

Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
.github/workflows/verifyPermit2Bytecode.yml (1)

33-53: 🛠️ Refactor suggestion

Harden change detection with strict mode and safe temp files
The current step uses fixed filenames (old.txt, new.txt, changed_lines.txt) and lacks strict error handling. In concurrent or failure scenarios, this can result in race conditions or silent failures. I recommend:

-run: |
-  git fetch origin main --depth=1
-
-  if git show origin/main:config/permit2Proxy.json > /dev/null 2>&1; then
-    git show origin/main:config/permit2Proxy.json | jq -r 'to_entries[] | "\(.key)=\(.value)"' | sort > old.txt
-  else
-    echo "" > old.txt
-  fi
-
-  jq -r 'to_entries[] | "\(.key)=\(.value)"' config/permit2Proxy.json | sort > new.txt
-  comm -13 old.txt new.txt > changed_lines.txt
-
-  if [ ! -s changed_lines.txt ]; then
-    echo "SKIP_CHECK=true" >> $GITHUB_ENV
-  else
-    cut -d= -f1 changed_lines.txt | jq -R . | jq -cs '.' > changed_networks.json
-    echo "CHANGED_NETWORKS=$(cat changed_networks.json)" >> $GITHUB_ENV
-  fi
+run: |
+  set -euo pipefail
+  old_file=$(mktemp)
+  new_file=$(mktemp)
+  diff_file=$(mktemp)
+  git fetch origin main --depth=1
+
+  if git show origin/main:config/permit2Proxy.json > /dev/null 2>&1; then
+    git show origin/main:config/permit2Proxy.json \
+      | jq -r 'to_entries[] | "\(.key)=\(.value)"' \
+      | sort > "$old_file"
+  else
+    printf '' >"$old_file"
+  fi
+
+  jq -r 'to_entries[] | "\(.key)=\(.value)"' config/permit2Proxy.json \
+    | sort > "$new_file"
+  comm -13 "$old_file" "$new_file" > "$diff_file"
+
+  if [ ! -s "$diff_file" ]; then
+    echo "SKIP_CHECK=true" >> "$GITHUB_ENV"
+  else
+    cut -d= -f1 "$diff_file" | jq -R . | jq -cs '.' > changed_networks.json
+    echo "CHANGED_NETWORKS=$(cat changed_networks.json)" >> "$GITHUB_ENV"
+  fi
+  rm -f "$old_file" "$new_file" "$diff_file"

This ensures any errors abort the step, files are unique per run, and temp files are cleaned up.

🧰 Tools
🪛 actionlint (1.7.7)

36-36: shellcheck reported issue in this script: SC2086:info:13:29: Double quote to prevent globbing and word splitting

(shellcheck)


36-36: shellcheck reported issue in this script: SC2086:info:16:59: Double quote to prevent globbing and word splitting

(shellcheck)

🧹 Nitpick comments (3)
.github/workflows/verifyPermit2Bytecode.yml (3)

6-9: Leverage paths filter to avoid unnecessary runs
Even though you perform an early exit when config/permit2Proxy.json is unchanged, you can improve efficiency by leveraging the paths filter:

on:
  pull_request:
    paths:
      - 'config/permit2Proxy.json'
    types: [opened, synchronize, reopened, ready_for_review]

This ensures the workflow triggers only when the target file is modified, reducing CI noise and speeding up runs.


23-31: Refine Git diff invocation for more precise change detection
Consider using the two-dot syntax (origin/main..HEAD) instead of the symmetric three-dot (origin/main...HEAD). The two-dot range lists commits on your branch not in main, avoiding potential noise from merge commits:

if git diff --name-only origin/main..HEAD | grep -q 'config/permit2Proxy.json'; then
  echo "CONTINUE=true" >> "$GITHUB_ENV"
else
  echo "✅ No changes in permit2Proxy.json identified. Check passed."
  echo "CONTINUE=false" >> "$GITHUB_ENV"
fi
🧰 Tools
🪛 actionlint (1.7.7)

25-25: shellcheck reported issue in this script: SC2086:info:2:27: Double quote to prevent globbing and word splitting

(shellcheck)


25-25: shellcheck reported issue in this script: SC2086:info:5:28: Double quote to prevent globbing and word splitting

(shellcheck)


85-93: Enhance verification loop with strict mode and aggregated reporting
Replace the plain set -e with set -euo pipefail and collect failures across networks, so you get a comprehensive summary rather than stopping at the first error:

-run: |
-  echo "Running permit2 verification..."
-  set -e
-  for NETWORK in $(echo "$CHANGED_NETWORKS" | jq -r '.[]'); do
-    echo "🔍 Verifying $NETWORK"
-    ./script/utils/permit2/verifyPermit2Bytecode.sh "$NETWORK"
-  done
+run: |
+  echo "Running permit2 verification..."
+  set -euo pipefail
+  failures=()
+  for NETWORK in $(echo "$CHANGED_NETWORKS" | jq -r '.[]'); do
+    echo "🔍 Verifying $NETWORK"
+    if ! ./script/utils/permit2/verifyPermit2Bytecode.sh "$NETWORK"; then
+      failures+=("$NETWORK")
+    fi
+  done
+  if [ "${#failures[@]}" -gt 0 ]; then
+    echo "❌ Verification failed for networks: ${failures[*]}"
+    exit 1
+  fi

This improves robustness and provides clear diagnostics for all problematic networks.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between caf71df and c5a892e.

📒 Files selected for processing (2)
  • .github/workflows/verifyPermit2Bytecode.yml (1 hunks)
  • script/utils/permit2/verifyPermit2Bytecode.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • script/utils/permit2/verifyPermit2Bytecode.sh
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/verifyPermit2Bytecode.yml

25-25: shellcheck reported issue in this script: SC2086:info:2:27: Double quote to prevent globbing and word splitting

(shellcheck)


25-25: shellcheck reported issue in this script: SC2086:info:5:28: Double quote to prevent globbing and word splitting

(shellcheck)


36-36: shellcheck reported issue in this script: SC2086:info:13:29: Double quote to prevent globbing and word splitting

(shellcheck)


36-36: shellcheck reported issue in this script: SC2086:info:16:59: Double quote to prevent globbing and word splitting

(shellcheck)

🔇 Additional comments (1)
.github/workflows/verifyPermit2Bytecode.yml (1)

71-73: Conditional strip of [etherscan] section applied correctly
The sed command is now appropriately gated by
if: env.CONTINUE == 'true' && env.SKIP_CHECK != 'true',
preventing unintended edits when no verification is needed.

Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
script/utils/permit2/Permit2Code.s.sol (6)

11-11: Consider adding more detailed explanations to the comment.

The comment "Don't run in fork! Run isolated!" provides an important warning, but it could benefit from more explanation about why running in a fork would be problematic and what "isolated" means in this context.

-    // Don't run in fork! Run isolated!
+    // Don't run in fork! Run isolated!
+    // This contract uses vm.etch to deploy code at specific addresses, which can cause
+    // unexpected behavior when run in a forked environment where contracts may already exist.

18-20: Consider storing this large bytecode constant separately.

This large hexadecimal blob makes the code harder to read and maintain. Consider moving it to a constant or a separate file to improve readability.

-        bytes
-            memory permit2CreationCalldata = hex"60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a";
+        bytes memory permit2CreationCalldata = hex"60c0346100bb574660a052602081017f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a60408301524660608301523060808301526080825260a082019180831060018060401b038411176100a557826040525190206080526123c090816100c1823960805181611b47015260a05181611b210152f35b634e487b7160e01b600052604160045260246000fd5b600080fdfe6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff80921
A780
6602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000000003611b69577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a";

21-25: Consider adding a zero address check.

After deploying the contract using vm.etch, it would be good to validate that the deployment was successful by checking the where address is not the zero address before making the call.

        vm.etch(where, permit2CreationCalldata);
+        if (where == address(0)) revert Permit2DeploymentFailed();
        (bool success, bytes memory runtimeBytecode) = where.call("");
        if (!success) revert Permit2DeploymentFailed();
        // vm.etch(where, runtimeBytecode);

24-24: Remove commented out code.

The commented out line // vm.etch(where, runtimeBytecode); should be removed as it's not being used and might confuse future developers.

        (bool success, bytes memory runtimeBytecode) = where.call("");
        if (!success) revert Permit2DeploymentFailed();
-        // vm.etch(where, runtimeBytecode);

12-27: Add detailed documentation to explain function purpose and usage.

This function uses Forge cheatcodes to retrieve the runtime bytecode for the Permit2 contract on a specific chain. Adding more detailed documentation would make it clearer how to use this function and what it does.

    // Don't run in fork! Run isolated!
+    /**
+     * @notice Gets the runtime bytecode for the Permit2 contract
+     * @dev This function deploys the Permit2 contract creation code at the specified address
+     *      and returns the runtime bytecode. It should be run in an isolated environment,
+     *      not on a fork, as it modifies the code at the specified address.
+     * @param chainid The chain ID to simulate
+     * @param where The address where to deploy the contract
+     * @return The runtime bytecode of the Permit2 contract
+     */
    function getCode(
        uint256 chainid,
        address where
    ) public virtual returns (bytes memory) {

29-31: Add documentation for the wrapper function.

The wrapper function should also have documentation to explain its purpose and relationship to the main function.

+    /**
+     * @notice Gets the runtime bytecode for the Permit2 contract at the standard address
+     * @dev Wrapper function that calls getCode with the standard PERMIT2 address
+     * @param chainid The chain ID to simulate
+     * @return The runtime bytecode of the Permit2 contract
+     */
    function getCode(uint256 chainid) public virtual returns (bytes memory) {
        return getCode(chainid, PERMIT2);
    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between c5a892e and bbc2f46.

📒 Files selected for processing (2)
  • script/utils/permit2/Permit2Code.s.sol (1 hunks)
  • script/utils/permit2/verifyPermit2Bytecode.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • script/utils/permit2/verifyPermit2Bytecode.sh
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: run-unit-tests
  • GitHub Check: Analyze (javascript-typescript)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0