fix: revm evaluator — UUPS bypass, deployedBytecode, graceful attack ops
- Skip UUPS upgradeTo: etch + vm.store ERC1967 implementation slot directly (OptimizerV3Push3 is standalone, no UUPS inheritance needed for evolution) - Use deployedBytecode (runtime) instead of bytecode (creation) for vm.etch - Inject transpiled body into OptimizerV3.sol (has getLiquidityParams via Optimizer) instead of using standalone OptimizerV3Push3.sol - Wrap buy/sell/stake/unstake in try/catch — attack ops should not abort the batch - Add /tmp read to fs_permissions for batch-eval manifest files - Bootstrap recenter returns bool instead of reverting (soft-fail per candidate)
This commit is contained in:
parent
b34e26eb70
commit
87bb5859e2
3 changed files with 97 additions and 30 deletions
|
|
@ -39,7 +39,10 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
|||
ONCHAIN_DIR="$REPO_ROOT/onchain"
|
||||
TRANSPILER_DIR="$REPO_ROOT/tools/push3-transpiler"
|
||||
TRANSPILER_OUT="$ONCHAIN_DIR/src/OptimizerV3Push3.sol"
|
||||
ARTIFACT_PATH="$ONCHAIN_DIR/out/OptimizerV3Push3.sol/OptimizerV3Push3.json"
|
||||
# Use OptimizerV3 (inherits Optimizer → UUPS compatible, has getLiquidityParams)
|
||||
# instead of standalone OptimizerV3Push3 which lacks UUPS hooks.
|
||||
OPTIMIZERV3_SOL="$ONCHAIN_DIR/src/OptimizerV3.sol"
|
||||
ARTIFACT_PATH="$ONCHAIN_DIR/out/OptimizerV3.sol/OptimizerV3.json"
|
||||
DEFAULT_ATTACKS_DIR="$ONCHAIN_DIR/script/backtesting/attacks"
|
||||
|
||||
# =============================================================================
|
||||
|
|
@ -124,6 +127,64 @@ for PUSH3_FILE in "${PUSH3_FILES[@]}"; do
|
|||
continue
|
||||
fi
|
||||
|
||||
# Inject transpiled calculateParams body into OptimizerV3.sol (UUPS-compatible).
|
||||
# Extract function body from OptimizerV3Push3.sol and replace content between
|
||||
# BEGIN/END markers in OptimizerV3.sol.
|
||||
python3 - "$TRANSPILER_OUT" "$OPTIMIZERV3_SOL" <<'PYEOF' || {
|
||||
import sys
|
||||
|
||||
push3_path = sys.argv[1]
|
||||
v3_path = sys.argv[2]
|
||||
|
||||
# Extract function body from OptimizerV3Push3.sol
|
||||
# Find "function calculateParams" then extract everything between the opening { and
|
||||
# the matching closing } at the same indent level (4 spaces / function level)
|
||||
with open(push3_path) as f:
|
||||
push3 = f.read()
|
||||
|
||||
# Find body start: line after "function calculateParams...{"
|
||||
fn_start = push3.find("function calculateParams")
|
||||
if fn_start == -1:
|
||||
sys.exit("calculateParams not found in OptimizerV3Push3")
|
||||
brace_start = push3.find("{", fn_start)
|
||||
body_start = push3.index("\n", brace_start) + 1
|
||||
|
||||
# Find body end: the closing " }" of the function (4-space indent, before contract close)
|
||||
# Walk backwards from end to find the function-level closing brace
|
||||
lines = push3[body_start:].split("\n")
|
||||
body_lines = []
|
||||
for line in lines:
|
||||
if line.strip() == "}" and (line.startswith(" }") or line == "}"):
|
||||
# This is the function-closing brace
|
||||
break
|
||||
body_lines.append(line)
|
||||
|
||||
body = "\n".join(body_lines)
|
||||
|
||||
# Now inject into OptimizerV3.sol between markers
|
||||
with open(v3_path) as f:
|
||||
v3 = f.read()
|
||||
|
||||
begin_marker = "// ── BEGIN TRANSPILER OUTPUT"
|
||||
end_marker = "// ── END TRANSPILER OUTPUT"
|
||||
begin_idx = v3.find(begin_marker)
|
||||
end_idx = v3.find(end_marker)
|
||||
if begin_idx == -1 or end_idx == -1:
|
||||
sys.exit("markers not found in OptimizerV3.sol")
|
||||
|
||||
begin_line_end = v3.index("\n", begin_idx) + 1
|
||||
# Keep the end marker line intact
|
||||
with open(v3_path, "w") as f:
|
||||
f.write(v3[:begin_line_end])
|
||||
f.write(body + "\n")
|
||||
f.write(v3[end_idx:])
|
||||
|
||||
PYEOF
|
||||
log "WARNING: failed to inject calculateParams into OptimizerV3.sol for $CANDIDATE_ID — skipping"
|
||||
FAILED_IDS="$FAILED_IDS $CANDIDATE_ID"
|
||||
continue
|
||||
}
|
||||
|
||||
# Compile (forge's incremental build skips unchanged files quickly)
|
||||
FORGE_EC=0
|
||||
(cd "$ONCHAIN_DIR" && forge build --silent) >/dev/null 2>&1 || FORGE_EC=$?
|
||||
|
|
@ -139,7 +200,7 @@ for PUSH3_FILE in "${PUSH3_FILES[@]}"; do
|
|||
import json, sys
|
||||
with open(sys.argv[1]) as f:
|
||||
d = json.load(f)
|
||||
bytecode = d["bytecode"]["object"]
|
||||
bytecode = d["deployedBytecode"]["object"]
|
||||
# Ensure 0x prefix
|
||||
if not bytecode.startswith("0x"):
|
||||
bytecode = "0x" + bytecode
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue