KeeperHub / KeeperHub/keeperhub

Workflows cannot trigger on a threshold over contract state, only on emitted events

Open
#2,240 10 comments 0 reactions 0 assignees View on GitHub
accepted enhancement help wanted
Dominant language
TypeScript
Stars
24
Forks
93
Avg merge
1d 4h
Merged PRs (30d)
253

Description

Part of #2239. Tier 1 of four - ranked first for unlock per unit of cost.

## Reason: what cannot be done today

A workflow cannot trigger on a threshold over derived contract state. "Health factor below 1.05", "LTV above X", "collateral ratio drifted", "balance below Y" are all conditions users want to act on, and most protocols do not emit an event when a derived value crosses a threshold. Aave emits on borrow, repay and liquidation; it does not emit when your health factor passes 1.05 on its way down because of a price move elsewhere.

On-chain observation today is `eth_getLogs` and nothing else (`keeperhub-events/event-tracker/src/chains/provider-manager.ts:11`), so a condition that no contract emits an event for cannot start a workflow at all.

**What the workaround costs:** a Schedule trigger polling on a fixed interval, with the comparison expressed as workflow steps. That pays for a full workflow execution on every poll whether or not the condition holds, and its resolution is bounded by the schedule interval rather than by block time. For position management - where the whole value is acting before a liquidation - a polling interval long enough to be affordable is long enough to be useless.

## Scope: what this touches, and what it does not

**In scope:** a trigger type that evaluates an `eth_call` against a user-specified view function once per block and compares the decoded result against a threshold. It reuses the block subscription the event-tracker already maintains, so the marginal cost is one RPC call per block per subscription.

**Not in scope:** trace and internal-call observation (tier 2), off-chain feeds (tier 3), pre-inclusion observation (tier 4). Also not in scope: how fast a workflow runs once triggered.

This is one change - a new trigger source. It ships and is useful without any other tier.

**Works on all 10 EVM mainnets** with no per-chain work, because `eth_call` is the same call everywhere on EVM. That is the main reason it is ranked first.

Solana is the exception and is out of scope here: it is `chainType: "solana"`, has no `eth_call`, and would need its own state-read path (`getAccountInfo` / `getProgramAccounts`) through the existing `solana-tracker`. Worth a follow-up issue if the EVM version proves out.

## Plan

The mechanism is straightforward; the semantics are where the design work is. **A threshold trigger is a condition, not an event.** It is true for as long as it holds, so a naive implementation fires on every block until the user's position recovers. It needs:

- **Edge detection** - fire on the transition into the condition, not on the state
- **Hysteresis or an explicit re-arm rule** - otherwise a value oscillating around the threshold produces a burst of executions

The existing dedup store keys on `transactionHash` (`keeperhub-events/event-tracker/src/listener/event-listener.ts:200-220`), which does not exist for a state-derived trigger. A new dedup identity is needed and is the part most likely to need agreement before code.

Open questions that triage should settle first:

- Where does evaluation live - the existing event-tracker, or a new satellite? Per-block `eth_call` fan-out across many subscriptions has a different scaling shape to batched `eth_getLogs`, which is deliberately rate-limited to one request per second per chain (`provider-manager.ts:108`).
- How does a user express the call and the comparison in the builder without it turning into a scripting surface?
- Cost control: one call per block per subscription, across chains with sub-second block times.

Anyone picking this up should propose an answer to the edge-detection and dedup-identity questions in a comment before writing code. Two reasonable implementations that differ there will not be mergeable together.

---
Tracking: [KEEP-1273](https://linear.app/keeperhubapp/issue/KEEP-1273) (internal tracker, not publicly accessible)

Contributor guide

Open the contributing guide

Research direction

Start by reading keeperhub-events/event-tracker/src/chains/provider-manager.ts, especially the provider and block-subscription handling, then inspect keeperhub-events/event-tracker/src/listener/event-listener.ts:200-220 for the transaction-based deduplication. Before writing code, propose decisions for edge detection, re-arming or hysteresis, and a dedup identity; done means the trigger design is agreed and supports the stated EVM threshold use case without covering Solana.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, blockchain
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.