@@ -79,7 +79,13 @@ for the report lifecycle assumptions and economics used by the arbitrager.
7979## Requirements
8080
8181- Bun and this project's frozen dependencies.
82- - An RPC endpoint for Ethereum mainnet or Sepolia. An archive-capable endpoint is recommended when
82+ - An RPC endpoint for Ethereum mainnet or Sepolia. Approved-coordinator discovery
83+ uses current contract state and does not require historical log access. Legacy
84+ journals without a persisted dispute index are the bounded exception: after a
85+ restart, replacement-credit recovery scans only that report's dispute logs from
86+ its entry block until the immediate successor. Execution RPCs must therefore
87+ retain log history back to the oldest open legacy position's entry block. Archive
88+ access can also be useful for coordinator-free diagnostic mode when
8389 ` runtime.lookbackBlocks ` reaches beyond the provider's retained log history.
8490- The deployed OpenOracle contract address.
8591- At least one reviewed Zoltar ` OpenOraclePriceCoordinator ` address for every
@@ -268,36 +274,33 @@ available when RPC validation is temporarily unavailable, reports
268274` connectivity-degraded ` , and retries with bounded backoff. The bot checks the chain
269275before every scan.
270276
271- Startup enters ** Syncing** while the bot scans the configured historical lookback in
272- 100-block chunks. The deliberately bounded response size prevents permissionless
273- OpenOracle event volume from turning one historical RPC response into an unbounded
274- memory spike. Once caught up, it polls the latest head and covers every unseen
275- height in the OpenOracle event-log query; if several blocks arrive between polls, no
276- event-log height is skipped. Opportunity evaluation and pool sampling run once at
277- the newest observed head, not once at every intermediate historical height. A
278- 12-block overlap is re-read and reconciled for shallow reorgs in event-derived
279- report state. With no new head the bot remains ** Running** without re-evaluating or
280- writing duplicate price samples.
277+ With approved coordinators configured, startup discovers reports by reading each
278+ coordinator's ` pendingReportId ` at one fixed block and then reads the corresponding
279+ stored OpenOracle state. It repeats those current-state reads at each new head and
280+ does not query historical OpenOracle logs. Execution mode requires a quorum to agree
281+ on the block and report snapshot. Opportunity evaluation and pool sampling run once
282+ at the newest agreed head. With no new head the bot remains ** Running** without
283+ re-evaluating or writing duplicate price samples.
284+
285+ Coordinator-free diagnostic mode retains the historical fallback: startup scans
286+ ` runtime.lookbackBlocks ` in 100-block log-query chunks, then reads a 12-block overlap
287+ at each new head for shallow reorganization handling. The deliberately bounded
288+ response size prevents permissionless event volume from producing an unbounded RPC
289+ response.
281290
282291### Data freshness and retention
283292
284- Startup lookback backfills OpenOracle events, but it does not backfill historical
285- pool prices. The price file can retain a sample from a block displaced by a reorg;
286- the 12-block reconciliation applies only to report events. The bot reads at most the
287- latest 8 MiB, loads and charts the latest 2,000 valid price records, and atomically
288- compacts the file to those records after it crosses 8 MiB. Approved-coordinator report
289- paths are reconstructed in memory from the startup lookback plus events observed by
290- the current process. Consequently a path can begin at a dispute when its submission
291- predates the lookback, and a settlement-only report is not shown when no earlier
292- event for that report was observed. For each active report, the scanner retains one
293- pre-overlap state anchor plus every event in the 12-block reorg window; older dispute
294- steps are compacted instead of replayed forever. Settled paths remain through that
295- reorg window and are then removed from the live scanner; confirmed transaction
296- history remains in the execution history file. Unapproved reports are not retained
297- in the execution cache. In diagnostic mode without configured coordinators, at most
293+ The price file can retain a sample from a block displaced by a reorganization. The
294+ bot reads at most the latest 8 MiB, loads and charts the latest 2,000 valid price
295+ records, and atomically compacts the file to those records after it crosses 8 MiB.
296+ Approved-coordinator monitoring keeps the complete current state of each pending
297+ report but does not reconstruct its historical dispute path from logs. Reports that
298+ are no longer pending are removed from the live cache; confirmed bot transaction
299+ history remains in the execution history file. In coordinator-free diagnostic mode,
300+ the startup lookback backfills report events but not historical pool prices. At most
298301256 reports and 64 permissionlessly observed tokens are retained so event spam
299- cannot create ever-growing per-block work. Increase ` runtime.lookbackBlocks ` when
300- complete active-game context is operationally important.
302+ cannot create ever-growing per-block work. Increase ` runtime.lookbackBlocks ` only
303+ when broader diagnostic event history is operationally important.
301304
302305## Run on Sepolia
303306
@@ -630,9 +633,8 @@ The dashboard shows:
630633- Selected network, expected chain ID, read/public RPC controls, and endpoint checks.
631634- A local signer control, connected address, and its ETH/WETH/REP balances.
632635- ETH, WETH, REP, executable REP value, and estimated portfolio value.
633- - Native ETH stakes, WETH stakes, and ETH settler rewards locked in active games
634- observed within the configured event lookback. The combined figure treats 1 WETH
635- as 1 ETH and can undercount games created before that lookback.
636+ - Native ETH stakes, WETH stakes, and ETH settler rewards locked in reports currently
637+ pending on configured coordinators. The combined figure treats 1 WETH as 1 ETH.
636638- Current opportunities, token-metadata-normalized inventory requirements, deadline
637639 window, token-specific direction, pool, and decision.
638640- Durable positions with actual hedge execution, entry and lifecycle gas, exact
@@ -658,8 +660,10 @@ The dashboard shows:
658660 address links to the selected-network explorer. The [ market discovery section] ( #token-and-pool-discovery )
659661 owns the venue, price, and liquidity semantics. A token with no supported pool is
660662 explicitly labeled instead of disappearing.
661- - The submitted/disputed/settled events observed for each OpenOracle report,
662- including blocks, reporters, raw locked amounts, and transaction links. See
663+ - In coordinator-free diagnostic mode, the submitted/disputed/settled events
664+ observed for each OpenOracle report, including blocks, reporters, raw locked
665+ amounts, and transaction links. Configured-coordinator mode shows current report
666+ state without reconstructing these historical paths. See
663667 [ data freshness and retention] ( #data-freshness-and-retention ) for lookback limits.
664668- A per-asset current-head price-history chart with one series per supported pool,
665669 axes, point tooltips, and a recent exact-value table. Samples persist across
@@ -1050,7 +1054,7 @@ scan. The same values live under `strategy` in the complete configuration:
10501054| TWAP window | ` 1800 seconds ` | ` twapSeconds ` | Controls the Uniswap manipulation-resistance window. Minimum: 60 seconds. |
10511055| Remaining time | ` 36 seconds ` | ` minimumRemainingSeconds ` | Inclusion buffer for timestamp-based games. |
10521056| Remaining blocks | ` 3 blocks ` | ` minimumRemainingBlocks ` | Inclusion buffer for block-based games. |
1053- | Head poll interval | ` 1000 ms ` | ` pollMilliseconds ` | Delay between latest-head checks. Every unseen event-log height is queried . |
1057+ | Head poll interval | ` 1000 ms ` | ` pollMilliseconds ` | Delay between latest-head checks. Coordinator-free diagnostic mode queries every unseen event-log height. |
10541058
10551059Increasing profit thresholds reduces execution frequency. Increasing the TWAP
10561060window or remaining-time buffers is generally more conservative, while decreasing
@@ -1271,10 +1275,10 @@ entry from depending on wallet inventory already committed to recovery.
12711275- Private delivery reduces public-mempool exposure but does not guarantee
12721276 confidentiality, inclusion, fair ordering, or relay/builder behavior. Configuring
12731277 multiple relays shares the signed payload with every listed operator.
1274- - A 12-block event overlap is replayed whenever a new head is processed to tolerate
1275- short reorganizations. The retained pre-overlap block hash is checked on every
1276- poll; a deeper reorganization stops execution and requires restart so the complete
1277- lookback is rebuilt . Operators still need independent alerting.
1278+ - Approved-coordinator reports are reread from a fixed block whenever a new head is
1279+ processed. A retained block hash is checked on every poll; a deeper reorganization
1280+ stops execution and requires restart. Coordinator-free diagnostic mode separately
1281+ replays a 12-block event overlap . Operators still need independent alerting.
12781282- Continuous mode retries transient poll failures with bounded exponential backoff.
12791283 The dashboard exposes per-endpoint health and the latest error, ` /healthz ` supports
12801284 container supervision, and Compose restarts an unexpectedly exited process.
0 commit comments