Skip to content

[Contracts] top_up_stream resets last_update_time, discarding recipient's already-vested tokens (sender can reclaim them via cancel) #786

Description

@grantfox-oss

Telegram (ask questions / claim the issue here first): https://t.me/+DOylgFv1jyJlNzM0

Why this matters

lib.rs:293 sets stream.last_update_time = env.ledger().timestamp() on top-up, but that field is the accrual anchor: calculate_claimable (lib.rs:343) computes elapsed = effective_now - last_update_time, so advancing it to now zeroes all accrued-but-unwithdrawn time. Concrete loss: 1000-token/1000s stream (rate 1); at t=900 recipient has vested 900 unwithdrawn; sender top_up(+100) -> last_update_time=900 -> get_claimable_amount=0; sender cancel_stream at t=901 pays recipient only 1 and refunds 1099 to sender. Recipient loses ~899 already-earned tokens.

Acceptance criteria

  • Remove the stream.last_update_time = now assignment in top_up_stream (lib.rs:293) so prior accrued time is preserved
  • After create(1000,1000s), advance 900s then top_up(+100): get_claimable_amount must stay ~900, not drop to 0
  • Add test: top_up then immediate cancel_stream - recipient receives the pre-top-up accrued amount
  • Cover the paused case: top_up on a paused stream must not push last_update_time past paused_at

Files to touch

  • contracts/stream_contract/src/lib.rs

Out of scope

  • Changing the protocol fee logic
  • Frontend/backend top-up wiring

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave programbugSomething isn't workingcontractsSmart contract related taskscriticalrustPull requests that update rust codesecuritySecurity related tasks

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions