Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions .github/workflows/validate-addresses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Validate Address Liveness

on:
workflow_dispatch:
schedule:
# Run weekly on Sunday at 00:00 UTC
- cron: '0 0 * * 0'
pull_request:
paths:
- 'mainnet/**'
- 'sepolia/**'
- 'sepolia-alpha/**'
- 'zeronet/**'
- '.github/workflows/validate-addresses.yml'

jobs:
validate-addresses:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install mise-managed toolchain
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1
with:
experimental: true

- name: Validate addresses for network
env:
NETWORK: ${{ matrix.network }}
strategy:
matrix:
include:
- network: mainnet
rpc_url_env: L1_RPC_URL
- network: sepolia
rpc_url_env: L1_RPC_URL
- network: sepolia-alpha
rpc_url_env: L1_RPC_URL
- network: zeronet
rpc_url_env: L1_RPC_URL
run: |
set -e

echo "=== Validating addresses for ${{ matrix.network }} ==="

# Source the network .env
set -a
source ${{ matrix.network }}/.env
set +a

RPC_URL="${!{{ matrix.rpc_url_env }}}"
if [ -z "$RPC_URL" ]; then
echo "ERROR: ${{ matrix.rpc_url_env }} not set in ${{ matrix.network }}/.env"
exit 1
fi

# Verify chain ID matches expected
case "${{ matrix.network }}" in
mainnet) EXPECTED_CHAIN_ID=8453 ;;
sepolia) EXPECTED_CHAIN_ID=11155111 ;;
sepolia-alpha) EXPECTED_CHAIN_ID=11763071 ;;
zeronet) EXPECTED_CHAIN_ID=127808 ;;
esac

ACTUAL_CHAIN_ID=$(cast chain-id --rpc-url "$RPC_URL")
if [ "$ACTUAL_CHAIN_ID" != "$EXPECTED_CHAIN_ID" ]; then
echo "ERROR: Chain ID mismatch for ${{ matrix.network }}"
echo " Expected: $EXPECTED_CHAIN_ID"
echo " Actual: $ACTUAL_CHAIN_ID"
exit 1
fi
echo " OK: Chain ID matches expected ($ACTUAL_CHAIN_ID)"

# Extract all *_ADDR and *_PROXY variables from .env and validate they have code
ENV_FILE="${{ matrix.network }}/.env"
ERROR_COUNT=0

while IFS='=' read -r key value; do
# Skip comments and empty lines
if [[ "$key" =~ ^# ]] || [[ -z "$key" ]]; then
continue
fi

# Check if key ends with _ADDR or _PROXY
if [[ "$key" =~ _ADDR$ ]] || [[ "$key" =~ _PROXY$ ]]; then
addr="$value"
# Skip placeholder values
if [[ "$addr" == "<"*">"* ]] || [[ -z "$addr" ]]; then
echo " SKIP: $key (placeholder)"
continue
fi

# Check if address is a valid eth address
if ! [[ "$addr" =~ ^0x[0-9a-fA-F]{40}$ ]]; then
echo " SKIP: $key (not a valid address: $addr)"
continue
fi

code=$(cast code "$addr" --rpc-url "$RPC_URL" 2>/dev/null || echo "0x")
if [ "$code" == "0x" ] || [ -z "$code" ]; then
echo " ERROR: $key=$addr — no contract code found at this address"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: $key=$addr (code length: ${#code})"
fi
fi
done < "$ENV_FILE"

echo ""
if [ $ERROR_COUNT -gt 0 ]; then
echo "VALIDATION FAILED: $ERROR_COUNT address(es) have no code"
exit 1
else
echo "All addresses validated successfully."
fi
122 changes: 122 additions & 0 deletions .github/workflows/validate-task-schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Validate Task Schema

on:
pull_request:
paths:
- 'mainnet/**'
- 'sepolia/**'
- 'sepolia-alpha/**'
- 'zeronet/**'

jobs:
validate-task-schema:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Validate task schema
run: |
set -e

# Get the list of task directories changed in this PR
CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD)
CHANGED_TASKS=$(echo "$CHANGED_FILES" | grep -oE '[^/]+/[0-9]{4}-[0-9]{2}-[^/]+' | sort -u)

if [ -z "$CHANGED_TASKS" ]; then
echo "No task directories changed."
exit 0
fi

echo "Validating tasks: $CHANGED_TASKS"
ERROR_COUNT=0

for TASK in $CHANGED_TASKS; do
TASK_DIR="$TASK"
echo ""
echo "=== Checking: $TASK_DIR ==="

# Check README.md exists and has Status field
if [ ! -f "$TASK_DIR/README.md" ]; then
echo " ERROR: README.md not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
if ! grep -q "Status: READY TO SIGN\|Status: EXECUTED" "$TASK_DIR/README.md"; then
echo " ERROR: README.md missing 'Status: READY TO SIGN' or 'Status: EXECUTED'"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: README.md has Status field"
fi
fi

# Check Makefile exists
if [ ! -f "$TASK_DIR/Makefile" ]; then
echo " ERROR: Makefile not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
if ! grep -q "../../Makefile\|../../Multisig.mk" "$TASK_DIR/Makefile"; then
echo " ERROR: Makefile missing standard includes (../../Makefile or ../../Multisig.mk)"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: Makefile has standard includes"
fi
fi

# Check foundry.toml exists
if [ ! -f "$TASK_DIR/foundry.toml" ]; then
echo " ERROR: foundry.toml not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: foundry.toml found"
fi

# Check script/ contains at least one .sol file
if [ ! -d "$TASK_DIR/script" ]; then
echo " ERROR: script/ directory not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
elif [ -z "$(ls "$TASK_DIR/script/"*.sol 2>/dev/null)" ]; then
echo " ERROR: script/ contains no .sol files"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: script/ has .sol files"
fi

# Check FACILITATOR.md exists
if [ ! -f "$TASK_DIR/FACILITATOR.md" ]; then
echo " ERROR: FACILITATOR.md not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: FACILITATOR.md found"
fi

# Check .env exists
if [ ! -f "$TASK_DIR/.env" ]; then
echo " ERROR: .env not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: .env found"
fi

# Check validations/ exists
if [ ! -d "$TASK_DIR/validations" ]; then
echo " ERROR: validations/ directory not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: validations/ found"
fi

# Check records/ exists
if [ ! -d "$TASK_DIR/records" ]; then
echo " ERROR: records/ directory not found"
ERROR_COUNT=$((ERROR_COUNT + 1))
else
echo " OK: records/ found"
fi
done

echo ""
if [ $ERROR_COUNT -gt 0 ]; then
echo "VALIDATION FAILED: $ERROR_COUNT error(s) found"
exit 1
else
echo "All tasks passed schema validation."
fi
11 changes: 11 additions & 0 deletions .github/workflows/validate-templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,14 @@ jobs:
echo "::error::Compilation failed for ${{ matrix.template }}. Check imports, types, and dependency versions."
exit 1
fi

- name: Check exact pragma versions (no range pragmas)
working-directory: ${{ steps.setup.outputs.task_dir }}
run: |
echo "==> checking for range pragmas in script/ (${{ matrix.template }})"
if grep -r "pragma solidity \^[0-9]" script/; then
echo ""
echo "::error::Range pragmas (^) found in script/. Use exact versions (e.g., 'pragma solidity 0.8.15'). See AGENTS.md."
exit 1
fi
echo " OK: No range pragmas found"