Join the discussion on Telegram
Why this matters
The Soroban event indexer crashes (per-event) on a legitimate on-chain state. In backend/src/workers/soroban-event-worker.ts, both handleStreamCreated and handleStreamToppedUp compute the stream end time with:
const durationSeconds = Number(BigInt(depositedAmount) / BigInt(ratePerSecond));
The contract explicitly allows rate_per_second == 0. When a sender funds a "dust" stream (amount smaller than the duration in seconds), create_stream rounds rate_per_second = net_amount / duration down to 0 — this is a tested, supported path (see test_create_stream_zero_rate in contracts/stream_contract/src/test.rs). When such a stream emits a stream_created event, BigInt(x) / 0n throws RangeError: Division by zero, the handler rejects, and the event is never indexed. Because the worker sorts stream_created first in a batch, a single zero-rate stream can also block dependent events in the same batch.
Acceptance criteria
Files to touch
backend/src/workers/soroban-event-worker.ts
backend/tests/soroban-event-worker.test.ts
Out of scope
- Changing whether the contract permits zero-rate streams (tracked separately).
Join the discussion on Telegram
Why this matters
The Soroban event indexer crashes (per-event) on a legitimate on-chain state. In
backend/src/workers/soroban-event-worker.ts, bothhandleStreamCreatedandhandleStreamToppedUpcompute the stream end time with:The contract explicitly allows
rate_per_second == 0. When a sender funds a "dust" stream (amount smaller than the duration in seconds),create_streamroundsrate_per_second = net_amount / durationdown to0— this is a tested, supported path (seetest_create_stream_zero_rateincontracts/stream_contract/src/test.rs). When such a stream emits astream_createdevent,BigInt(x) / 0nthrowsRangeError: Division by zero, the handler rejects, and the event is never indexed. Because the worker sortsstream_createdfirst in a batch, a single zero-rate stream can also block dependent events in the same batch.Acceptance criteria
ratePerSecond === 0ninhandleStreamCreatedandhandleStreamToppedUp; when the rate is zero, store the stream without computing a finiteendTime(e.g. leaveendTimenull or set it tostartTime).streamEventrows are lost for zero-rate streams.backend/tests/soroban-event-worker.test.tsthat feeds astream_createdevent withrate_per_second = 0and asserts the stream + event are persisted without throwing.Files to touch
backend/src/workers/soroban-event-worker.tsbackend/tests/soroban-event-worker.test.tsOut of scope