Changelog

CHANGELOG — Growth Engineer at Envio Candidate Package

This is a chronological record of how the package evolved. The atomic unit is a commit; commits are grouped by phase. Reverse-chronological — most recent first.


2026-05-01 — Proof-of-work readability pass: PROOF_OF_WORK.md + per-template RUN.md + saved harness transcripts

The package was already complete (3/3 templates live-verified, 48,014/48,014 invariant checks passing), but the proof was spread across 18 JSON captures + 3 README sections. A reviewer landing cold had to piece it together. This pass adds three readability artifacts so the proof is legible at a glance:

  • PROOF_OF_WORK.md at repo root — one-page scoreboard with vitest counts, invariant counts, live-check counts, chain provenance (with block-explorer links), 4-line replay block. The doc that answers "what is the PoW" without explanation.
  • Saved harness output transcriptsdocs/screenshots/queries{,-defi,-perp}/HARNESS_OUTPUT.txt. The literal stdout from the recorded pnpm assert* runs. A reviewer who doesn't want to re-run anything can cat these and see the per-invariant ✓ PASS lines + Summary: N/N checks passed totals.
  • Per-template RUN.md in each pow/*/ — five-line reproduction guide (install → test → dev → assert) with the public RPC URL preset. Audience differs from README.md (which is for studying the template's architecture); RUN.md is for reproducing the proof.

Updated scripts/demo-capture/README.md with a "saved harness output transcripts" section pointing at the three TXT files.

No template code touched, no harness logic changed. All three vitest suites still passing; both repos still match the 2026-04-30 scoreboard (48,014/48,014).


2026-04-30 — DEX + perp harness extension; perp pivots to real GMX v2 EventEmitter

Closed the consistency gap from "1/3 templates live-verified" to 3/3 templates live-verified.

DEX harness (pnpm assert:defi against Optimism Velodrome V2): 8 invariants × 31,091 checks, all passing. Caught two real bugs in the harness itself during development:

  • Unstable Hasura pagination (order_by + offset without unique tiebreaker re-emitted rows; fixed by adding id asc as secondary sort key + dedup pass)
  • Bad heuristic D8 ("pools with swapCount > 100 have reserve0 < cumulativeVolume0") — false for pools with large LPs and few swaps; replaced with "pools with cumulativeVolume0 > 0 have at least one PoolHourSnapshot"

Perp template pivoted to GMX v2's real EventEmitter pattern. The previous synthesised flat-event ABIs (PositionIncrease(positionKey, account, isLong, ...)) were a teaching scaffold that no real protocol emits. Now the template:

  • Subscribes to a single global EventEmitter on Arbitrum (0xC8ee91A54287DB53897056e12D9819156D3822Fb, deploy block 107,737,756)
  • Routes events on the eventName string field
  • Decodes EventLogData (a typed-dictionary tuple-of-tuples) into typed entity fields via src/Effects/decodeEventLogData.ts
  • v1 scope: PositionIncrease only — proves the architecture works against real chain data; v2 (PositionDecrease, Liquidation, Funding, OrderExecuted) is mechanical follow-up documented inline

Perp harness (pnpm assert:perp against Arbitrum GMX v2, v1 scope): 4 invariants × 2,522 checks, all passing on real data. 9 perp markets, 1,252 positions indexed end-to-end through the EventLog1 → decode → entity flow. Real position sizes up to $950k.

Total: 21 invariants × 48,014 cross-entity checks across three different real-world protocols (Aave V3 / Polygon, Velodrome V2 / Optimism, GMX v2 / Arbitrum). Both repos pushed.


2026-04-30 — Live-indexer assertion harness (pnpm assert)

Added scripts/demo-capture/assertions.mjs — a script that queries the live pnpm dev indexer and checks 9 cross-entity invariants the schema implies. First run: 14,401 / 14,401 checks passed across 9 invariants on real Aave V3 history (1,089 liquidations, 5000 user-reserves, 16 reserves, 9990 user-aggregators).

The harness catches a different class of bug from the unit tests:

  • Unit tests use MockDb with ~5–10 synthetic events; pass/fail on contrived data
  • This harness queries real Polygon Aave V3 history and asserts cross-entity invariants — would fail if any handler bug produced inconsistent state across thousands of real events

The 9 invariants anchor on the liquidation lifecycle (the trickiest event in the vertical):

  • L1–L2: FK integrity from LiquidationReserve (both collateral + debt sides)
  • L3–L4: counter increments on UserAggregator for victim + liquidator
  • L5: aggregator total >= count of liquidations touching this reserve (catches single-side bug)
  • L6–L7: counter sanity (uniqueSuppliers >= 1 when totalSupplied > 0, same for borrowers)
  • L8–L9: arithmetic invariants (netSupplyPosition == cumulativeSupplied - cumulativeWithdrawn, same for debt)

Not in CI — the harness requires a running pnpm dev against Polygon. It's a manual reproduction step; documented as such with sample output in scripts/demo-capture/README.md.

Money-market template only in v1; same pattern would apply to DEX + perp templates as a follow-up.


2026-04-30 — Live Aave V3 indexing run + template-quality bug fix

Ran the money-market template end-to-end against real Aave V3 on Polygon mainnet. Indexed ~1.4M Polygon blocks of Aave V3 history (block 25,826,028 → ~27,300,000+) before stopping. Captured 6 GraphQL response dumps + 2 PNG screenshots in docs/screenshots/:

  • 16 distinct Aave V3 reserves on Polygon (USDC, DAI, WMATIC, WBTC, WETH, AAVE, LINK, etc.) with real totalSupplied / totalBorrowed aggregates
  • 119 liquidations preserved as Liquidation entities with real victim addresses, liquidator addresses (0x36d43ccb... shows up multiple times — clearly an active liquidator bot from April 2022), collateral/debt amounts in BigInt wei
  • 1000+ UserReserve, UserAggregator, ReserveRateSnapshot entities

Real bug surfaced + fixed in the process. pnpm dev failed on first run with ERR_REQUIRE_ESM — Envio v2's bundled ts-node@10.9.1 couldn't load Pool.ts because the template had "type": "module" + "module": "ESNext" in tsconfig, which made Node's ESM loader claim ownership of .ts files but ts-node's CJS-default loader couldn't bridge them. Fix: remove "type": "module" from package.json + add a "ts-node" block in tsconfig.json overriding to "module": "CommonJS" for the runtime path. ESNext/Bundler stays for vitest/tsc compile path. Applied to all three templates (defi, money-market, perp); 19/19 vitest still passing across them.

This is the kind of bug a reviewer catches in the first 60 seconds. Running the indexer ourselves caught it first.

Captures reproducible via scripts/demo-capture/ (separate package — playwright lives there, doesn't bloat template installs).


2026-04-30 — PM vertical pivot to money market (Aave V3)

After surveying the customer base, enviodev/polymarket-v2-indexer (opens in a new tab) was identified as Envio's production-shipped indexer for Polymarket V2 (CTFExchange + PolyUSD + Rewards). My synthesised envio-pm-template-v1 was at best parallel and at worst redundant against that production reference. Money market replaces PM as the second-anchor vertical.

Why money market:

  • Third of the four DeFi shapes named in the playbook §3 ("DEX, perp, money market, execution layer") — closes the third-shape claim
  • Comparable analytics-as-product structure to PM (risk dashboards = leaderboards in PM terms)
  • Aave V3 multi-chain TVL >$10B; structurally a major vertical
  • No current Envio-team production indexer for money market — clean candidate-team opportunity

What changed:

  • Removed: pow/envio-pm-template-v1/, contracts/pm/, test/pm/, script/DeployPMSepolia.s.sol, docs/gas-report.txt, 5 PM-specific memos (PREDICTION_MARKETS_TEMPLATE, PREDICTION_MARKETS_TECH_DIAGNOSTIC, PREDICTION_MARKETS_POSITIONING_AUDIT, SETTLEMENT_HANDLER_REFERENCE, LEADERBOARD_QUERY_ARCHITECTURE)
  • Added: pow/envio-money-market-template-v1/ (Aave-V3-shaped, 5/5 vitest), 5 money-market-specific memos mirroring the deleted PM memo structures (TEMPLATE, TECH_DIAGNOSTIC, POSITIONING_AUDIT, LIQUIDATION_HANDLER_REFERENCE, RISK_DASHBOARD_QUERY_ARCHITECTURE)
  • Updated: ENVIO_VERTICAL_PLAYBOOK.md §4 worked example, ENVIO_PAIN_MAP_MATRIX.md second-vertical column (10 cells), cross-reference link rewrites in DEFI_60MIN_TEMPLATE / EFFECT_API_PATTERN / MULTICHAIN_EXPANSION_RUNBOOK / DECK_OUTLINE
  • CI: dropped pm-template job + contracts job; added money-market-template job. Three CI jobs total: defi-template, money-market-template, perp-template

Polymarket and Limitless still appear in ENVIO_CLICKHOUSE_DECK.md, ENVIO_CLICKHOUSE_TEARDOWN.md, ENVIO_INDEXER_TEARDOWN.md as factual customer-wall references (4B events on Polygon is real evidence). They are not vertical-strategy claims; they are customer facts.


Day 3 — Multi-chain CLI + polish (architecture diagrams + gas report + CHANGELOG)

  • Multi-chain expansion CLI at scripts/add-chain.ts in all three templates (DEX, PM, perp). Reads a chain config JSON, deterministically patches config.yaml + src/Constants.ts. Idempotent — re-running with the same config is a no-op. Implements ENVIO_MULTICHAIN_EXPANSION_RUNBOOK.md as code.
  • docs/architecture.md — Mermaid diagrams of the three-layer indexer architecture, the four-state settlement machine, the dual-write Production-vs-Dedicated tier upgrade path, and the repo layout.
  • docs/gas-report.txtforge test --gas-report output committed; regenerated by CI on every push.
  • CHANGELOG.md — this file.

Day 2 — GMX-v2-shaped perp template

  • pow/envio-perp-template-v1/ — third forkable indexer scaffold. Anchors §3 of ENVIO_VERTICAL_PLAYBOOK.md's "DEX, perp, money market, execution layer" claim with running code. Same three-layer architecture as the DEX template; perp-specific entities (Position, Liquidation, FundingSnapshot); event signatures adapted from gmx-io/gmx-synthetics (opens in a new tab).
  • 4 vitest tests for the perp aggregator math: PositionIncrease + open interest, PositionDecrease + signed PnL accumulation, Liquidation + isLiquidated latch, FundingFeeAmountPerSizeUpdated + FundingSnapshot write.
  • CI updated to add a perp-template job (alongside contracts, defi-template, pm-template).

Day 1 — CI + Sepolia deploy script + hardening

  • GitHub Actions CI workflow at .github/workflows/ci.yml in both repos. Four jobs: contracts (Foundry build + tests + gas report), defi-template, pm-template, perp-template (each: pnpm install + envio codegen + tsc + vitest). CI badge added to top-level README in the standalone repo.
  • PM contracts deployed to Sepolia (pending) — broadcast script at script/DeployPMSepolia.s.sol is dry-run validated. --broadcast step is gated on explicit user textual go-ahead due to safety guardrails on irreversible on-chain spends. When it lands, deployed-addresses.json + live-indexing screenshots committed to docs/screenshots/.
  • DeFi Effect API now does real viem ERC-20 reads with rate-limiting, lazy chain-keyed client cache, and Sablier-style 0-alias fallback for non-conformant tokens.
  • PM leaderboard scan — replaced stub with in-memory accumulator + top-N sort. Production-tier shape; ClickHouse Sink Dedicated tier is the documented upgrade path.
  • vitest suites — 5 PM tests covering all four state transitions + race-safe correction guard; 7 DeFi tests covering apply* functions + snapshot epoch boundary.

Pre-day-1 — Original PoW pass

  • PM Solidity contracts (contracts/pm/): PMMarketFactory, PMMarket, PMMockOracle. Implements the on-chain twin of the indexer's four-state machine. Event signatures byte-identical to the indexer's ABI files.
  • 15 Foundry tests (test/pm/PMMarket.t.sol) covering lifecycle + correction + 9 guard conditions.
  • Sepolia deploy script (script/DeployPMSepolia.s.sol).
  • Two forkable Envio indexer templates (pow/envio-defi-template-v1/, pow/envio-pm-template-v1/) with real Velodrome ABIs, three-layer architecture (EventHandlers → Aggregators → Snapshots), dynamic contract registration, Effect API integration.

Pre-PoW — Strategy memo set

  • 23 ENVIO_*.md memos — vertical playbook, pain-map matrix, 4 Week-One diagnostics, 6 tech artifact specs, 5 companion analyses, decks. Each prose artifact carries a footer naming the §2 pain-map cell + revenue mechanism it addresses.

Verification surface

CheckStatus
forge buildgreen (CI)
forge test --match-path test/pm/*15/15 (CI)
pow/envio-defi-template-v1: install / codegen / tsc / test7/7 (CI)
pow/envio-pm-template-v1: install / codegen / tsc / test5/5 (CI)
pow/envio-perp-template-v1: install / codegen / tsc / test4/4 (CI)
pnpm add-chain idempotentmanually verified
Sepolia broadcastpending user go-ahead

31 automated tests, 3 indexer templates, 1 contract suite, 23 memos, 1 CLI, all green.