Skip to content

fix(streaming): reject backdated start_time, add pagination overflow regression test - #697

Merged
Austinaminu2 merged 1 commit into
FlowwStar:mainfrom
davidsoniaudin2-oss:fix/streaming-backdated-start-pagination
Aug 27, 2026
Merged

fix(streaming): reject backdated start_time, add pagination overflow regression test#697
Austinaminu2 merged 1 commit into
FlowwStar:mainfrom
davidsoniaudin2-oss:fix/streaming-backdated-start-pagination

Conversation

@davidsoniaudin2-oss

@davidsoniaudin2-oss davidsoniaudin2-oss commented Aug 27, 2026

Copy link
Copy Markdown

Summary

Solves the four issues assigned to this account on the streaming contract and the affected frontend surfaces. Two required real changes (both in contracts/streaming), and two turned out to already be fixed on main — details below.

Fixes #221, #222


#221create_stream / create_streams_batch now reject backdated start_time ✅ fixed

Problem: Neither entrypoint validated start_time against the current ledger time, so a sender could backdate start_time/cliff_time and have a large chunk of the deposit unlocked (and withdrawable) the moment the stream was created, bypassing the vesting UX.

Change (contracts/streaming/src/lib.rs):

  • New typed error variant StreamError::PastStartTime = 21.
  • create_stream: rejects start_time < env.ledger().timestamp() (returning PastStartTime) before any funds move.
  • create_streams_batch: same check per-input in phase-1 validation, so a single backdated input rejects the entire batch atomically with no partial state and no funds moved.
  • Backdated cliff_time (cliff before start) was already rejected as InvalidCliff; it now has explicit test coverage.

Tests added (test.rs, test_batch.rs):

  • test_create_stream_rejects_past_start_time — asserts PastStartTime and that no funds moved.
  • test_create_stream_rejects_backdated_cliff — asserts InvalidCliff.
  • test_batch_rejects_past_start_time — asserts PastStartTime plus atomicity (no stream created, contract balance unchanged).

#222 — pagination no longer aborts on offset + limit overflow ✅ fixed (fix on main) + regression test added

Problem: get_sent_streams / get_received_streams / get_archived_* computed offset + limit as a raw u32; with overflow-checks = true in Cargo.toml a large combination aborted the read call.

Status: The clamping fix already landed on main — the shared paginate helper (introduced in #475) uses offset.checked_add(limit) and clamps both bounds to the vector length, returning an empty page for out-of-range offsets instead of aborting. What was missing is exactly what the issue asked for: a regression test.

Test added (test.rs):

  • test_pagination_clamps_large_offset_limit — creates 5 streams and asserts:
    • offset=2, limit=u32::MAX (overflows u32) → clamps to the tail (3 entries) instead of aborting;
    • offset=u32::MAX, limit=u32::MAX → empty page, no abort;
    • offset=0, limit=u32::MAX → full page still works.

#224use-batch-create unmount cleanup ✅ already fixed on main

hooks/use-batch-create.ts already contains the unmount cleanup:

useEffect(() => {
  return () => {
    abortRef.current = true
  }
}, [])

Landed in d535901 ("fix(hooks): add unmount cleanup to useBatchCreate", merged via PR #335). The in-flight batch loop aborts as soon as the component unmounts, so no wallet-signature prompts fire after navigating away. No code change needed — the issue can be closed.

#456 — landing page SSR/hydration mismatch ✅ already fixed on main

components/landing/live-stream-preview.tsx no longer computes a module-level NOW. The demo stream is seeded inside the useState initializer:

const [demoStream] = useState(() => buildDemoStream(Math.floor(Date.now() / 1000)))

so server and client render the same markup on first paint (the initializer-based approach the issue's suggested fix calls for). Landed in 59ba171 ("…fix SSR hydration mismatch…"). No code change needed — the issue can be closed.


Verification

⚠️ Note: I could not run cargo test locally — this environment has no Rust toolchain (and the user opted to skip installing one). The contract changes were reviewed manually against the existing code and test conventions:

  • The new checks reuse the existing env.ledger().timestamp() pattern already used by top_up/withdraw/cancel.
  • All existing tests create streams with start_time >= the current ledger timestamp (they call set_time(now) before create_stream with start_time: now), so the new check should not break any of them.
  • New tests follow the exact assert_eq!(result, Err(Ok(StreamError::…))) pattern used throughout the suite.

Please let CI (cargo test in contracts/streaming) confirm. The frontend issues required no changes, so no frontend verification was needed.
closes #456
closes #222
closes #224
closes #221

…regression test

- create_stream and create_streams_batch now return the new typed
  StreamError::PastStartTime when start_time is before the current
  ledger timestamp, so a sender can no longer backdate a stream and
  unlock a large chunk of the deposit immediately on creation (FlowwStar#221).
  The batch check runs in phase-1 validation, so a single backdated
  input rejects the whole batch atomically with no funds moved.
- Add tests: backdated start_time (single-stream, with no-funds-moved
  assertion), backdated cliff_time (InvalidCliff), and batch atomicity.
- Add a pagination regression test covering offset+limit combinations
  that overflow u32, asserting the call clamps/returns empty instead
  of aborting (FlowwStar#222). The clamping fix itself already landed on main
  via the paginate helper (FlowwStar#475); this closes the loop with the
  missing test the issue requested.

Fixes FlowwStar#221, FlowwStar#222

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Aug 27, 2026

Copy link
Copy Markdown

@davidsoniaudin2-oss Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Austinaminu2
Austinaminu2 merged commit 65c5f20 into FlowwStar:main Aug 27, 2026
0 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment