- Add scripts/harb-evaluator/run-resources.sh: collects disk, RAM, Anthropic API usage, and Woodpecker CI queue metrics - Add scripts/harb-evaluator/run-protocol.sh: collects TVL, fees, position data, and rebalance events from LiquidityManager - Fix run-protocol.toml: positions accessed via positions(uint8) not named getters (floorPosition/anchorPosition/discoveryPosition) - Fix event signature: Recentered(int24,bool) not Recenter(int24,int24,int24) Addresses review findings: missing implementation files and contract interface mismatch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
187 lines
7.9 KiB
TOML
187 lines
7.9 KiB
TOML
# formulas/run-protocol.toml
|
|
#
|
|
# On-chain protocol health snapshot — collect TVL, accumulated fees,
|
|
# position count, and rebalance frequency from the deployed LiquidityManager.
|
|
# Write a structured JSON evidence file for planner and predictor consumption.
|
|
#
|
|
# Type: sense. Read-only — produces metrics only, no git artifacts.
|
|
#
|
|
# Staleness threshold: 1 day (matches evidence/protocol/ schema).
|
|
# Cron: daily at 07:00 UTC (staggered 1 h after run-resources).
|
|
|
|
[formula]
|
|
id = "run-protocol"
|
|
name = "On-Chain Protocol Health Snapshot"
|
|
description = "Collect TVL, accumulated fees, position count, and rebalance frequency from the deployed LiquidityManager; write evidence/protocol/{date}.json."
|
|
type = "sense"
|
|
# "sense" → read-only, produces metrics only
|
|
# "act" → produces git artifacts (cf. run-evolution, run-red-team)
|
|
|
|
# ── Cron ───────────────────────────────────────────────────────────────────────
|
|
|
|
[cron]
|
|
schedule = "0 7 * * *" # daily at 07:00 UTC (1 h after run-resources)
|
|
description = "Matches 1-day staleness threshold — one snapshot per day keeps the record fresh."
|
|
|
|
# ── Inputs ─────────────────────────────────────────────────────────────────────
|
|
|
|
[inputs.rpc_url]
|
|
type = "string"
|
|
required = true
|
|
description = """
|
|
Base network RPC endpoint used to query on-chain state.
|
|
Example: https://mainnet.base.org or a running Anvil fork URL.
|
|
"""
|
|
|
|
[inputs.deployments_file]
|
|
type = "string"
|
|
required = false
|
|
default = "onchain/deployments-local.json"
|
|
description = """
|
|
Path to the deployments JSON file containing contract addresses.
|
|
The formula reads LiquidityManager address from this file.
|
|
Use onchain/deployments.json for mainnet; onchain/deployments-local.json
|
|
for a local Anvil fork.
|
|
"""
|
|
|
|
[inputs.lookback_blocks]
|
|
type = "integer"
|
|
required = false
|
|
default = 7200
|
|
description = """
|
|
Number of blocks to scan for Recenter events when computing
|
|
rebalance_count_24h (~24 h of Base blocks at ~2 s/block).
|
|
"""
|
|
|
|
# ── Execution ──────────────────────────────────────────────────────────────────
|
|
|
|
[execution]
|
|
script = "scripts/harb-evaluator/run-protocol.sh"
|
|
invocation = "RPC_URL={rpc_url} DEPLOYMENTS_FILE={deployments_file} LOOKBACK_BLOCKS={lookback_blocks} bash scripts/harb-evaluator/run-protocol.sh"
|
|
|
|
# Exit codes:
|
|
# 0 snapshot written successfully
|
|
# 2 infrastructure error (RPC unreachable, missing deployments file, forge unavailable, etc.)
|
|
|
|
# ── Steps ──────────────────────────────────────────────────────────────────────
|
|
|
|
[[steps]]
|
|
id = "read-addresses"
|
|
description = """
|
|
Read the LiquidityManager contract address from {deployments_file}.
|
|
Fail with exit code 2 if the file is absent or the address is missing.
|
|
"""
|
|
|
|
[[steps]]
|
|
id = "collect-tvl"
|
|
description = """
|
|
Query LiquidityManager total ETH via forge script LmTotalEth.s.sol
|
|
against {rpc_url}.
|
|
Records tvl_eth (wei string) and tvl_eth_formatted (ETH, 2 dp).
|
|
LmTotalEth.s.sol uses exact Uniswap V3 integer math (LiquidityAmounts +
|
|
TickMath) to sum free ETH, free WETH, and ETH locked across all three
|
|
positions (floor, anchor, discovery).
|
|
"""
|
|
forge_script = "onchain/script/LmTotalEth.s.sol"
|
|
|
|
[[steps]]
|
|
id = "collect-fees"
|
|
description = """
|
|
Query accumulated protocol fees from the LiquidityManager via cast call:
|
|
cast call $LM "accumulatedFees()(uint256)"
|
|
Records accumulated_fees_eth (wei string) and accumulated_fees_eth_formatted
|
|
(ETH, 3 dp).
|
|
Falls back to 0 gracefully if the function reverts or is not present on
|
|
the deployed contract (older deployment without fee tracking).
|
|
"""
|
|
|
|
[[steps]]
|
|
id = "collect-positions"
|
|
description = """
|
|
Query the three Uniswap V3 positions held by the LiquidityManager:
|
|
LiquidityManager.positions(0) → (liquidity, tickLower, tickUpper) # FLOOR
|
|
LiquidityManager.positions(1) → (liquidity, tickLower, tickUpper) # ANCHOR
|
|
LiquidityManager.positions(2) → (liquidity, tickLower, tickUpper) # DISCOVERY
|
|
Records position_count (number of positions with liquidity > 0) and the
|
|
positions array.
|
|
"""
|
|
|
|
[[steps]]
|
|
id = "collect-rebalances"
|
|
description = """
|
|
Count Recenter events emitted by the LiquidityManager in the past
|
|
{lookback_blocks} blocks via eth_getLogs.
|
|
Records:
|
|
- rebalance_count_24h: total Recenter event count in the window.
|
|
- last_rebalance_block: block number of the most recent Recenter event
|
|
(0 if none found in the window).
|
|
"""
|
|
event_signature = "Recentered(int24,bool)"
|
|
|
|
[[steps]]
|
|
id = "collect"
|
|
description = """
|
|
Assemble all collected metrics into evidence/protocol/{date}.json.
|
|
Compute verdict:
|
|
- "offline" if tvl_eth = 0 or RPC was unreachable.
|
|
- "degraded" if position_count < 3, or rebalance_count_24h = 0 and the
|
|
protocol has been live for > 1 day.
|
|
- "healthy" otherwise.
|
|
Write the file conforming to the schema in evidence/README.md
|
|
## Schema: protocol/YYYY-MM-DD.json.
|
|
"""
|
|
output = "evidence/protocol/{date}.json"
|
|
schema = "evidence/README.md" # see ## Schema: protocol/YYYY-MM-DD.json
|
|
|
|
[[steps]]
|
|
id = "deliver"
|
|
description = """
|
|
Commit evidence/protocol/{date}.json to main.
|
|
Post a one-line summary comment to the originating issue (if any):
|
|
verdict, tvl_eth_formatted, accumulated_fees_eth_formatted,
|
|
position_count, rebalance_count_24h.
|
|
On "degraded" or "offline": highlight the failing dimension and its value.
|
|
"""
|
|
|
|
# ── Products ───────────────────────────────────────────────────────────────────
|
|
|
|
[products.evidence_file]
|
|
path = "evidence/protocol/{date}.json"
|
|
delivery = "commit to main"
|
|
schema = "evidence/README.md" # see ## Schema: protocol/YYYY-MM-DD.json
|
|
|
|
[products.issue_comment]
|
|
delivery = "post to originating issue (if any)"
|
|
content = "verdict, tvl_eth_formatted, accumulated_fees_eth_formatted, position_count, rebalance_count_24h"
|
|
on_degraded = "highlight failing dimension and its current value"
|
|
|
|
# ── Resources ──────────────────────────────────────────────────────────────────
|
|
|
|
[resources]
|
|
profile = "light"
|
|
compute = "local — forge script + cast calls only; no Anvil or Docker startup required"
|
|
rpc = "Base network RPC ({rpc_url}) — read-only calls"
|
|
concurrency = "safe to run in parallel with other formulas"
|
|
|
|
# ── Notes ──────────────────────────────────────────────────────────────────────
|
|
|
|
[notes]
|
|
tvl_metric = """
|
|
TVL is measured as LiquidityManager total ETH: free ETH + free WETH + ETH
|
|
locked across all three Uniswap V3 positions (floor, anchor, discovery).
|
|
Uses the same LmTotalEth.s.sol forge script as run-red-team to ensure
|
|
consistent measurement methodology.
|
|
"""
|
|
|
|
rebalance_staleness = """
|
|
A zero rebalance_count_24h on an established deployment indicates the
|
|
recenter() upkeep bot (services/txnBot) has stalled. The "degraded"
|
|
verdict triggers a planner alert. On a fresh deployment (< 1 day old)
|
|
zero rebalances is expected and does not trigger degraded.
|
|
"""
|
|
|
|
fees_fallback = """
|
|
accumulated_fees_eth falls back to 0 for deployments without fee tracking.
|
|
The verdict is not affected by a zero fee value alone — only TVL and
|
|
position_count drive the verdict.
|
|
"""
|