harb/tools/push3-transpiler/test_transpiler_clamping.sh
openhands 1e75285579 fix: fix: transpiler outputs raw int literals for uint24 anchorWidth — overflow crashes forge (#900)
Clamp anchorWidth output with `% (2**24)` before the uint24 cast so that
large literal values (e.g. 1e18 from evolved constants) produce valid
Solidity instead of a compile-time overflow error.

Add test_transpiler_clamping.sh (Test 5) verifying that a Push3 program
outputting 1e18 for anchorWidth generates `uint24(... % (2**24))` and not
the raw overflowing literal. Update package.json to run both test suites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 06:40:30 +00:00

88 lines
2.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# test_transpiler_clamping.sh — Tests that the transpiler clamps anchorWidth to uint24 bounds.
# Verifies that a Push3 program producing 1e18 for anchorWidth generates
# `uint24(... % (2**24))` rather than a raw overflowing literal.
# Exit: 0 if all tests pass, 1 if any fail.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PASS=0
FAIL=0
assert_contains() {
local name="$1"
local output="$2"
local expected="$3"
if echo "$output" | grep -qF "$expected"; then
echo " PASS: $name"
PASS=$((PASS + 1))
else
echo " FAIL: $name"
echo " expected to contain: $expected"
echo " actual output:"
echo "$output" | sed 's/^/ /'
FAIL=$((FAIL + 1))
fi
}
assert_not_contains() {
local name="$1"
local output="$2"
local pattern="$3"
if echo "$output" | grep -qF "$pattern"; then
echo " FAIL: $name"
echo " expected NOT to contain: $pattern"
echo " actual output:"
echo "$output" | sed 's/^/ /'
FAIL=$((FAIL + 1))
else
echo " PASS: $name"
PASS=$((PASS + 1))
fi
}
# ── Ensure node_modules exist ────────────────────────────────────────────────
if [ ! -d "$SCRIPT_DIR/node_modules" ]; then
(cd "$SCRIPT_DIR" && npm install --silent)
fi
# ── Test 5: anchorWidth = 1e18 is clamped to uint24 range ───────────────────
echo "Test 5: anchorWidth overflow clamped via % (2**24)"
TMPDIR_T=$(mktemp -d)
trap 'rm -rf "$TMPDIR_T"' EXIT
INPUT_PUSH3="$TMPDIR_T/overflow.push3"
OUTPUT_SOL="$TMPDIR_T/overflow.sol"
# Push3 program: push 4 values (discoveryDepth, anchorWidth=1e18, anchorShare, ci).
# The transpiler pops top-4 from DYADIC stack; these literals sit on top of the
# primed input slots, so they become the 4 output vars.
cat > "$INPUT_PUSH3" <<'PUSH3EOF'
(
300000000000000000
1000000000000000000
300000000000000000
0
)
PUSH3EOF
(cd "$SCRIPT_DIR" && node --loader ts-node/esm src/index.ts "$INPUT_PUSH3" "$OUTPUT_SOL" 2>/dev/null)
SOL_CONTENT=$(cat "$OUTPUT_SOL")
assert_not_contains \
"anchorWidth: no raw uint24(1000000000000000000) literal" \
"$SOL_CONTENT" \
"uint24(1000000000000000000)"
assert_contains \
"anchorWidth: output uses % (2**24) clamping" \
"$SOL_CONTENT" \
"uint24(1000000000000000000 % (2**24))"
# ── Summary ──────────────────────────────────────────────────────────────────
echo ""
echo "Results: $PASS passed, $FAIL failed"
[ "$FAIL" -eq 0 ]