Materialized snapshot event (optional)
Emit SnapshotMaterialized(time, blockNumber) inside _setCurrentSnapshot() when the current snapshot time advances (and from a simple poke() if you add one). This gives indexers/ops a clean trigger to export cap tables, open claim windows, or anchor Merkle roots, no polling needed.
Guard against _valueAt misuse
valueAt(t, …) returns the first snapshot id ≥ t. Passing a non-scheduled timestamp can mislead.
Example: scheduled at 100 and 200; changes at 110 (+200) and 180 (–300). Asking for 130 could return the value from id 200 (e.g., 700) even though the true balance at t=130 was 1000.
Fix: expose helpers like snapshotExists(T) and snapshotBalanceExact(T, addr) that require T to be a scheduled record date, and document clearly that integrators should only query scheduled times.
Materialized snapshot event (optional)
Emit SnapshotMaterialized(time, blockNumber) inside _setCurrentSnapshot() when the current snapshot time advances (and from a simple poke() if you add one). This gives indexers/ops a clean trigger to export cap tables, open claim windows, or anchor Merkle roots, no polling needed.
Guard against _valueAt misuse
valueAt(t, …) returns the first snapshot id ≥ t. Passing a non-scheduled timestamp can mislead.
Example: scheduled at 100 and 200; changes at 110 (+200) and 180 (–300). Asking for 130 could return the value from id 200 (e.g., 700) even though the true balance at t=130 was 1000.
Fix: expose helpers like snapshotExists(T) and snapshotBalanceExact(T, addr) that require T to be a scheduled record date, and document clearly that integrators should only query scheduled times.