7.1 KiB
Ponder LM Indexing - Backend Metrics Implementation
Branch: feat/ponder-lm-indexing
Commit: 3ec9bfb
Date: 2026-02-16
Summary
Successfully implemented backend indexing for three key protocol metrics:
- ETH Reserve Growth (7d) ✅
- Floor Price per KRK ✅
- Trading Fees (7d) ⚠️ Infrastructure ready, awaiting implementation
Changes Made
1. Schema Updates (ponder.schema.ts)
Extended stats Table
Added fields to track new metrics:
// 7-day ETH reserve growth metrics
ethReserve7dAgo: bigint (nullable)
ethReserveGrowthBps: int (nullable) // basis points
// 7-day trading fees earned
feesEarned7dEth: bigint (default 0n)
feesEarned7dKrk: bigint (default 0n)
feesLastUpdated: bigint (nullable)
// Floor price metrics
floorTick: int (nullable)
floorPriceWei: bigint (nullable) // wei per KRK
currentPriceWei: bigint (nullable)
floorDistanceBps: int (nullable) // distance from floor in bps
New Tables
-
ethReserveHistory: Tracks ETH balance over time for 7-day growth calculationsid(string): block_logIndex formattimestamp(bigint): event timestampethBalance(bigint): ETH reserve at that time
-
feeHistory: Infrastructure for fee tracking (ready for Collect events)id(string): block_logIndex formattimestamp(bigint): event timestampethFees(bigint): ETH fees collectedkrkFees(bigint): KRK fees collected
2. Handler Updates (src/lm.ts)
New Helper Functions
-
priceFromTick(tick: number): bigint- Calculates price in wei per KRK from Uniswap V3 tick
- Uses formula:
price = 1.0001^tick - Accounts for WETH as token0 in the pool
- Returns wei-denominated price for precision
-
calculateBps(newValue: bigint, oldValue: bigint): number- Calculates basis points difference:
(new - old) / old * 10000 - Used for growth percentages and distance metrics
- Calculates basis points difference:
Updated Event Handlers
EthScarcity and EthAbundance Handlers:
-
Record ETH Reserve History
- Insert ethBalance into
ethReserveHistorytable - Enables time-series analysis
- Insert ethBalance into
-
Calculate 7-Day Growth
- Look back 7 days in
ethReserveHistory - Find oldest record within window
- Calculate growth in basis points
- Updates:
ethReserve7dAgo,ethReserveGrowthBps
- Look back 7 days in
-
Calculate Floor Price
- Uses
vwapTickfrom event as floor tick - Converts to wei per KRK using
priceFromTick() - Updates:
floorTick,floorPriceWei
- Uses
-
Calculate Current Price
- Uses
currentTickfrom event - Converts to wei per KRK
- Updates:
currentPriceWei
- Uses
-
Calculate Floor Distance
- Computes distance from floor in basis points
- Formula:
(currentPrice - floorPrice) / floorPrice * 10000 - Updates:
floorDistanceBps
Recentered Handler:
- Cleaned up: removed direct ETH balance reading
- Now relies on EthScarcity/EthAbundance events for balance data
- Maintains counter updates for recenter tracking
Fee Tracking Status
Current State: Infrastructure Ready ⚠️
The fee tracking infrastructure is in place but not yet populated with data:
feeHistorytable exists in schemafeesEarned7dEthandfeesEarned7dKrkfields default to0nfeesLastUpdatedfield available
Implementation Options
Documented two approaches in code:
Option 1: Uniswap V3 Pool Collect Events (Recommended)
Pros:
- Accurate fee data directly from pool
- Clean separation of concerns
Cons:
- Requires adding UniswapV3Pool contract to
ponder.config.ts - Forces a full re-sync from startBlock (significant downtime)
Implementation Steps:
- Add pool contract to
ponder.config.ts:UniswapV3Pool: { abi: UniswapV3PoolAbi, chain: NETWORK, address: '<pool-address>', startBlock: selectedNetwork.contracts.startBlock, } - Add handler for
Collect(address owner, int24 tickLower, int24 tickUpper, uint128 amount0, uint128 amount1) - Filter for LM contract as owner
- Record to
feeHistorytable - Calculate 7-day rolling totals
Option 2: Derive from ETH Balance Changes
Pros:
- No config changes needed
- No resync required
Cons:
- Less accurate (hard to isolate fees from other balance changes)
- More complex logic
- Potential edge cases
Recommendation
Wait for next planned resync or maintenance window to implement Option 1 (Collect events). This provides the most accurate and maintainable solution.
Verification
All success criteria met:
✅ Schema compiles (valid TypeScript)
npm run build
# ✓ Wrote ponder-env.d.ts
✅ New fields added to stats
- ethReserve7dAgo, ethReserveGrowthBps
- feesEarned7dEth, feesEarned7dKrk, feesLastUpdated
- floorTick, floorPriceWei, currentPriceWei, floorDistanceBps
✅ EthScarcity/EthAbundance handlers updated
- Record history to
ethReserveHistory - Calculate 7-day growth
- Calculate floor and current prices
- Calculate floor distance
✅ Fee tracking infrastructure
feeHistorytable created- Fee fields in stats table
- Documentation for implementation approaches
✅ Git commit with --no-verify
git log -1 --oneline
# 3ec9bfb feat(ponder): add ETH reserve growth, floor price, and fee tracking metrics
✅ Linting passes
npm run lint
# (no errors)
Testing Recommendations
-
Deploy to staging and verify:
ethReserveHistorytable populates on Scarcity/Abundance events- 7-day growth calculates correctly after 7 days of data
- Floor price calculations match expected values
- Current price tracks tick movements
-
API Integration:
- Query
statstable for dashboard metrics - Use
ethReserveHistoryfor time-series charts - Monitor for null values in first 7 days (expected)
- Query
-
Future Fee Implementation:
- Plan maintenance window for resync
- Test Collect event handler on local fork first
- Verify fee calculations match pool data
Technical Notes
Price Calculation Details
- Formula:
price = 1.0001^tick - Token Order: WETH (0x4200...0006) < KRK (0xff196f...) → WETH is token0
- Conversion: Price in KRK/WETH → invert to get wei per KRK
- Precision: Uses
BigIntfor wei-level accuracy, floating point only for tick math
7-Day Lookback Strategy
- Simple approach: Query
ethReserveHistoryfor oldest record ≥ 7 days ago - Performance: Acceptable given low event volume (~50-200 recenters/week)
- Edge case: Returns
nullif less than 7 days of history exists
Data Consistency
- Both EthScarcity and EthAbundance handlers implement identical logic
- Ensures consistent metrics regardless of recenter direction
- History records use
block_logIndexformat for unique IDs
Files Modified
/home/debian/harb/services/ponder/ponder.schema.ts(+50 lines)/home/debian/harb/services/ponder/src/lm.ts(+139 lines, -32 lines)
Total: +157 lines, comprehensive implementation with documentation.
Status: ✅ Ready for staging deployment
Next Steps: Monitor metrics in staging, plan fee implementation during next maintenance window