fix: feat: red-team memory should track candidate + abstract learnings (#820)
- Add CANDIDATE_NAME and OPTIMIZER_PROFILE env vars to red-team.sh (defaults to "unknown" for standalone runs) - Update extract_memory Python: new fields candidate, optimizer_profile, pattern (abstract op sequence via make_pattern()), and improved insight extraction that also captures WHY explanations (because/since/due to) - Update MEMORY_SECTION Python: entries now grouped by candidate; universal patterns (DECREASED across multiple candidates) surfaced first - Update prompt: add "Current Attack Target" table with candidate/profile, optimizer parameter explanations (CI/AW/AS/DD behavioral impact), Rule 9 requiring pattern+insight per strategy, updated report format with Pattern/Insight fields and universal-pattern conclusion field - Update red-team-sweep.sh: after inject, parse OptimizerV3Push3.sol for r40/r39/r38/r37 constants to build OPTIMIZER_PROFILE string; pass CANDIDATE_NAME and OPTIMIZER_PROFILE as env vars to red-team.sh Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7a09c16966
commit
e7c60edeb6
2 changed files with 147 additions and 14 deletions
|
|
@ -63,12 +63,45 @@ for seed_file in "${seeds[@]}"; do
|
|||
fi
|
||||
log "Injected into OptimizerV3.sol"
|
||||
|
||||
# 1b. Extract optimizer profile from transpiler output (CI/AW/AS/DD constants)
|
||||
TRANSPILER_OUT="$REPO_ROOT/onchain/src/OptimizerV3Push3.sol"
|
||||
OPTIMIZER_PROFILE=$(python3 - "$TRANSPILER_OUT" <<'PYEOF'
|
||||
import re, sys
|
||||
try:
|
||||
with open(sys.argv[1]) as f:
|
||||
sol = f.read()
|
||||
ci_vals = set(re.findall(r'\br40\s*=\s*uint256\((\d+)\)', sol))
|
||||
aw_vals = set(re.findall(r'\br38\s*=\s*uint256\((\d+)\)', sol))
|
||||
as_vals = set(re.findall(r'\br39\s*=\s*uint256\((\d+)\)', sol))
|
||||
dd_vals = set(re.findall(r'\br37\s*=\s*uint256\((\d+)\)', sol))
|
||||
|
||||
def fmt_pct(vals):
|
||||
pcts = sorted(set(round(int(v) * 100 / 1e18) for v in vals))
|
||||
return '/'.join(str(p) + '%' for p in pcts) if pcts else '?'
|
||||
|
||||
def fmt_int(vals):
|
||||
ints = sorted(set(int(v) for v in vals))
|
||||
return '/'.join(str(v) for v in ints) if ints else '?'
|
||||
|
||||
profile = f"CI={fmt_pct(ci_vals)}, AW={fmt_int(aw_vals)}, AS={fmt_pct(as_vals)}, DD={fmt_pct(dd_vals)}"
|
||||
if len(ci_vals) > 1 or len(aw_vals) > 1 or len(as_vals) > 1 or len(dd_vals) > 1:
|
||||
profile += ", adaptive"
|
||||
print(profile)
|
||||
except Exception as e:
|
||||
import sys as _sys
|
||||
print(f"unknown (parse error: {e})", file=_sys.stderr)
|
||||
print("unknown")
|
||||
PYEOF
|
||||
)
|
||||
log "Optimizer profile: $OPTIMIZER_PROFILE"
|
||||
|
||||
# 2. Clear stale attack file from previous candidate
|
||||
rm -f "$REPO_ROOT/tmp/red-team-attacks.jsonl"
|
||||
|
||||
# 3. Run red-team.sh (handles bootstrap + compile + deploy + attack)
|
||||
log "Running red-team.sh (timeout: ${TIMEOUT_PER}s)..."
|
||||
CLAUDE_TIMEOUT="$TIMEOUT_PER" timeout "$((TIMEOUT_PER + 120))" \
|
||||
CLAUDE_TIMEOUT="$TIMEOUT_PER" CANDIDATE_NAME="$seed_name" OPTIMIZER_PROFILE="$OPTIMIZER_PROFILE" \
|
||||
timeout "$((TIMEOUT_PER + 120))" \
|
||||
bash "$SCRIPT_DIR/red-team.sh" 2>&1 | tee "/tmp/red-team-${seed_name}.log" || true
|
||||
|
||||
# 4. Collect attacks
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue