Add FeeDestinationSet and FeeDestinationLocked events to LiquidityManager,
emitted on every setFeeDestination() call and lock engagement respectively.
Update tests to assert both events are emitted in all code paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
AGENTS.md principle #1/#3 forbids fixed delays. When evolution.patch fails
the pre-flight --check, exit 1 lets the process supervisor handle restart
timing instead of a hardcoded sleep 300 busy-spin.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When git apply --check fails, the daemon now sleeps 300s before retrying,
preventing a tight busy loop that would hammer the git remote indefinitely.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the two per-slot require checks with a loop over all 8 input slots
so future subclasses using slots 2-7 are protected from silent uint256 wrap.
Add testCalculateParamsRevertsOnNegativeMantissaSlots2to7 to verify the guard.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add llm_balanced.push3: arithmetic-only optimizer that keeps all
outputs in a balanced mid-range. anchorShare=40-60% (linear with
percentageStaked), anchorWidth=10-200 ticks (linear with taxRate),
discoveryDepth=30-50% (linear with percentageStaked), ci=0. No
EXEC.IF branches — all transitions via multiplication and division.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 30-way threshold lookup in optimizer_seed.push3 generates enough
local variables to trigger "Stack too deep" without IR compilation.
Add via_ir = true to the minimal foundry.toml created in both test
scripts, matching the setting in onchain/foundry.toml.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- test_transpiler_clamping.sh: add Test 11 that runs forge build on the
valid Solidity output from Test 6; fails if the transpiled contract
does not compile (regression guard for #900)
- test_inject_extraction.sh: add SCRIPT_DIR, then Test 5 that transpiles
optimizer_seed.push3 and runs forge build on the generated contract;
ensures the full push3→Solidity→compile pipeline stays green
- .woodpecker/ci.yml: add transpiler-tests step that installs npm deps
and runs both test scripts with forge on PATH
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous guard blocked setFeeDestination when feeDestination.code.length > 0
but did not persist feeDestinationLocked — a revert undoes all state changes. An
attacker could CREATE2-deploy bytecode to the EOA fee destination, triggering the
block, then SELFDESTRUCT to clear the code, then call setFeeDestination again
successfully (lock was never committed).
Fix: detect bytecode at the current feeDestination first; if found, set
feeDestinationLocked = true and RETURN (not revert) so the storage write is
committed. A subsequent SELFDESTRUCT cannot undo a committed storage slot.
Updated NatSpec documents both the protection and the remaining limitation
(atomic CREATE2+SELFDESTRUCT in a single tx cannot be detected).
Added testSetFeeDestination_CREATE2BytecodeDetection_Locks covering:
set EOA → vm.etch (simulate CREATE2 deploy) → verify lock committed → vm.etch
empty (simulate selfdestruct) → verify setter still blocked.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Make V3_FACTORY injectable via vm.envOr("V3_FACTORY", DEFAULT_V3_FACTORY),
preserving the Base mainnet address as the default for existing fork runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add detect_swap_router() that queries chain ID from $ANVIL_RPC and selects
the Base mainnet SwapRouter (0x2626...e481) for chain ID 8453, falling back
to Base Sepolia (0x94cC...2bc4) for all other networks. Called lazily with
idempotency from bootstrap_vwap() and seed_application_state().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
red-team.sh produces the stream JSONL that export-attacks.py parses, so
they must agree on addresses. Update SWAP_ROUTER and NPM in red-team.sh
to Base Sepolia and fix the invariant comment in export-attacks.py.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update SWAP_ROUTER_ADDR and NPM_ADDR in export-attacks.py from Base
mainnet addresses to the correct Base Sepolia addresses, matching
helpers/market.ts and helpers/swap.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>