Commit graph

339 commits

Author SHA1 Message Date
Agent
47a02cab92 chore: gardener housekeeping 2026-04-05
AGENTS.md watermarks refreshed to HEAD (62ba6f2).

Content updates:
- root AGENTS.md: added Docker/LXD notes (apparmor=unconfined, umami port 3001),
  viem v2 slot0 array pattern to Key Patterns
- services/ponder/AGENTS.md: documented LM_ADDRESS, POOL_ADDRESS, and
  MINIMUM_BLOCKS_FOR_RINGBUFFER env vars; added zero-stats troubleshooting note
- web-app/AGENTS.md: added viem v2 slot0 array compat section

Grooming: no open issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 18:04:27 +00:00
johba
bff29e75a1 chore: gardener housekeeping 2026-03-27
AGENTS.md watermarks refreshed to HEAD (79a93d4).

Grooming: closed 2 prediction/actioned issues.
- #1179: /stakestake fix verified working in post-fix user-test (2026-03-27)
- #1177: fresh red-team session 2026-03-27 with 7 real attacks (floor_held)
Remaining open: #1166, #1141 (prediction/backlog, planner watching),
#857, #856, #383 (vision).
No blocked issues, no open PRs, no stale PRs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 18:04:08 +00:00
johba
ca7162fedb chore: gardener housekeeping 2026-03-27
AGENTS.md watermarks refreshed to HEAD (7d72f40).
landing/AGENTS.md: document new pitch-deck.html (influencer outreach).

Grooming: CLEAN — 5 open issues (2 prediction/backlog, 3 vision), no
backlog issues, no blocked issues, no open PRs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 06:03:33 +00:00
johba
cbc3c3fd8e chore: gardener housekeeping 2026-03-26
AGENTS.md watermarks refreshed to HEAD (4dedc72). Watermark bump only —
no code changes since last gardener run.

Pending actions (3): re-queue promotion of #1155 pitch-deck to backlog
(pending actions from PR #1162 were not executed by orchestrator).

Escalate: #1158 (Phase 1 completion accuracy) — still needs planner/human decision.
2026-03-26 06:02:19 +00:00
johba
fce4b8b068 chore: gardener housekeeping 2026-03-25
AGENTS.md watermarks refreshed to HEAD (358f719). Content updates:
- scripts/harb-evaluator/AGENTS.md: documented wallet.ts auto-reconnect
  fix (wagmi EIP-6963 auto-connect handling, 10s disconnect timeout)
- All other AGENTS.md files: watermark bump only

Pending actions (3): promote #1155 pitch-deck to backlog.

Escalate: #1158 (Phase 1 completion accuracy) — needs planner/human decision.
2026-03-25 18:05:32 +00:00
johba
2ef2e48f8a chore: gardener housekeeping 2026-03-23
AGENTS.md watermarks refreshed to HEAD (209e0c7). Key content updates:
- root AGENTS.md: added packages/analytics/ to directory map
- landing/AGENTS.md: documented @harb/analytics integration and Umami funnel tracking
- web-app/AGENTS.md: documented analytics events (wallet_connect, swap_initiated, stake_created)
- onchain/AGENTS.md: documented AttackRunner fixes (taxRate as index, vm.warp, same-broadcast recenter), 2000-trade floor-ratchet evidence

Pending actions (6): promote #1083 and #1086 to backlog, unblock #1099.
2026-03-23 18:07:12 +00:00
johba
a76d3937dd fix: bundled dust cleanup — onchain source quality (#1134)
- Fix misleading taxRate comment in AttackRunner.s.sol (index into TAX_RATES[], not raw rate)
- Clarify _validatePriceMovement NatSpec return doc in PriceOracle.sol
- Remove redundant double-cast uint256(uint256(...)) in OptimizerV3Push3Lib.sol
- Add Basescan URL source comments for SWAP_ROUTER and WETH addresses

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 09:51:46 +00:00
johba
1b3d0ddd78 Merge pull request 'fix: Floor Ratchet 2000-trade oscillation needs a dedicated full-sequence red-team run (#1082)' (#1137) from fix/issue-1082 into master 2026-03-23 10:36:02 +01:00
johba
69ba4fd44e fix: Floor Ratchet 2000-trade oscillation needs a dedicated full-sequence red-team run (#1082)
- Expand floor-ratchet-oscillation.jsonl to 2000 buy→recenter cycles
  (10 rounds × 200 cycles at 5 ETH/buy with stake/unstake/sell phases)
- Fix AttackRunner buy_recenter_loop: add vm.warp/vm.roll for recenter
  cooldown bypass and TWAP convergence; use single-signer broadcast
- Fix AttackRunner mine op: advance timestamp alongside block number
- Replace pending 2026-03-22 evidence with completed 2026-03-23 run
- Result: INCREASED (+1230 bps). TWAP oracle blocked 99.9% of recenters.
  Floor ratchet risk from #630 is defeated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 09:12:00 +00:00
johba
67de651242 chore: gardener housekeeping 2026-03-23
- Update all AGENTS.md watermarks to HEAD (b276392)
- Clean up dust.jsonl: remove already-bundled items (601,627,739,741)
- Pending actions: promote #1099/#1100/#1101 to backlog, close stale
  prediction issues #1020/#1103/#1107, comment on partial resolution
  of #1022 (holdout resolved, user-test still empty)
2026-03-23 07:15:23 +00:00
johba
b276392e7a chore: gardener housekeeping 2026-03-23
- Update all AGENTS.md watermarks to HEAD (224edcc)
- onchain/AGENTS.md: document VWAPTracker _hasRecenterTick guard (#609),
  overflow guard for slots 0-7 (#997), Floor Ratchet defeated (#1067),
  fee-income delta_bps audit trail (#1084)
- landing/AGENTS.md: document SecurityInfo.vue component (#147)

Issues actioned via API:
- Unblocked #1099, #1100, #1101 (all prereqs 1031/997/1067/1054 closed)
- Created #1134 bundled backlog: onchain source quality cleanup (4 dust items)
- Closed dust #601, #627, #739, #741 → bundled into #1134
2026-03-23 07:04:19 +00:00
johba
caedd5c4e6 fix: Fee-income calculation model needs documentation to make delta_bps auditable (#1084)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 03:23:23 +00:00
johba
db1c26838d fix: _isPriceStable fallback interval can still revert on pools with very short history (#610)
Wrap the fallback pool.observe() call in a try/catch so that pools with
insufficient observation history for both the primary (30s) and fallback
(6000s) intervals return false (price unstable) instead of reverting with
an opaque Uniswap V3 error. This prevents recenter() from failing for
unpermissioned callers on newly created pools.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 20:31:04 +00:00
johba
937f2a833b fix: Investigate: adversary parasitic LP extracts 29% from holder, all recenters fail (#517)
Root cause: PRICE_STABILITY_INTERVAL (300s) was too long relative to
MIN_RECENTER_INTERVAL (60s). After any significant trade moving the tick
>1000 positions, the 5-minute TWAP lagged behind the current price by
hundreds of ticks, exceeding MAX_TICK_DEVIATION (50). Recenter reverted
with "price deviated from oracle" for ~285s — creating a window where
the LM could not reposition and adversary parasitic LP could extract
value from passive holders.

Fix: Reduce PRICE_STABILITY_INTERVAL from 300s to 30s. This ensures
TWAP converges within the 60s cooldown while still preventing same-block
manipulation (30s > ~12s Ethereum mainnet block time).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 19:45:35 +00:00
johba
d2c1e83962 fix: testMomentumFullBearAtNegMaxDelta has no slot assertions (#1011)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 17:50:41 +00:00
johba
180119aabf fix: address review — consistent evidence fields, unstake all positions
- Evidence file: change result to PENDING (not INCREASED) with delta_bps 0,
  since this is a registration placeholder, not a measured run
- Attack file: add missing unstake for position 6 so all staking positions
  are cleaned up

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 17:06:45 +00:00
johba
af3fd56d55 fix: Floor Ratchet attack not yet defeated — needs explicit test (#1067)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 16:38:44 +00:00
johba
bdc17645f9 fix: Catch block skips clamping that try block applies (#1019)
Add defence-in-depth assert statements in recenter()'s catch block to
verify bear-mode constants (CI=0, AS=30%, AW=100, DD=0.3e18) satisfy
the same bounds the try-path clamps to (MAX_PARAM_SCALE, MAX_ANCHOR_WIDTH).

Add test verifying bear defaults are within clamping bounds and that the
catch path deploys all three positions (floor, anchor, discovery).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:31:49 +00:00
johba
c59bb81a40 fix: Overflow guard missing for slots 1-7 in both Optimizer.sol and OptimizerV3Push3.sol (#997)
Add <= 1e18 upper-bound check for all 8 input slots in the validation
loops of both Optimizer.calculateParams() and OptimizerV3Push3Lib.calculateParams().

Previously only slot 0 (percentageStaked) had an overflow guard —
slots 1-7 (averageTaxRate and future indicators) could silently accept
values > 1e18, violating the documented [0, 1e18] invariant.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 12:11:03 +00:00
johba
ce9be22d2e fix: Attack file schema for burn_lp needs documentation and migration (#615)
Add SCHEMA.md documenting the JSONL attack file format with all operation
definitions, field types, and the burn_lp tokenId convention divergence
between AttackRunner (.positionIndex) and FitnessEvaluator (.tokenId).

Add schema-version header comments to all existing attack files and teach
both consumers to skip comment lines starting with //.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 10:53:07 +00:00
johba
0b6442a87c fix: Attack files have hardcoded tokenIds that are fork-block-sensitive (#614)
Make burn_lp ops fork-block-independent by using a 1-based positionIndex
(resolved at runtime from prior mint_lp ops) instead of hardcoded NFT
tokenIds. Mirrors the existing pattern used by unstake/_stakedPositionIds.

Also log a warning when burn_lp encounters zero liquidity instead of
silently becoming a no-op.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 10:11:58 +00:00
johba
5c9cf81589 Merge pull request 'fix: shouldRecordVWAP else-branch fires incorrectly when lastRecenterTick==0 after bootstrap (#609)' (#1102) from fix/issue-609 into master 2026-03-22 09:06:03 +01:00
johba
83a1b576e4 chore: gardener housekeeping 2026-03-22
- Update all AGENTS.md watermarks to HEAD (5f01d55)
- Add feeDestinationLocked and recenterAccess removal to onchain/AGENTS.md guardrails
- Add gardener/dust.jsonl accumulator (6 dust items: onchain comments, evidence schema docs)

Issues actioned via API:
- Closed #1085 as duplicate of #1082
- Promoted #1079, #1082, #1084 to backlog with acceptance criteria
- Unblocked #607, #609, #610, #611, #614, #615 (dev-crash blockers, no technical blockers)
- Added dependency-resolved comment to #1054 (dep #970 now closed)
2026-03-22 08:47:11 +01:00
johba
63dafd82ca fix: shouldRecordVWAP else-branch fires incorrectly when lastRecenterTick==0 after bootstrap (#609)
Add `_hasRecenterTick` boolean guard to decouple bootstrap detection from
VWAP volume tracking. Before this fix, the bootstrap condition relied solely
on `cumulativeVolume == 0`, which made `lastRecenterTick==0` ambiguous:
it could mean "never recentered" or "previous recenter landed at tick 0
(price = 1.0 token ratio)".

The new guard ensures the direction comparison in the else-branch only
runs after a recenter has explicitly set `lastRecenterTick`, eliminating
the tick-0 ambiguity. Belt-and-suspenders: both `!_hasRecenterTick` and
`cumulativeVolume == 0` trigger bootstrap.

Tests added:
- test_hasRecenterTickGuardPreventsTick0Ambiguity
- test_vwapFrozenDuringBuyOnlyAfterSellRecenter

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 07:28:08 +00:00
johba
87912b06da fix: No Foundry test for OptimizerV3 calculateParams correctness (#607)
Add table-driven Foundry tests for OptimizerV3.calculateParams covering:
- Bear regime at 0%, 1%, 50%, 91% staking (all tax rates)
- Bull/bear boundary at 92% with tax index transitions
- Bull/bear at 95% with penalty=50 exact boundary
- EffIdx shift behavior at 96% (taxIdx 13→14 discontinuity)
- Bull at 97% with max tax, 100% always bull
- Edge cases: all-zero inputs, zero tax at high staking
- Mantissa overflow guard
- Unused slots ignored
- Fuzz: no reverts, output always exactly bear or bull

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 06:31:06 +00:00
johba
9086a4c5e4 fix: AGENTS.md guardrails do not document the stakingPoolAddr != feeDestination exclusion (#934)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 03:37:02 +00:00
johba
e04e041a0f fix: correct EOA→contract in FEE_DEST comment (#795)
The production feeDest has contract bytecode on Base mainnet, not an EOA.
Fix the contradictory comment flagged in review.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 02:15:29 +00:00
johba
fcd8f77693 fix: DeployBaseMainnet.sol:15 may need FEE_DEST update (#795)
Document the FEE_DEST derivation in DeployBaseMainnet.sol and explain
why FitnessEvaluator.t.sol intentionally uses a different address.

The production address (0xf6a3...D9011) is correct — it has contract
bytecode on Base mainnet, so setFeeDestination() locks it permanently.
The test uses a keccak-derived EOA (0x8A91...9383) to avoid the locking
behaviour breaking snapshot/revert cycles in fork tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 01:51:39 +00:00
johba
636ba989ee fix: Optimizer and OptimizerV3 lack _disableInitializers() in constructor (#1055) (#1080)
Fixes #1055

## Changes
That notification is for the earlier background task which already completed — I retrieved its output and used it to diagnose and fix the failing test. The work is done.

Reviewed-on: https://codeberg.org/johba/harb/pulls/1080
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-21 13:42:54 +01:00
johba
62fc7957b0 fix: OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 20:52:29 +00:00
johba
6f7b6c4254 fix: OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063)
- getLiquidityParams() now reverts with "OptimizerV3Push3: not for production use" instead
  of silently returning zeroed bear-mode defaults; LiquidityManager.recenter() already has
  a try/catch fallback so backtesting is unaffected
- Added @custom:experimental NatSpec annotation to the contract marking it as a transpiler
  harness / backtesting stub only
- DeployBase.sol now validates any pre-existing optimizer address by calling getLiquidityParams()
  and reverting if it fails, blocking accidental wiring of OptimizerV3Push3 as a live optimizer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 20:13:18 +00:00
openhands
05753054b9 fix: OptimizerV3Push3 — deeply-nested if-else vs flat if-else chain in OptimizerV3 (#599)
Extract transpiler output into OptimizerV3Push3Lib so both OptimizerV3
and OptimizerV3Push3 delegate to the same canonical copy.  Future
transpiler changes now require only one edit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:18:12 +00:00
openhands
abbf14854d fix: address review — add negative-mantissa guard to OptimizerV3, add OptimizerV3 test file
- Add require(mantissa >= 0) to OptimizerV3.calculateParams validation loop
  (was missing unlike Optimizer and OptimizerV3Push3)
- Create onchain/test/OptimizerV3.t.sol with shift, negative-mantissa, and
  basic bear/bull output tests
- Fix stale comment in Optimizer.sol: "shift=0 assumed" → "shift=0 enforced"
- Use implementation-neutral NatSpec phrasing in IOptimizer.sol

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:10:03 +00:00
openhands
42b4bf4149 fix: Shift field silently ignored — dyadic rational inputs effectively unsupported (#606)
Add require(shift == 0) guards to Optimizer.calculateParams and
OptimizerV3.calculateParams so non-zero shifts revert instead of being
silently discarded.  OptimizerV3Push3 already had this guard.

Update IOptimizer.sol NatSpec to document that shift is reserved for
future use and must be 0 in all current implementations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:42:50 +00:00
openhands
79a2e2ee5e fix: deployments-local.json committed to repo (#589)
- Add onchain/deployments-local.json to .gitignore so it is no longer tracked
- Remove the stale committed file from git
- Update fitness.sh to read LM address from forge broadcast JSON
  (DeployLocal.sol's run-latest.json) instead of the potentially stale
  deployments-local.json, matching the approach deploy-optimizer.sh already uses

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:48:00 +00:00
openhands
e28e69c98a fix: guard int128 overflow in ThreePositionStrategy mirror tick (#622)
Move overflow guard to the actual vulnerable site:
ThreePositionStrategy._computeFloorTickWithSignal() line 262 where
vwapX96 >> 32 is cast to int128 for _tickAtPriceRatio. Values
exceeding int128.max now skip mirror tick (fallback to scarcity/clamp)
instead of reverting.

Remove incorrect require from Optimizer._buildInputs() which guarded
a non-existent int256 cast path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 02:46:30 +00:00
openhands
7007e593da fix: getLiquidityParams: int256 overflow on large VWAP values (#622)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 02:05:25 +00:00
openhands
170cc839e6 fix: _scrapePositions: unguarded safeTransfer to address(0) when feeDestination unset (#624)
Add address(0) guard to fee transfer condition in _scrapePositions so
that when feeDestination is uninitialized, fees accrue as deployable
liquidity instead of reverting on safeTransfer to the zero address.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 01:05:05 +00:00
openhands
37905a29b2 fix: mint_lp and burn_lp not soft-failing in attack execution (#630)
Wrap mint_lp and burn_lp ops in _executeOp with try/catch to match
the soft-fail pattern used by buy, sell, stake, and unstake. Replace
burn_lp's require() with a soft return for out-of-range index validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:23:58 +00:00
openhands
fbe8384342 fix: No recovery path if VWAP bootstrap fails mid-sequence (#644)
Add recovery procedure documentation and automated recovery script for
when the VWAP bootstrap fails partway through (e.g. second recenter
reverts due to insufficient price movement).

- Add "Recovery from failed mid-sequence bootstrap" section to
  docs/mainnet-bootstrap.md with diagnosis steps and manual recovery
- Create scripts/recover-bootstrap.sh to automate diagnosis and retry
- Add warning comments in BootstrapVWAPPhase2.s.sol, DeployBase.sol,
  and bootstrap-common.sh referencing the recovery procedure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:24:05 +00:00
openhands
d3ff2cd0bf fix: Bear defaults duplicated across Optimizer and LiquidityManager (#646)
Extract bear-mode default values (0, 3e17, 100, 3e17) into file-level
constants in IOptimizer.sol so both Optimizer._bearDefaults() and
LiquidityManager.recenter()'s catch block reference a single source of
truth instead of independent hardcoded literals.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 18:22:43 +00:00
openhands
5a7363b718 fix: move @return NatSpec from _buildInputs to getLiquidityParams
The @return annotations were orphaned after _buildInputs() was inserted
between the NatSpec block and getLiquidityParams(). Move them to directly
precede getLiquidityParams() where they belong.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:08:26 +00:00
openhands
bb150671ea fix: OptimizerInputCapture test harness is structurally broken (#652)
The pure override in OptimizerInputCapture could not write to storage,
and getLiquidityParams calls calculateParams via staticcall which
prevents both storage writes and event emissions.

Fix: extract the input-building normalization from getLiquidityParams
into _buildInputs() (internal view, behavior-preserving refactor).
The test harness now exposes _buildInputs() via getComputedInputs(),
allowing tests to assert actual normalized slot values.

Updated tests for pricePosition, timeSinceRecenter, volatility,
momentum, and utilizationRate to assert non-zero captured values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:57:25 +00:00
johba
5c4ceaf78d fix: No negative-mantissa guard in OptimizerV3Push3 (#650) (#966)
Fixes #650

## Changes
Add require(inputs[k].mantissa >= 0, 'negative mantissa') for all 8 input slots inside the existing validation loop in OptimizerV3Push3.sol, matching the guard pattern in Optimizer.sol lines 372-374. Added 3 tests covering slots 0, 1, and 5 to confirm revert on negative mantissa.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/966
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-19 11:30:18 +01:00
openhands
db6abda17e fix: address review feedback for #769
- Apply PRIVATE_KEY env-var fallback to UpgradeOptimizer.sol (missed in first pass)
- Add comment on zero-sentinel silent-fallback behaviour in all four scripts
- Remove spurious view modifier from BaseDeploy.run() (violated by vm.readFile)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 00:26:04 +00:00
openhands
9632693b8a fix: BootstrapVWAPPhase2.s.sol hardcodes .secret file dependency (#769)
Check PRIVATE_KEY env var first in BootstrapVWAPPhase2.s.sol, DeployBase.sol,
and BaseDeploy.sol; fall back to .secret seed-phrase file when unset.
This allows CI/CD environments to inject keys via environment variables
while preserving the existing local .secret workflow unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 00:03:59 +00:00
openhands
f33d5e932d fix: address review feedback for #958
- Document new LiquidityManager events in kraiken-lib/src/version.ts per
  AGENTS.md pre-PR checklist item 6 (Kraiken VERSION unchanged; no ponder
  subscriber impact)
- Add vm.expectEmit assertions to testSetFeeDestinationLocked_Reverts for
  the setup call that now emits FeeDestinationSet + FeeDestinationLocked

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 22:06:13 +00:00
openhands
e3c699b7eb fix: No events on fee destination state changes (#958)
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>
2026-03-18 21:25:12 +00:00
openhands
28ce5ec8cd fix: Optimizer.sol base class only guards slots 0 and 1 (#968)
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>
2026-03-18 18:24:18 +00:00
openhands
534382f785 fix: CREATE2 self-destruct bypass in onchain/src/LiquidityManager.sol (#921)
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>
2026-03-18 11:58:28 +00:00