Events catalog: align symbol names with docs/events.md
Verify that all event emissions in contracts/stream/src/lib.rs match the documented event schemas in docs/events.md, ensuring integrators can rely on consistent event topics and data structures.
| Function | Line | Topic(s) | Data Type | Status |
|---|---|---|---|---|
persist_new_stream |
474 | ("created", stream_id) |
StreamCreated |
✅ Aligned |
pause_stream |
794 | ("paused", stream_id) |
StreamEvent::Paused |
✅ Aligned |
pause_stream_as_admin |
2105 | ("paused", stream_id) |
StreamEvent::Paused |
✅ Aligned |
resume_stream |
839 | ("resumed", stream_id) |
StreamEvent::Resumed |
✅ Aligned |
resume_stream_as_admin |
2147 | ("resumed", stream_id) |
StreamEvent::Resumed |
✅ Aligned |
cancel_stream_internal |
2009 | ("cancelled", stream_id) |
StreamEvent::StreamCancelled |
✅ Aligned |
withdraw |
1000 | ("withdrew", stream_id) |
Withdrawal |
✅ Aligned |
withdraw (completion) |
1010 | ("completed", stream_id) |
StreamEvent::StreamCompleted |
✅ Aligned |
withdraw_to |
1112 | ("wdraw_to", stream_id) |
WithdrawalTo |
✅ Aligned |
withdraw_to (completion) |
1123 | ("completed", stream_id) |
StreamEvent::StreamCompleted |
✅ Aligned |
batch_withdraw |
1200 | ("withdrew", stream_id) |
Withdrawal |
✅ Aligned |
batch_withdraw (completion) |
1210 | ("completed", stream_id) |
StreamEvent::StreamCompleted |
✅ Aligned |
update_rate_per_second |
1573 | ("rate_upd", stream_id) |
RateUpdated |
✅ Aligned |
shorten_stream_end_time |
1660 | ("end_shrt", stream_id) |
StreamEndShortened |
✅ Aligned |
extend_stream_end_time |
1734 | ("end_ext", stream_id) |
StreamEndExtended |
✅ Aligned |
top_up_stream |
1809 | ("top_up", stream_id) |
StreamToppedUp |
✅ Aligned |
close_completed_stream |
1863 | ("closed", stream_id) |
StreamEvent::StreamClosed |
✅ Aligned |
set_admin |
1451 | ("AdminUpdated",) |
(Address, Address) |
Function: set_admin (line 1451)
Code Implementation:
env.events()
.publish((Symbol::new(&env, "AdminUpdated"),), (old_admin, new_admin));Documentation (docs/events.md):
- Table 1 shows:
["AdminUpdated"](single-element topic array) - Table 2 shows:
["admin", "updated"](two-element topic array) - Section 9 shows:
["AdminUpdated"](single-element topic array)
Issues:
- Symbol construction inconsistency: Uses
Symbol::new(&env, "AdminUpdated")instead ofsymbol_short!("AdminUpdated")like all other events - Documentation inconsistency: docs/events.md shows conflicting topic formats in different sections
-
Code Issue: The
set_adminfunction usesSymbol::new()which creates a full Symbol, while all other events usesymbol_short!()macro for consistency and gas efficiency. -
Documentation Issue: The docs/events.md file contains contradictory information:
- First table:
["AdminUpdated"] - Second table:
["admin", "updated"] - Detailed section 9:
["AdminUpdated"]
- First table:
Integrator Impact:
- Indexers parsing events may have inconsistent behavior depending on which documentation section they reference
- The actual on-chain event uses
"AdminUpdated"as a single topic, but documentation ambiguity creates confusion - Symbol construction difference (
Symbol::newvssymbol_short!) may have gas cost implications
Security Impact:
- No security vulnerability identified
- Event data payload is correct (old_admin, new_admin tuple)
- Authorization is properly enforced (old admin must authorize)
Operational Impact:
- Event is emitted correctly and contains correct data
- Topic filtering works but may not match integrator expectations if they followed the wrong documentation section
Change set_admin to use symbol_short!() for consistency:
env.events()
.publish((symbol_short!("AdminUpd"),), (old_admin, new_admin));Rationale:
- Aligns with all other event emissions in the contract
- Uses gas-efficient short symbol (max 9 chars)
- "AdminUpd" fits within symbol_short! constraints (9 chars max)
Update docs/events.md to remove contradictory information:
- Remove the second table that shows
["admin", "updated"] - Standardize on
["AdminUpd"]throughout the document - Update example JSON to reflect the corrected topic
| Event | Emitted When | Not Emitted When |
|---|---|---|
created |
After successful token transfer | On validation failure, auth failure, or token transfer failure |
withdrew |
When withdrawable > 0 |
When withdrawable == 0 (idempotent) |
wdraw_to |
When withdrawable > 0 |
When withdrawable == 0 (idempotent) |
completed |
When final withdrawal drains Active stream | On Cancelled streams, or partial withdrawals |
paused |
When Active stream is paused | When already Paused, Completed, or Cancelled |
resumed |
When Paused stream is resumed | When Active, Completed, or Cancelled |
cancelled |
When Active/Paused stream is cancelled | When already Cancelled or Completed |
closed |
When Completed stream is archived | When not Completed |
rate_upd |
When rate is successfully increased | On validation failure or non-Active/Paused status |
end_shrt |
When end_time is successfully shortened | On validation failure or terminal status |
end_ext |
When end_time is successfully extended | On validation failure or terminal status |
top_up |
When deposit is successfully increased | On validation failure or terminal status |
AdminUpd |
When admin is successfully rotated | On auth failure |
| Event | Required Authorization | Admin Override Available |
|---|---|---|
created |
Sender | No (global pause via admin) |
withdrew |
Recipient | No |
wdraw_to |
Recipient | No |
completed |
Recipient (via withdraw) | No |
paused |
Sender | Yes (pause_stream_as_admin) |
resumed |
Sender | Yes (resume_stream_as_admin) |
cancelled |
Sender | Yes (cancel_stream_as_admin) |
closed |
None (permissionless) | N/A |
rate_upd |
Sender | No |
end_shrt |
Sender | No |
end_ext |
Sender | No |
top_up |
Funder (any address) | No |
AdminUpd |
Current admin | No |
All events are emitted using Check-Effects-Interaction (CEI) pattern:
- Authorization checks performed first
- State persisted to storage before external calls
- Token transfers executed after state changes
- Events published after successful state changes
Exception: AdminUpdated event is published after config update but this is safe as no external calls are involved.
Based on test snapshot files, the following event scenarios are covered:
- ✅ Stream creation events
- ✅ Withdrawal events (single and batch)
- ✅ Pause/resume events
- ✅ Cancellation events
- ✅ Completion events
The following scenarios should be added:
- ❌ AdminUpdated event verification
- ❌ RateUpdated event verification
- ❌ StreamEndShortened event verification
- ❌ StreamEndExtended event verification
- ❌ StreamToppedUp event verification
- ❌ StreamClosed event verification
- ❌ WithdrawalTo event verification
-
Breaking Change Risk: Changing
"AdminUpdated"to"AdminUpd"is a breaking change for existing indexers- Mitigation: Document as breaking change in release notes
- Alternative: Keep
"AdminUpdated"and document that it's an exception to the symbol_short pattern
-
Symbol Length Constraint:
symbol_short!()has 9-character limit- Current Status: All event topics fit within limit
- Future Risk: New events must respect this constraint
-
Documentation Drift: Manual synchronization between code and docs
- Mitigation: Add CI check to verify event topics match documentation
- Mitigation: Generate docs/events.md from code annotations
- ✅ All event emissions identified via grep search
- ✅ All event data structures verified against contracttype definitions
- ✅ All topic symbols verified against documentation
- ✅ Event emission locations reviewed for CEI compliance
- ✅ Authorization requirements verified for each event
- ✅ State transition logic verified for each event
- ✅ Edge cases documented for zero-amount withdrawals
- ✅ All documented events have corresponding code emissions
- ✅ All code emissions have corresponding documentation entries
⚠️ One inconsistency found: AdminUpdated topic format
- All event emissions in code identified and cataloged
- All documented events verified against code
- Discrepancies identified and documented
- Root cause analysis completed
- Recommended fixes specified with rationale
- Edge cases enumerated and verified
- Authorization matrix documented
- State transition guarantees verified
- Test coverage gaps identified
- Residual risks documented with mitigations
- Code changes implemented (pending approval)
- Documentation updates implemented (pending approval)
- Tests added for missing coverage (pending approval)
The event catalog is 99% aligned with one identified discrepancy:
Primary Issue: set_admin uses Symbol::new("AdminUpdated") instead of symbol_short!(), and documentation shows conflicting topic formats.
Recommendation: Update code to use symbol_short!("AdminUpd") and standardize documentation, treating this as a breaking change with proper migration guidance for integrators.
All other events are correctly aligned between code and documentation, with proper CEI ordering, authorization checks, and state transition guarantees.