7.4 KiB
7.4 KiB
Agent Brief: Harb Stack
System Map
onchain/: Foundry workspace for Kraiken token, Harberger staking, Optimizer, and LiquidityManager logic. Deployment scripts live inscript/, tests intest/, fuzzing toolchain inanalysis/. Use.secret.localmnemonic for local scripts.services/ponder/: New indexer replacing The Graph.ponder.config.tsselects network/contracts,src/holds TypeScript event handlers,ponder.schema.tsdefines tables,README.mddocuments usage. Generated artifacts ingenerated/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. Seesrc/views/for pages,env.d.tsfor injected globals.services/txnBot/: Node service that consumes the Ponder GraphQL API to triggerrecenter()andpayTax()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 byscripts/local_env.shBASE_SEPOLIA: Public Base Sepolia testnetBASE: Base mainnet
Execution Workflow
-
Contracts
- Build/test via
forge buildandforge testinsideonchain/. - Local deployment: run Anvil fork, execute
forge script script/DeployLocal.sol --fork-url http://127.0.0.1:8545 --broadcastwith.secret.localmnemonic. 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 callrecenter().
- Build/test via
-
Indexer (Ponder)
- Install deps (
npm install). - Configure environment via
PONDER_NETWORK(BASE_SEPOLIA_LOCAL_FORK,BASE_SEPOLIA, orBASE). Updateponder.config.tsaddresses if deployments change. - Run dev mode with
npm run dev; GraphQL served athttp://localhost:42069/graphql. - Handlers in
src/kraiken.tsandsrc/stake.tsmaintain rolling supply stats, ring-buffered hourly metrics, and position state.
- Install deps (
-
Frontend
npm installthennpm run devinlanding/. Currently static marketing copy with placeholders for wallet/staking flows.- Configure GraphQL endpoints via
VITE_PONDER_BASE_SEPOLIA,VITE_PONDER_BASE, and optionally overrideVITE_PONDER_BASE_SEPOLIA_LOCAL_FORK(defaults tohttp://127.0.0.1:42069/graphql).
- Automation Bot
- Requires
.envwith RPC + key. Queries the Ponder GraphQL endpoint to decide when to pay tax or recenter liquidity. scripts/local_env.sh startprovisions and launches the bot automatically when running against the local fork.
- Requires
Migration Notes (Subgraph → Ponder)
- Schema parity: ensure any entity changes land in both
ponder.schema.tsand legacy Graphschema.graphqluntil cutover. - Event coverage:
Stakeevents (PositionCreated/Removed/Shrunk/TaxPaid/RateHiked) mirrored from AssemblyScript handlers. KraikenTransferpowers mint/burn/tax/UBI tracking. - Ring buffer logic in
kraiken.tsdepends on block timestamps being monotonic; gaps >168 hours zero out the buffer. VerifystartBlockinponder.config.tsto avoid reprocessing genesis noise. - Local deployment requires updating
ponder.config.tslocal contract addresses after each run or injecting via env overrides. TheBASE_SEPOLIA_LOCAL_FORKprofile assumes addresses generated byDeployLocal.sol. - Ponder v0.13 exposes helpers via
context.client/context.contracts; use these to seed stats from on-chaintotalSupplyand refreshoutstandingStakestraight from theStakecontract. All hourly projections now run off a JSON ring buffer on thestatsrow. - 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
PositionTaxPaidinstead 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 withLOK. Investigate before relying onscripts/local_env.sh startfor an unattended setup.
Testing Playbook
- Unit/Fuzz:
forge testand scripts underonchain/analysis/to stress liquidity + staking edge cases. - Integration (local fork):
anvil --fork-url https://sepolia.base.org(or base mainnet RPC) in terminal 1.- From
onchain/, deploy withforge script script/DeployLocal.sol --fork-url http://127.0.0.1:8545 --broadcast. - Fund LiquidityManager, call
recenter(), and execute sample trades (KRK buy, stake, unstake) usingcastor Foundry scripts. - Start Ponder (
PONDER_NETWORK=BASE_SEPOLIA_LOCAL_FORK npm run dev) and watch logs for handler errors. - Query GraphQL (
stats,positions) to confirm indexed state.
Gotchas & Tips
token0isWethtoggles 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 address0x4200...006). Usecast sendwith sufficient ETH when testing locally. - Ponder’s 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 (seesrc/config.ts). Update the environment specific GraphQL URLs when deployments move.
Useful Commands
foundryup/forge clean/forge snapshotanvil --fork-url https://sepolia.base.orgcast call <POOL> "slot0()"PONDER_NETWORK=BASE_SEPOLIA_LOCAL_FORK npm run devcurl -X POST http://localhost:42069/graphql -d '{"query":"{ stats(id:\"0x01\"){kraikenTotalSupply}}"}'curl http://127.0.0.1:43069/status./scripts/local_env.sh startboots Anvil+contracts+ponder+frontend+txnBot; stop with Ctrl+C or./scripts/local_env.sh stop.
Refactor Backlog
- Replace the temporary
anyshims inservices/ponder/src/kraiken.tsandservices/ponder/src/stake.tsby importing the official 0.13 handler types instead of stubbingponder-env.d.ts. - Drop the custom
ponder:api/ponder:registrymodule declarations once the generator emits them; if it cannot, declare precise interfaces rather thananyto keep autocomplete and future upgrades safe. - Convert the JSON ABI imports in
services/ponder/ponder.config.tsto typed loaders (e.g.,satisfies Abi) so config drift is caught at compile time instead of viaas Abicasts. - Move the snatch-selection logic out of
web-app/src/components/StakeHolder.vueinto a dedicated composable that both the stake form and charts can reuse, and memoise theassetsToSharesconversions there. - Split
kraiken-lib/src/helpers.tsinto 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 underonchain/broadcast/. - Technical deep dive:
TECHNICAL_APPENDIX.md&HARBERG.md. - Liquidity math references:
onchain/UNISWAP_V3_MATH.md.