From 404fe663a2e6021dbc298be1e4364ced1bdea92f Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2026 17:13:09 +0000 Subject: [PATCH 1/8] ci: hash-check old forge tarball and all solc before use --- .github/workflows/forge-old.yml | 46 +++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index 8f08b66c..ea1521ff 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -16,28 +16,34 @@ jobs: with: submodules: recursive - name: Install Foundry (old) - uses: foundry-rs/foundry-toolchain@908c540300062bd5a7e473851cdb4282204cee09 # v1.9.1 - with: - version: v1.5.1 - - name: Verify forge executable hash env: - EXPECTED_FORGE_SHA256: a39fc1913b53dde6a35b603756f65d799e13817ef694107ec0d3704c20435cce + FOUNDRY_VERSION: v1.5.1 + FOUNDRY_SHA256: 73640b01bd9ed29fdb4965085099371f8cf0dbbec3e2086cf54564efc4dcfe88 run: | - forge_path="$(which forge)" - echo "forge path: $forge_path" - actual="$(sha256sum "$forge_path" | awk '{print $1}')" - echo "actual: $actual" - echo "expected: $EXPECTED_FORGE_SHA256" - [ "$actual" = "$EXPECTED_FORGE_SHA256" ] || { echo "forge hash mismatch"; exit 1; } - - name: Install solc 0.8.34 into svm cache + archive="$RUNNER_TEMP/foundry.tar.gz" + curl -fsSL -o "$archive" \ + "https://github.com/foundry-rs/foundry/releases/download/$FOUNDRY_VERSION/foundry_${FOUNDRY_VERSION}_linux_amd64.tar.gz" + echo "$FOUNDRY_SHA256 $archive" | sha256sum -c - + mkdir -p "$RUNNER_TEMP/foundry-old" + tar -xzf "$archive" -C "$RUNNER_TEMP/foundry-old" + echo "$RUNNER_TEMP/foundry-old" >> "$GITHUB_PATH" + - name: Install solc into svm cache run: | - mkdir -p "$HOME/.svm/0.8.34" - curl -fsSL -o "$HOME/.svm/0.8.34/solc-0.8.34" \ - https://github.com/ethereum/solidity/releases/download/v0.8.34/solc-static-linux - chmod +x "$HOME/.svm/0.8.34/solc-0.8.34" - "$HOME/.svm/0.8.34/solc-0.8.34" --version + while read -r version sha256; do + solc="$HOME/.svm/$version/solc-$version" + mkdir -p "${solc%/*}" + curl -fsSL -o "$solc" "https://github.com/ethereum/solidity/releases/download/v$version/solc-static-linux" + echo "$sha256 $solc" | sha256sum -c - + chmod +x "$solc" + done <<'EOF' + 0.8.17 99f2070b776e9714f1f76c43c229cf99b8978a92938ee8d2364c6de11c1a03d4 + 0.8.19 7a5c1d3dc9a8eba62bb2ec37192c9178ae5fe8a54a56e5573fd3c9c17cd9eb48 + 0.8.21 f2857a898be15c69e8de5598dcd3f3e169e94964a0ce9a0bbb1b111f145a81df + 0.8.28 9a0fb7e0db2c0641dbae1c5cc645dc686820c83af516226abb1c0a2f76636f25 + 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39 + EOF - name: Build with Foundry (old) - run: forge build --force + run: forge build --force --offline - name: Collect version-pinned sources run: | mkdir -p compare @@ -61,11 +67,11 @@ jobs: done > compare/old.tsv [ -s compare/old.tsv ] || { echo "old manifest is empty"; exit 1; } - name: Run Forge tests - run: forge test + run: forge test --offline - name: Install Foundry uses: foundry-rs/foundry-toolchain@908c540300062bd5a7e473851cdb4282204cee09 # v1.9.1 - name: Build with Foundry - run: forge build --force --out out-new --cache-path cache-new + run: forge build --force --offline --out out-new --cache-path cache-new - name: Export bytecode manifest (new) run: | find out-new -name '*.json' -not -path '*/build-info/*' -print0 | sort -z | while IFS= read -r -d '' file; do From e6b82961e08b9eb095dc1e6c428b64987e8fb98a Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2026 08:46:52 +0000 Subject: [PATCH 2/8] ci: simplify forge-old workflows --- .github/workflows/forge-old.yml | 83 +++------------------------------ 1 file changed, 6 insertions(+), 77 deletions(-) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index ea1521ff..38f2ca60 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -16,17 +16,14 @@ jobs: with: submodules: recursive - name: Install Foundry (old) - env: - FOUNDRY_VERSION: v1.5.1 - FOUNDRY_SHA256: 73640b01bd9ed29fdb4965085099371f8cf0dbbec3e2086cf54564efc4dcfe88 run: | - archive="$RUNNER_TEMP/foundry.tar.gz" - curl -fsSL -o "$archive" \ - "https://github.com/foundry-rs/foundry/releases/download/$FOUNDRY_VERSION/foundry_${FOUNDRY_VERSION}_linux_amd64.tar.gz" - echo "$FOUNDRY_SHA256 $archive" | sha256sum -c - mkdir -p "$RUNNER_TEMP/foundry-old" - tar -xzf "$archive" -C "$RUNNER_TEMP/foundry-old" - echo "$RUNNER_TEMP/foundry-old" >> "$GITHUB_PATH" + cd "$RUNNER_TEMP/foundry-old" + curl -fsSL -o foundry.tar.gz https://github.com/foundry-rs/foundry/releases/download/v1.5.1/foundry_v1.5.1_linux_amd64.tar.gz + echo "73640b01bd9ed29fdb4965085099371f8cf0dbbec3e2086cf54564efc4dcfe88 foundry.tar.gz" | sha256sum -c - + tar -xzf foundry.tar.gz + rm foundry.tar.gz + echo "$PWD" >> "$GITHUB_PATH" - name: Install solc into svm cache run: | while read -r version sha256; do @@ -42,73 +39,5 @@ jobs: 0.8.28 9a0fb7e0db2c0641dbae1c5cc645dc686820c83af516226abb1c0a2f76636f25 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39 EOF - - name: Build with Foundry (old) - run: forge build --force --offline - - name: Collect version-pinned sources - run: | - mkdir -p compare - # Only sources that pin an exact solc version are comparable across forge - # versions. A range pragma resolves to whatever solc each forge knows about, - # and a contract compiled under several compiler profiles has its artifact - # path disambiguated differently from one forge version to the next, so - # range-pragma artifacts report spurious mismatches. Everything that is - # actually deployed pins its version, so scope the manifests to those. - grep -rlE --include='*.sol' 'pragma solidity[[:space:]]+[=0-9]' src lib \ - | sed 's|.*/||' | LC_ALL=C sort -u > compare/pinned.txt - [ -s compare/pinned.txt ] || { echo "no version-pinned sources found"; exit 1; } - echo "version-pinned sources: $(wc -l < compare/pinned.txt)" - - name: Export bytecode manifest (old) - run: | - find out -name '*.json' -not -path '*/build-info/*' -print0 | sort -z | while IFS= read -r -d '' file; do - rel="${file#out/}" - source="${rel%/*}" - grep -qxF "${source##*/}" compare/pinned.txt || continue - jq -r --arg rel "$rel" '[$rel, (.bytecode.object // ""), (.deployedBytecode.object // "")] | @tsv' "$file" - done > compare/old.tsv - [ -s compare/old.tsv ] || { echo "old manifest is empty"; exit 1; } - name: Run Forge tests run: forge test --offline - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@908c540300062bd5a7e473851cdb4282204cee09 # v1.9.1 - - name: Build with Foundry - run: forge build --force --offline --out out-new --cache-path cache-new - - name: Export bytecode manifest (new) - run: | - find out-new -name '*.json' -not -path '*/build-info/*' -print0 | sort -z | while IFS= read -r -d '' file; do - rel="${file#out-new/}" - source="${rel%/*}" - grep -qxF "${source##*/}" compare/pinned.txt || continue - jq -r --arg rel "$rel" '[$rel, (.bytecode.object // ""), (.deployedBytecode.object // "")] | @tsv' "$file" - done > compare/new.tsv - [ -s compare/new.tsv ] || { echo "new manifest is empty"; exit 1; } - - name: Compare bytecode - run: | - if cmp -s compare/old.tsv compare/new.tsv; then - echo "bytecode is identical" - exit 0 - fi - cut -f1 compare/old.tsv | LC_ALL=C sort > compare/old.names - cut -f1 compare/new.tsv | LC_ALL=C sort > compare/new.names - LC_ALL=C comm -23 compare/old.names compare/new.names > compare/only-old - LC_ALL=C comm -13 compare/old.names compare/new.names > compare/only-new - awk -F'\t' ' - NR == FNR { bytecode[$1] = $2; deployed[$1] = $3; next } - !($1 in bytecode) { next } - { - which = "" - if (bytecode[$1] != $2) which = "bytecode" - if (deployed[$1] != $3) which = (which == "" ? "deployedBytecode" : which ", deployedBytecode") - if (which != "") print $1 " (" which ")" - } - ' compare/old.tsv compare/new.tsv > compare/changed - report() { - count="$(wc -l < "$2")" - [ "$count" -eq 0 ] && return 0 - echo "$1 ($count):" - sed 's/^/ /' "$2" - echo "::error title=$1 ($count)::$(head -n 20 "$2" | sed 's/$/%0A/' | tr -d '\n')" - } - report "Artifacts only in the old build" compare/only-old - report "Artifacts only in the new build" compare/only-new - report "Artifacts whose bytecode changed" compare/changed - exit 1 From 3d3f9270b706336bf6f4bfd155ad8bf501669ca0 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2026 08:53:26 +0000 Subject: [PATCH 3/8] ci: rename old forge job --- .github/workflows/forge-old.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index 38f2ca60..6c8a8e6f 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: jobs: - compare-bytecode: + forge-old: runs-on: ubuntu-latest steps: - name: Checkout repository From 83c1ced5e325ace3c73096c11320e25747edfeab Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:11:46 +0000 Subject: [PATCH 4/8] ci: pipe pinned solcs into installer loop --- .github/workflows/forge-old.yml | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index 6c8a8e6f..a573fa08 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -26,18 +26,16 @@ jobs: echo "$PWD" >> "$GITHUB_PATH" - name: Install solc into svm cache run: | - while read -r version sha256; do - solc="$HOME/.svm/$version/solc-$version" - mkdir -p "${solc%/*}" - curl -fsSL -o "$solc" "https://github.com/ethereum/solidity/releases/download/v$version/solc-static-linux" - echo "$sha256 $solc" | sha256sum -c - - chmod +x "$solc" - done <<'EOF' - 0.8.17 99f2070b776e9714f1f76c43c229cf99b8978a92938ee8d2364c6de11c1a03d4 - 0.8.19 7a5c1d3dc9a8eba62bb2ec37192c9178ae5fe8a54a56e5573fd3c9c17cd9eb48 - 0.8.21 f2857a898be15c69e8de5598dcd3f3e169e94964a0ce9a0bbb1b111f145a81df - 0.8.28 9a0fb7e0db2c0641dbae1c5cc645dc686820c83af516226abb1c0a2f76636f25 - 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39 - EOF + echo "0.8.17 99f2070b776e9714f1f76c43c229cf99b8978a92938ee8d2364c6de11c1a03d4 + 0.8.19 7a5c1d3dc9a8eba62bb2ec37192c9178ae5fe8a54a56e5573fd3c9c17cd9eb48 + 0.8.21 f2857a898be15c69e8de5598dcd3f3e169e94964a0ce9a0bbb1b111f145a81df + 0.8.28 9a0fb7e0db2c0641dbae1c5cc645dc686820c83af516226abb1c0a2f76636f25 + 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39" | while read -r version sha256; do + solc="$HOME/.svm/$version/solc-$version" + mkdir -p "${solc%/*}" + curl -fsSL -o "$solc" "https://github.com/ethereum/solidity/releases/download/v$version/solc-static-linux" + echo "$sha256 $solc" | sha256sum -c - + chmod +x "$solc" + done - name: Run Forge tests run: forge test --offline From 40a4f3de0cdf4275a85e4d1b4852313b9c9d3118 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:15:30 +0000 Subject: [PATCH 5/8] ci: align solc installer indentation --- .github/workflows/forge-old.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index a573fa08..9bc646c6 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -26,16 +26,16 @@ jobs: echo "$PWD" >> "$GITHUB_PATH" - name: Install solc into svm cache run: | - echo "0.8.17 99f2070b776e9714f1f76c43c229cf99b8978a92938ee8d2364c6de11c1a03d4 - 0.8.19 7a5c1d3dc9a8eba62bb2ec37192c9178ae5fe8a54a56e5573fd3c9c17cd9eb48 - 0.8.21 f2857a898be15c69e8de5598dcd3f3e169e94964a0ce9a0bbb1b111f145a81df - 0.8.28 9a0fb7e0db2c0641dbae1c5cc645dc686820c83af516226abb1c0a2f76636f25 - 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39" | while read -r version sha256; do - solc="$HOME/.svm/$version/solc-$version" - mkdir -p "${solc%/*}" - curl -fsSL -o "$solc" "https://github.com/ethereum/solidity/releases/download/v$version/solc-static-linux" - echo "$sha256 $solc" | sha256sum -c - - chmod +x "$solc" - done + echo "0.8.17 99f2070b776e9714f1f76c43c229cf99b8978a92938ee8d2364c6de11c1a03d4 + 0.8.19 7a5c1d3dc9a8eba62bb2ec37192c9178ae5fe8a54a56e5573fd3c9c17cd9eb48 + 0.8.21 f2857a898be15c69e8de5598dcd3f3e169e94964a0ce9a0bbb1b111f145a81df + 0.8.28 9a0fb7e0db2c0641dbae1c5cc645dc686820c83af516226abb1c0a2f76636f25 + 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39" | while read -r version sha256; do + solc="$HOME/.svm/$version/solc-$version" + mkdir -p "${solc%/*}" + curl -fsSL -o "$solc" "https://github.com/ethereum/solidity/releases/download/v$version/solc-static-linux" + echo "$sha256 $solc" | sha256sum -c - + chmod +x "$solc" + done - name: Run Forge tests run: forge test --offline From 23e12a06c68adde8a0bccbd0be7b4762937f6dfb Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:22:01 +0000 Subject: [PATCH 6/8] ci: simplify pinned old Forge installation --- .github/workflows/forge-old.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index 9bc646c6..9b0a3080 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -17,13 +17,10 @@ jobs: submodules: recursive - name: Install Foundry (old) run: | - mkdir -p "$RUNNER_TEMP/foundry-old" - cd "$RUNNER_TEMP/foundry-old" curl -fsSL -o foundry.tar.gz https://github.com/foundry-rs/foundry/releases/download/v1.5.1/foundry_v1.5.1_linux_amd64.tar.gz echo "73640b01bd9ed29fdb4965085099371f8cf0dbbec3e2086cf54564efc4dcfe88 foundry.tar.gz" | sha256sum -c - - tar -xzf foundry.tar.gz - rm foundry.tar.gz - echo "$PWD" >> "$GITHUB_PATH" + tar -xzf foundry.tar.gz -C "$RUNNER_TEMP" + echo "$RUNNER_TEMP" >> "$GITHUB_PATH" - name: Install solc into svm cache run: | echo "0.8.17 99f2070b776e9714f1f76c43c229cf99b8978a92938ee8d2364c6de11c1a03d4 From c7803a15c33280d8241285607dec8828034e0b08 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:27:09 +0000 Subject: [PATCH 7/8] ci: update old Forge and solc install scripts --- .github/workflows/forge-old.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index 9b0a3080..d3cb1add 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -19,15 +19,17 @@ jobs: run: | curl -fsSL -o foundry.tar.gz https://github.com/foundry-rs/foundry/releases/download/v1.5.1/foundry_v1.5.1_linux_amd64.tar.gz echo "73640b01bd9ed29fdb4965085099371f8cf0dbbec3e2086cf54564efc4dcfe88 foundry.tar.gz" | sha256sum -c - - tar -xzf foundry.tar.gz -C "$RUNNER_TEMP" - echo "$RUNNER_TEMP" >> "$GITHUB_PATH" + mkdir "$RUNNER_TEMP/foundry" + tar -xzf foundry.tar.gz -C "$RUNNER_TEMP/foundry" + echo "$RUNNER_TEMP/foundry" >> "$GITHUB_PATH" - name: Install solc into svm cache run: | echo "0.8.17 99f2070b776e9714f1f76c43c229cf99b8978a92938ee8d2364c6de11c1a03d4 0.8.19 7a5c1d3dc9a8eba62bb2ec37192c9178ae5fe8a54a56e5573fd3c9c17cd9eb48 0.8.21 f2857a898be15c69e8de5598dcd3f3e169e94964a0ce9a0bbb1b111f145a81df 0.8.28 9a0fb7e0db2c0641dbae1c5cc645dc686820c83af516226abb1c0a2f76636f25 - 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39" | while read -r version sha256; do + 0.8.34 d40adc6f9fdbb22a97d32a02fa05688bf2ee7886affc48c9851b0afd4a726b39" | + while read -r version sha256; do solc="$HOME/.svm/$version/solc-$version" mkdir -p "${solc%/*}" curl -fsSL -o "$solc" "https://github.com/ethereum/solidity/releases/download/v$version/solc-static-linux" From a204c9852bad6d385dd0dbe4f472d2289ba153c0 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:39:44 +0000 Subject: [PATCH 8/8] ci: restrict forge-old token to contents: read --- .github/workflows/forge-old.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/forge-old.yml b/.github/workflows/forge-old.yml index d3cb1add..a4725938 100644 --- a/.github/workflows/forge-old.yml +++ b/.github/workflows/forge-old.yml @@ -7,6 +7,9 @@ on: pull_request: workflow_dispatch: +permissions: + contents: read + jobs: forge-old: runs-on: ubuntu-latest