Commit graph

176 commits

Author SHA1 Message Date
openhands
5e8a94b7a9 feat: Push3 → Solidity transpiler + OptimizerV3 port 2026-02-23 14:47:38 +00:00
openhands
9e2dea02de fix: gitignore JS lock files in onchain/ (Foundry-managed deps)
onchain/ uses Foundry for dependency management, not yarn/npm.
Adding yarn.lock, package-lock.json, and node_modules/ to .gitignore
prevents accidental commits of JS toolchain artifacts in future.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 13:40:19 +00:00
openhands
6a98fd6ad5 fix: remove accidentally committed onchain/yarn.lock
yarn install was run during forge build troubleshooting; the generated
lock file was not intentional and is architecturally inconsistent with
the Foundry-only onchain/ toolchain. Also restores package-lock.json
to its pre-npm-install state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 13:38:23 +00:00
openhands
b146b7a2ab fix: Clean up dead code and stale domain references across landing + web-app (#189) 2026-02-23 13:04:51 +00:00
openhands
58c3e62f3d fix: refactor AGENTS.md into progressive-disclosure structure (#184)
- Root AGENTS.md: 350+ lines → 68 lines (map, not encyclopedia)
- New docs/dev-environment.md (67 lines): Docker, dev.sh, ports, pitfalls
- New docs/ci-pipeline.md (73 lines): Woodpecker setup, monitoring, debugging
- New docs/testing.md (41 lines): Foundry, E2E, version validation
- New docs/codeberg-api.md (32 lines): .netrc auth, API usage
- Updated stale model refs in .claude-code-supervisor.yml files
- Sub-component AGENTS.md files unchanged
- Context docs (PRODUCT-TRUTH, ARCHITECTURE, UX-DECISIONS) unchanged
2026-02-23 09:46:35 +00:00
johba
31063379a8 feat/ponder-lm-indexing (#142) 2026-02-18 00:19:05 +01:00
openhands
de3c8eef94 docs: consolidate and update all documentation for launch readiness
- Rewrite root README.md with proper project overview, tech stack, and repo structure
- Remove duplicate CLAUDE.md files (root, onchain, ponder) — AGENTS.md is the standard
- Update HARBERG.md to reflect Stage 1 completion and Stage 2 evolution
- Delete stale onchain/testing_todos.md (all high-priority items completed)
- Update VERSION_VALIDATION.md for VERSION=2
- Trim root AGENTS.md: replace Docker duplication with docs/docker.md reference
- Trim onchain/AGENTS.md (129→71 lines): reference TECHNICAL_APPENDIX for formulas
- Trim web-app/AGENTS.md (278→55 lines): remove internal API docs, keep architecture
- Rewrite onchain/README.md: add contract table, deployment addresses, analysis links
- Trim services/ponder/README.md: remove stale subgraph comparison
- Add otterscan to docs/docker.md service topology
- Update TECHNICAL_APPENDIX.md references

Net: -388 lines across documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:22:34 +00:00
openhands
b7260b2eaf chore: analysis tooling, research artifacts, and code quality
- Analysis: parameter sweep scripts, adversarial testing, 2D frontier maps
- Research: KRAIKEN_RESEARCH_REPORT, SECURITY_REVIEW, STORAGE_LAYOUT
- FuzzingBase: consolidated fuzzing helper, BackgroundLP simulation
- Sweep results: CSV data for full 4D sweep (1050 combos), bull-bear,
  AS sweep, VWAP fix validation
- Code quality: .gitignore for fuzz CSVs, gas snapshot, updated docs
- Remove dead analysis helpers (CSVHelper, CSVManager, ScenarioRecorder)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:22:03 +00:00
openhands
d64b63aff4 feat: deployment scripts, E2E tests, and documentation
- DeployBase: shared deployment logic with OptimizerV3 UUPS proxy
- DeployBaseMainnet: Base mainnet configuration (feeDest, WETH, factory)
- DeployLocal: local Anvil deployment with OptimizerV3
- UpgradeOptimizer: UUPS upgrade script for existing proxy
- DEPLOYMENT_RUNBOOK: step-by-step mainnet deployment guide
- E2E tests: recenter position verification, optimizer integration
- Landing page: updated docs for OptimizerV3 and protocol changes
- Remove dead DeployScript2.sol

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:21:49 +00:00
openhands
85350caf52 feat: OptimizerV3 with direct 2D staking-to-LP parameter mapping
Core protocol changes for launch readiness:

- OptimizerV3: binary bear/bull mapping from (staking%, avgTax) — avoids
  exploitable AW 30-90 kill zone. Bear: AS=30%, AW=100, CI=0, DD=0.3e18.
  Bull: AS=100%, AW=20, CI=0, DD=1e18. UUPS upgradeable with __gap[48].
- Directional VWAP: only records prices on ETH inflow (buys), preventing
  sell-side dilution of price memory
- Floor formula: unified max(scarcity, mirror, clamp) — VWAP mirror uses
  distance from adjusted VWAP as floor distance, no branching
- PriceOracle (M-1 fix): correct fallback TWAP divisor (60000s, not 300s)
- Access control (M-2 fix): deployer-only guard on one-time setters
- Recenter rate limit (M-3 fix): 60-second cooldown for open recenters
- Safe fallback params: recenter() optimizer-failure defaults changed from
  exploitable CI=50%/AW=50 to safe bear-mode CI=0/AW=100
- Recentered event for monitoring and indexing
- VERSION bump to 2, kraiken-lib COMPATIBLE_CONTRACT_VERSIONS updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:21:18 +00:00
openhands
21857ae8ca feat: protocol stats display + parameter sweep fuzzing infrastructure (#106)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:09:11 +00:00
openhands
61b7ee435f chore: remove unused pt-v5-twab-controller submodule (54MB) 2026-02-13 14:37:20 +00:00
openhands
d581b8394b fix(onchain): resolve KRK token supply corruption during recenter (#98)
PROBLEM:
Recenter operations were burning ~137,866 KRK tokens instead of minting
them, causing severe deflation when inflation should occur. This was due
to the liquidity manager burning ALL collected tokens from old positions
and then minting tokens for new positions separately, causing asymmetric
supply adjustments to the staking pool.

ROOT CAUSE:
During recenter():
1. _scrapePositions() collected tokens from old positions and immediately
   burned them ALL (+ proportional staking pool adjustment)
2. _setPositions() minted tokens for new positions (+ proportional
   staking pool adjustment)
3. The burn and mint operations used DIFFERENT totalSupply values in
   their proportion calculations, causing imbalanced adjustments
4. When old positions had more tokens than new positions needed, the net
   result was deflation

WHY THIS HAPPENED:
When KRK price increases (users buying), the same liquidity depth
requires fewer KRK tokens. The old code would:
- Burn 120k KRK from old positions (+ 30k from staking pool)
- Mint 10k KRK for new positions (+ 2.5k to staking pool)
- Net: -137.5k KRK total supply (WRONG!)

FIX:
1. Modified uniswapV3MintCallback() to use existing KRK balance first
   before minting new tokens
2. Removed burn() from _scrapePositions() - keep collected tokens
3. Removed burn() from end of recenter() - don't burn "excess"
4. Tokens held by LiquidityManager are already excluded from
   outstandingSupply(), so they don't affect staking calculations

RESULT:
Now during recenter, only the NET difference is minted or used:
- Collect old positions into LiquidityManager balance
- Use that balance for new positions
- Only mint additional tokens if more are needed
- Keep any unused balance for future recenters
- No more asymmetric burn/mint causing supply corruption

VERIFICATION:
- All 107 existing tests pass
- Added 2 new regression tests in test/SupplyCorruption.t.sol
- testRecenterDoesNotCorruptSupply: verifies single recenter preserves supply
- testMultipleRecentersPreserveSupply: verifies no accumulation over time

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:20:57 +00:00
johba
4277f19b68 feature/ci (#84)
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/84
2026-02-02 19:24:57 +01:00
johba
f7ef56f65f reworked stack 2025-10-07 21:57:32 +00:00
johba
6cbb1781ce tax rate, version and compose (#70)
resolves #67

Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/70
2025-10-07 19:26:08 +02:00
johba
514be62cbb txnbot - rewrite and lint (#53)
resolves #46

Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/53
2025-10-04 15:40:30 +02:00
johba
d7c2184ccf Add Solidity linting with solhint, Foundry formatter, and pre-commit hooks (#51)
## Changes

### Configuration
- Added .solhint.json with recommended rules + custom config
  - 160 char line length (warn)
  - Double quotes enforcement (error)
  - Explicit visibility required (error)
  - Console statements allowed (scripts/tests need them)
  - Gas optimization warnings enabled
  - Ignores test/helpers/, lib/, out/, cache/, broadcast/

- Added foundry.toml [fmt] section
  - 160 char line length
  - 4-space tabs
  - Double quotes
  - Thousands separators for numbers
  - Sort imports enabled

- Added .lintstagedrc.json for pre-commit auto-fix
  - Runs solhint --fix on .sol files
  - Runs forge fmt on .sol files

- Added husky pre-commit hook via lint-staged

### NPM Scripts
- lint:sol - run solhint
- lint:sol:fix - auto-fix solhint issues
- format:sol - format with forge fmt
- format:sol:check - check formatting
- lint / lint:fix - combined commands

### Code Changes
- Added explicit visibility modifiers (internal) to constants in scripts and tests
- Fixed quote style in DeployLocal.sol
- All Solidity files formatted with forge fmt

## Verification
-  forge fmt --check passes
-  No solhint errors (warnings only)
-  forge build succeeds
-  forge test passes (107/107)

resolves #44

Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/51
2025-10-04 15:17:09 +02:00
johba
4f7cebda56 start stack from container (#40)
resolves #36

Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/40
2025-10-02 17:11:22 +02:00
johba
b4c829e4d6 fix/podman-postgres-integration (#37)
resolves #25

Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/37
2025-10-01 20:26:49 +02:00
johba
76d84341de feat: add ABI validation helpers for Ponder (#29)
resolves https://codeberg.org/johba/harb/issues/23

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/29
2025-09-30 20:02:43 +02:00
johba
769fa105b8 added web-app and landing 2025-09-23 14:18:04 +02:00
johba
af031877a5 fix position calculation 2025-09-23 11:46:57 +02:00
Your Name
0de1cffea8 another fixup of fuzzer 2025-09-16 22:46:43 +02:00
Your Name
c32f1b102b small fixes 2025-08-24 18:38:48 +02:00
johba
137adfe82b another rewrite 2025-08-23 22:32:41 +02:00
johba
c72fe56ad0 bounded buy/sell 2025-08-23 16:10:05 +02:00
johba
8b537302d8 feat: Add staking functionality to fuzzing analysis with snatching
- Integrate staking and exitPosition actions into fuzzing scenarios
- Add staking metrics (percentageStaked, avgTaxRate) to CSV output
- Implement snatching mechanism when stake pool reaches capacity
- Add configurable staking parameters (enable/disable, buy bias, staking bias)
- Support configurable number of trades per run
- Simplify to single trader account with proportional ETH funding
- Configure tax rates: 0-15 for initial stakes, 28 for snatching
- Clean up debug logging and verbose output

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-19 18:29:20 +02:00
johba
74e09bb38b consolidated scripts 2025-08-19 17:35:43 +02:00
johba
10702f5aa3 feat: Enhance fuzzing with staking integration and configurable parameters
- Add staking/unstaking actions to fuzzing scenarios (stake every 3rd trade)
- Implement snatching logic when stake pool reaches capacity (uses max tax rate)
- Add configurable parameters:
  - buyBias: Control buy vs sell ratio (0-100%)
  - stakingBias: Control stake vs unstake ratio (0-100%)
  - tradesPerRun: Configure number of trades per scenario
  - staking: Enable/disable staking entirely
- Simplify to single trading strategy (_executeRandomLargeTrades)
- Fix memory issues by recording only every 5th trade to CSV
- Track staking metrics (stakes attempted/succeeded, snatches attempted/succeeded)
- Update CLAUDE.md with new fuzzing parameters and usage examples
- Clean up old TODO files and unused code

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-19 14:57:49 +02:00
johba
27a8998a82 feat: Add buy bias parameter to fuzzing analysis
- Added BUY_BIAS environment variable (0-100%) to control trading direction
- Implemented biased trading logic in all strategies (Random, Whale, Volatile, etc.)
- Created run-improved-fuzzing.sh script with buy bias support
- Fixed memory issues in CSV generation by simplifying string concatenation
- Fixed console.log parameter issues in staking functions
- Updated run-recorded-fuzzing.sh to accept buybias parameter
- Testing shows up to 99% of authorized stake reached with 100% buy bias

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-19 14:02:11 +02:00
johba
25d6e2301a out of gas 2025-08-19 13:47:04 +02:00
johba
db23d756e9 fix: Optimize fuzzing and fix CSV buffer accumulation
- Deploy Uniswap factory once before all runs (saves ~1.16M gas per run)
- Fix CSV buffer accumulation bug by clearing buffer between runs
- Add clearCSV() function to CSVManager for proper buffer management
- Each fuzzing run now gets its own clean CSV with correct token0isWeth values
- Comment out failing console.log in Optimizer.t.sol to fix compilation

The token ordering now correctly alternates:
- Even seeds: token0isWeth = true (WETH < KRAIKEN)
- Odd seeds: token0isWeth = false (KRAIKEN < WETH)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-19 13:30:18 +02:00
johba
e5d47b1890 Merge branch 'anchor' 2025-08-19 11:49:50 +02:00
johba
f3047072f6 feat: Dynamic anchorWidth based on staking metrics
Replace hardcoded anchorWidth=100 with dynamic calculation that uses staking data as a decentralized oracle.

Changes:
- Add _calculateAnchorWidth() function to Optimizer.sol
- Base width 40% with adjustments based on staking percentage and average tax rate
- Staking adjustment: -20% to +20% (inverse relationship)
- Tax rate adjustment: -10% to +30% (direct relationship)
- Final range clamped to 10-80% for safety

Rationale:
- High staking % = bullish sentiment → narrower anchor (20-35%) for fee optimization
- Low staking % = bearish/uncertain → wider anchor (60-80%) for defensive positioning
- High tax rates = volatility expected → wider anchor to reduce rebalancing
- Low tax rates = stability expected → narrower anchor for fee collection

The Harberger tax mechanism acts as a prediction market where stakers' self-assessed valuations reveal market expectations.

Tests:
- Add comprehensive unit tests in test/Optimizer.t.sol
- Add mock contracts for testing (MockStake.sol, MockKraiken.sol)
- Manual verification confirms all scenarios calculate correctly

Documentation:
- Add detailed analysis of anchorWidth price ranges
- Add staking-based strategy recommendations
- Add verification of calculation logic

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-19 11:41:02 +02:00
johba
400ab325ed refactor: Complete project renaming from HARB/Harberger to KRAIKEN
- Updated all production code references from 'harb' to 'kraiken'
- Changed 'Harberger tax' references to 'self-assessed tax'
- Updated function names (_getHarbToken -> _getKraikenToken)
- Modified documentation and comments to reflect new branding
- Updated token symbol from HARB to KRAIKEN in tests
- Maintained backward compatibility with test variable names

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-19 11:05:08 +02:00
johba
7eef96f366 recorded fuzzing 2025-08-18 22:09:03 +02:00
johba
85cc8191be fix: Resolve out-of-gas errors in fuzzing by disabling block gas limit
The fuzzing script was failing with out-of-gas errors when large KRAIKEN sells
tried to traverse many tick ranges in Uniswap V3. Fixed by adding the
--disable-block-gas-limit flag to forge script execution.

Also fixed the CSV symlink path for the visualizer to work correctly.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 21:17:42 +02:00
johba
fbd8170198 fix: Resolve fuzzing script issues with gas limits and CSV symlinks
- Increased gas limit to 100M to prevent out-of-gas errors during large swaps
- Fixed symlink path for profitable_scenario.csv to work with visualizer
- Position CSVs are now always generated when recording profitable scenarios

The out-of-gas error was occurring when large KRAIKEN sells tried to traverse
many tick ranges in Uniswap V3. The visualizer couldn't display data because
the CSV symlink was created in the wrong directory.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 21:14:48 +02:00
johba
c1627dd4c9 refactor: Migrate to improved fuzzing system with visualizer support
- Replaced old FuzzingAnalysis.s.sol with improved RecordedFuzzingAnalysis
- Old fuzzing used trades too small (0.1-100% of remaining balance) to reach discovery
- New system uses larger trades (50-200 ETH) that successfully find invariants
- run-fuzzing.sh now redirects to run-recorded-fuzzing.sh for backward compatibility
- Added position CSV generation for profitable scenarios to support visualizer
- Visualizer automatically launches when invariants are found
- Removed unnecessary debugCSV complexity

The old fuzzing couldn't find invariants because trades got progressively smaller
(often <1 ETH after a few iterations) and couldn't move price the 3,690 ticks
needed to reach the discovery position. The new system maintains large trade sizes
throughout the scenario, successfully finding profitable exploits.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 21:09:03 +02:00
johba
2c69963151 feat: Add scenario recording and replay system for invariant debugging
Implements comprehensive fuzzing improvements to find and reproduce invariant violations:

Recording System:
- ScenarioRecorder captures exact trading sequences that violate invariants
- Exports to JSON, replay scripts, and human-readable summaries
- Unique Run IDs (format: YYMMDD-XXXX) for easy communication

Enhanced Fuzzing:
- ImprovedFuzzingAnalysis with larger trades (50-500 ETH) to reach discovery position
- Multiple strategies: Discovery Push, Whale Manipulation, Volatile Swings
- Successfully finds profitable scenarios with 66% success rate

Shell Scripts:
- run-recorded-fuzzing.sh: Automated fuzzing with recording and unique IDs
- replay-scenario.sh: One-command replay of specific scenarios

New Optimizers:
- ExtremeOptimizer: Tests extreme market conditions
- MaliciousOptimizer: Attempts to exploit the protocol

Documentation:
- Updated CLAUDE.md with complete recording workflow
- Enhanced 4-step debugging process
- Quick reference for team collaboration

This system successfully identifies and reproduces the discovery position exploit,
where traders can profit by pushing trades into the unused liquidity at extreme ticks.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 20:31:39 +02:00
johba
e04885ad8a docs: Update onchain/CLAUDE.md with debugging insights
Added critical implementation details discovered during floor position debugging:
- VWAPTracker stores price² (squared) in X96 format
- Token calculation gotchas for Amount0/Amount1 functions
- Outstanding supply calculation details
- ETH scarcity sqrt calculation
- Precise optimizer parameter formulas

Made documentation more concise (133→108 lines) while adding actionable debugging tips.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 18:10:34 +02:00
johba
f4ae2fea7a docs: Merge analysis/CLAUDE.md into onchain/CLAUDE.md
Consolidated the fuzzing analysis documentation into the main onchain
CLAUDE.md file for better discoverability. Removed the redundant
analysis/CLAUDE.md file.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 17:52:39 +02:00
johba
1a45646017 docs: Replace debugging reflection with actionable TODOs
Converted the debugging reflection into 4 concrete improvement areas:
1. Document Uniswap V3 mechanics & token flows
2. Document optimizer parameters & effects
3. Implement calculation tracing & visualization tools
4. Improve code quality with type safety, tests & invariants

Each TODO has specific tasks and acceptance criteria for implementation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 17:47:59 +02:00
johba
e2f44b07c2 docs: Add debugging reflection report
Documented lessons learned from debugging the floor position calculation bug,
including missing tools and knowledge that would have accelerated the process.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 17:24:57 +02:00
johba
61ea25517c fix: Fix discovery position KRAIKEN amount calculation
The discovery position was incorrectly calculating ETH amount instead
of KRAIKEN amount when determining how much to subtract from outstanding
supply. This caused the floor position to be placed at extreme ticks
(141k+) instead of bordering the anchor position.

When token0isWeth=true:
- Before: discoveryAmount = getAmount0 (ETH amount)
- After: discoveryAmount = getAmount1 (KRAIKEN amount)

This ensures the outstanding supply calculation properly excludes all
KRAIKEN tokens locked in liquidity positions.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 17:05:32 +02:00
johba
516b7cc087 fix: Correct VWAP price calculation in floor position placement
The VWAP tracker stores price² (squared price) in X96 format, but the floor position
calculation was using it as regular price. This caused two issues:

1. ETH scarcity calculation overestimated required ETH by using price² instead of price
2. ETH abundance floor placement was incorrect due to passing price² to _tickAtPriceRatio

Fixed by taking sqrt(vwapX96) before using it in both ETH scarcity and abundance cases.

Also updated BullMarketOptimizer documentation to be more accurate.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 15:33:57 +02:00
johba
01471b7037 more docs 2025-08-18 00:16:09 +02:00
johba
50eac74b18 better visualizer 2025-08-17 15:09:41 +02:00
johba
6a012c5fd9 price multipliers instead of ticks 2025-08-16 18:22:32 +02:00