harb/docs/ARCHITECTURE.md

126 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ARCHITECTURE.md — System Map
Compressed overview for AI agents. Read this first, drill into source for details.
## Contract Architecture
```
Kraiken.sol (ERC-20 token)
├── liquidityManager: address (set once, immutable after)
│ └── LiquidityManager.sol (ThreePositionStrategy)
│ ├── optimizer: Optimizer (private immutable ref)
│ ├── pool: IUniswapV3Pool
│ ├── kraiken: Kraiken
│ └── Positions: Floor, Anchor, Discovery
├── stakingPool: address
│ └── Stake.sol
│ ├── Staking positions with tax rates
│ ├── Snatch mechanics (competitive staking)
│ └── getPercentageStaked(), getAverageTaxRate()
└── feeDestination: address (protocol revenue)
Optimizer.sol (UUPS Upgradeable Proxy)
├── Reads: stake.getPercentageStaked(), stake.getAverageTaxRate()
├── Computes: sentiment → 4 liquidity params
├── Versions: Optimizer, OptimizerV2, OptimizerV3, OptimizerV3Push3
└── Admin: single address, set at initialize()
```
## Key Relationships
- **Kraiken → LiquidityManager**: set once via `setLiquidityManager()`, reverts if already set
- **LiquidityManager → Optimizer**: `private immutable` — baked into constructor, never changes
- **LiquidityManager → Kraiken**: exclusive minting/burning rights
- **Optimizer → Stake**: reads sentiment data (% staked, avg tax rate)
- **Optimizer upgrades**: UUPS proxy, admin-only `_authorizeUpgrade()`
## Three-Position Strategy
All managed by LiquidityManager via ThreePositionStrategy abstract:
| Position | Purpose | Behavior |
|----------|---------|----------|
| **Floor** | Safety net | Deep liquidity at VWAP-adjusted prices |
| **Anchor** | Price discovery | Near current price, 1-100% width |
| **Discovery** | Fee capture | Borders anchor, ~3x price range (11000 tick spacing) |
**Recenter** = atomic repositioning of all three positions. Triggered by anyone, automated by txnBot.
## Optimizer Parameters
`getLiquidityParams()` returns 4 values:
1. `capitalInefficiency` (0 to 1e18) — capital buffer level
2. `anchorShare` (0 to 1e18) — % allocated to anchor position
3. `anchorWidth` (ticks) — width of anchor position
4. `discoveryDepth` (0 to 1e18) — depth of discovery position
Sentiment calculation: `sentiment = f(averageTaxRate, percentageStaked)`
- High sentiment (bull) → wider discovery, aggressive fees
- Low sentiment (bear) → tight around floor, maximum protection
## Stack
### On-chain
- Solidity, Foundry toolchain
- Uniswap V3 for liquidity positions
- OpenZeppelin for UUPS proxy, Initializable
- Base L2 (deployment target)
### Indexer
- **Ponder** (`services/ponder/`) — indexes on-chain events
- Schema: `services/ponder/ponder.schema.ts`
- Stats table with 168-slot ring buffer (7d × 24h × 4 segments)
- Ring buffer segments: [ethReserve, minted, burned, tax] (slot 3 being changed to holderCount)
- GraphQL API at port 42069
### Landing Page
- Vue 3 + Vite (`landing/`)
- `@wagmi/vue` for wallet connection (WalletButton, WalletCard)
- `@tanstack/vue-query` — required peer dep for `@wagmi/vue`; provides TanStack Query context for Wagmi's reactive hooks
- `@harb/web3` shared composables (`useAccount`, `useConnect`, `useDisconnect`, `useTokenBalance`)
- Three variants: HomeView (default), HomeViewOffensive (degens), HomeViewMixed
- Docs section: HowItWorks, Tokenomics, Staking, LiquidityManagement, AIAgent, FAQ
- LiveStats component polls Ponder GraphQL every 30s
### Staking Web App
- Vue 3 (`web-app/`)
- Password-protected (multiple passwords in LoginView.vue)
- ProtocolStatsCard shows real-time protocol metrics
### Infrastructure
- Docker Compose on 8GB VPS
- Woodpecker CI at ci.niovi.voyage
- Codeberg repo: johba/harb (private)
- Container registry: registry.niovi.voyage
## Directory Map
```
harb/
├── onchain/ # Solidity contracts + Foundry
│ ├── src/ # Contract source
│ ├── test/ # Forge tests
│ └── foundry.toml # via_ir = true required
├── services/
│ ├── ponder/ # Indexer service
│ │ ├── ponder.schema.ts
│ │ ├── src/
│ │ │ ├── helpers/stats.ts # Ring buffer logic
│ │ │ ├── lm.ts # LiquidityManager indexing
│ │ │ └── stake.ts # Stake indexing
│ └── txnBot/ # Automation bot: calls recenter() and payTax() on profitable opportunities
├── landing/ # Landing page (Vue 3)
│ ├── src/
│ │ ├── components/ # LiveStats, KFooter, WalletCard, etc.
│ │ ├── views/ # HomeView variants, docs pages
│ │ └── router/
├── web-app/ # Staking app (Vue 3)
│ ├── src/
│ │ ├── components/ # ProtocolStatsCard, etc.
│ │ └── views/ # LoginView, StakeView, etc.
├── kraiken-lib/ # Shared TypeScript helpers (bigint math, ABIs, encoding) for frontend and indexer
│ └── src/ # abis, format, ids, position, snatch, staking, subgraph, taxRates, version
├── containers/ # Docker configs, entrypoints
├── docs/ # This file, PRODUCT-TRUTH.md
└── .woodpecker/ # CI pipeline configs
```