harb/AGENTS.md
2025-09-23 19:24:05 +02:00

7.4 KiB
Raw Blame History

Agent Brief: Harb Stack

System Map

  • onchain/: Foundry workspace for Kraiken token, Harberger staking, Optimizer, and LiquidityManager logic. Deployment scripts live in script/, tests in test/, fuzzing toolchain in analysis/. Use .secret.local mnemonic for local scripts.
  • ponder/: New indexer replacing The Graph. ponder.config.ts selects network/contracts, src/ holds TypeScript event handlers, ponder.schema.ts defines tables, README.md documents usage. Generated artifacts in generated/ are auto-created by Ponder.
  • subgraph/base_sepolia/: Legacy AssemblyScript implementation kept for reference during migration. Do not modify unless syncing schema changes between stacks.
  • landing/: Vue 3 app (Vite + TypeScript) for the public launch site and forthcoming staking UI. See src/views/ for pages, env.d.ts for injected globals.
  • services/txnBot/: Node service that consumes the Ponder GraphQL API to trigger recenter() and payTax() on-chain when profitable.
  • kraiken-lib/: Shared TypeScript helpers (e.g., bytesToUint256) consumed by the landing app + bots.

Environment Profiles

  • BASE_SEPOLIA_LOCAL_FORK: Anvil fork bootstrapped by scripts/local_env.sh
  • BASE_SEPOLIA: Public Base Sepolia testnet
  • BASE: Base mainnet

Execution Workflow

  1. Contracts

    • Build/test via forge build and forge test inside onchain/.
    • Local deployment: run Anvil fork, execute forge script script/DeployLocal.sol --fork-url http://127.0.0.1:8545 --broadcast with .secret.local mnemonic. Script attaches to Base Uniswap V3 factory, creates pool if absent, deploys Optimizer proxy + LiquidityManager, configures Kraiken/Stake links.
    • Post-deploy: fund LiquidityManager (cast send <LM> --value 0.1ether) and call recenter().
  2. Indexer (Ponder)

    • Install deps (npm install).
    • Configure environment via PONDER_NETWORK (BASE_SEPOLIA_LOCAL_FORK, BASE_SEPOLIA, or BASE). Update ponder.config.ts addresses if deployments change.
    • Run dev mode with npm run dev; GraphQL served at http://localhost:42069/graphql.
    • Handlers in src/kraiken.ts and src/stake.ts maintain rolling supply stats, ring-buffered hourly metrics, and position state.
  3. Frontend

  • npm install then npm run dev in landing/. Currently static marketing copy with placeholders for wallet/staking flows.
  • Configure GraphQL endpoints via VITE_PONDER_BASE_SEPOLIA, VITE_PONDER_BASE, and optionally override VITE_PONDER_BASE_SEPOLIA_LOCAL_FORK (defaults to http://127.0.0.1:42069/graphql).
  1. Automation Bot
    • Requires .env with RPC + key. Queries the Ponder GraphQL endpoint to decide when to pay tax or recenter liquidity.
    • scripts/local_env.sh start provisions and launches the bot automatically when running against the local fork.

Migration Notes (Subgraph → Ponder)

  • Schema parity: ensure any entity changes land in both ponder.schema.ts and legacy Graph schema.graphql until cutover.
  • Event coverage: Stake events (PositionCreated/Removed/Shrunk/TaxPaid/RateHiked) mirrored from AssemblyScript handlers. Kraiken Transfer powers mint/burn/tax/UBI tracking.
  • Ring buffer logic in kraiken.ts depends on block timestamps being monotonic; gaps >168 hours zero out the buffer. Verify startBlock in ponder.config.ts to avoid reprocessing genesis noise.
  • Local deployment requires updating ponder.config.ts local contract addresses after each run or injecting via env overrides. The BASE_SEPOLIA_LOCAL_FORK profile assumes addresses generated by DeployLocal.sol.
  • Ponder v0.13 exposes helpers via context.client / context.contracts; use these to seed stats from on-chain totalSupply and refresh outstandingStake straight from the Stake contract. All hourly projections now run off a JSON ring buffer on the stats row.
  • Subgraph naming differs from the new schema (stats_collection, decimal shares). The web-app and txn bot now target the Ponder schema directly; keep legacy Graph compatibility only until the AssemblyScript stack is fully retired.
  • Tax accounting must listen to PositionTaxPaid instead of guessing via hard-coded addresses. The old subgraph missed this; Ponder now increments the ring buffer segment on each tax payment.
  • Liquidity bootstrap still depends on the Uniswap pool stepping through recenter(). On current Base-Sepolia forks the LM reverts with LOK. Investigate before relying on scripts/local_env.sh start for an unattended setup.

Testing Playbook

  • Unit/Fuzz: forge test and scripts under onchain/analysis/ to stress liquidity + staking edge cases.
  • Integration (local fork):
    1. anvil --fork-url https://sepolia.base.org (or base mainnet RPC) in terminal 1.
    2. From onchain/, deploy with forge script script/DeployLocal.sol --fork-url http://127.0.0.1:8545 --broadcast.
    3. Fund LiquidityManager, call recenter(), and execute sample trades (KRK buy, stake, unstake) using cast or Foundry scripts.
    4. Start Ponder (PONDER_NETWORK=BASE_SEPOLIA_LOCAL_FORK npm run dev) and watch logs for handler errors.
    5. Query GraphQL (stats, positions) to confirm indexed state.

Gotchas & Tips

  • token0isWeth toggles amount0/amount1 semantics—check pool ordering before seeding liquidity.
  • VWAP/ethScarcity logic expects squared price format; do not convert to sqrt unintentionally.
  • LiquidityManager recenter() reverts unless funded with WETH (Base WETH address 0x4200...006). Use cast send with sufficient ETH when testing locally.
  • Ponders SQLite store lives in .ponder/ (gitignored). Delete between runs if schema changes.
  • Legacy subgraph is maintained for reference only; all active services now read from Ponder.
  • web-app/ reads from Ponder by default (see src/config.ts). Update the environment specific GraphQL URLs when deployments move.

Useful Commands

  • foundryup / forge clean / forge snapshot
  • anvil --fork-url https://sepolia.base.org
  • cast call <POOL> "slot0()"
  • PONDER_NETWORK=BASE_SEPOLIA_LOCAL_FORK npm run dev
  • curl -X POST http://localhost:42069/graphql -d '{"query":"{ stats(id:\"0x01\"){kraikenTotalSupply}}"}'
  • curl http://127.0.0.1:43069/status
  • ./scripts/local_env.sh start boots Anvil+contracts+ponder+frontend+txnBot; stop with Ctrl+C or ./scripts/local_env.sh stop.

Refactor Backlog

  • Replace the temporary any shims in ponder/src/kraiken.ts and ponder/src/stake.ts by importing the official 0.13 handler types instead of stubbing ponder-env.d.ts.
  • Drop the custom ponder:api / ponder:registry module declarations once the generator emits them; if it cannot, declare precise interfaces rather than any to keep autocomplete and future upgrades safe.
  • Convert the JSON ABI imports in ponder/ponder.config.ts to typed loaders (e.g., satisfies Abi) so config drift is caught at compile time instead of via as Abi casts.
  • Move the snatch-selection logic out of web-app/src/components/StakeHolder.vue into a dedicated composable that both the stake form and charts can reuse, and memoise the assetsToShares conversions there.
  • Split kraiken-lib/src/helpers.ts into focused modules (ids, tax rates, snatch selection) so consumers can tree-shake and each helper stays small and testable.

Contacts & Artifacts

  • Deployment addresses recorded in onchain/deployments-local.json (local) and broadcast traces under onchain/broadcast/.
  • Technical deep dive: TECHNICAL_APPENDIX.md & HARBERG.md.
  • Liquidity math references: onchain/UNISWAP_V3_MATH.md.