fix: No upper-bound validation for ci/anchorShare/discoveryDepth outputs (#960)
Add assertUint256Max1e18 validator in index.ts and apply it to the ci, anchorShare, and discoveryDepth output literals. Programs emitting values > 1e18 for these fields now fail with a clear transpiler-level error instead of silently violating LiquidityManager invariants at runtime. Add tests 12-14 in test_transpiler_clamping.sh covering the over-range rejection for each of the three fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0e10d091a6
commit
8fbac32717
2 changed files with 65 additions and 0 deletions
|
|
@ -51,6 +51,23 @@ function assertUint24Range(value: string, name: string): void {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a transpiler output variable for a uint256 field scaled to 1e18
|
||||
* does not exceed 1e18 when it is a literal constant. Values > 1e18 violate
|
||||
* LiquidityManager invariants (these fields represent fractions in [0, 1]).
|
||||
*/
|
||||
function assertUint256Max1e18(value: string, name: string): void {
|
||||
if (INT_LITERAL_RE.test(value)) {
|
||||
const n = BigInt(value);
|
||||
if (n > 1000000000000000000n) {
|
||||
throw new Error(
|
||||
`Transpiler error: ${name} literal (${value}) exceeds 1e18 (max allowed). ` +
|
||||
`Fix the Push3 program to produce a value in [0, 1e18] for ${name}.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function main(): void {
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length < 2) {
|
||||
|
|
@ -70,9 +87,12 @@ function main(): void {
|
|||
const { functionBody, ciVar, anchorShareVar, anchorWidthVar, discoveryDepthVar } = transpile(ast);
|
||||
|
||||
assertNonNegativeLiteral(ciVar, 'ci');
|
||||
assertUint256Max1e18(ciVar, 'ci');
|
||||
assertNonNegativeLiteral(anchorShareVar, 'anchorShare');
|
||||
assertUint256Max1e18(anchorShareVar, 'anchorShare');
|
||||
assertUint24Range(anchorWidthVar, 'anchorWidth');
|
||||
assertNonNegativeLiteral(discoveryDepthVar, 'discoveryDepth');
|
||||
assertUint256Max1e18(discoveryDepthVar, 'discoveryDepth');
|
||||
|
||||
const solidityLines = [
|
||||
'// SPDX-License-Identifier: GPL-3.0-or-later',
|
||||
|
|
|
|||
|
|
@ -217,6 +217,51 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
# ── Test 12: ci literal > 1e18 → transpiler error ────────────────────────────
|
||||
echo "Test 12: ci = 2e18 (literal) → transpiler error"
|
||||
|
||||
STDERR=$(run_transpiler "(
|
||||
300000000000000000
|
||||
100
|
||||
300000000000000000
|
||||
2000000000000000000
|
||||
)")
|
||||
|
||||
assert_contains \
|
||||
"ci 2e18: transpiler emits max1e18 error message" \
|
||||
"$STDERR" \
|
||||
"ci literal (2000000000000000000) exceeds 1e18 (max allowed)"
|
||||
|
||||
# ── Test 13: anchorShare literal > 1e18 → transpiler error ───────────────────
|
||||
echo "Test 13: anchorShare = 2e18 (literal) → transpiler error"
|
||||
|
||||
STDERR=$(run_transpiler "(
|
||||
300000000000000000
|
||||
100
|
||||
2000000000000000000
|
||||
0
|
||||
)")
|
||||
|
||||
assert_contains \
|
||||
"anchorShare 2e18: transpiler emits max1e18 error message" \
|
||||
"$STDERR" \
|
||||
"anchorShare literal (2000000000000000000) exceeds 1e18 (max allowed)"
|
||||
|
||||
# ── Test 14: discoveryDepth literal > 1e18 → transpiler error ────────────────
|
||||
echo "Test 14: discoveryDepth = 2e18 (literal) → transpiler error"
|
||||
|
||||
STDERR=$(run_transpiler "(
|
||||
2000000000000000000
|
||||
100
|
||||
300000000000000000
|
||||
0
|
||||
)")
|
||||
|
||||
assert_contains \
|
||||
"discoveryDepth 2e18: transpiler emits max1e18 error message" \
|
||||
"$STDERR" \
|
||||
"discoveryDepth literal (2000000000000000000) exceeds 1e18 (max allowed)"
|
||||
|
||||
# ── Summary ──────────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue