Skip to content

test: cover withdraw() dust reconciliation at stream end (#328) - #383

Merged
Chuks-coderr merged 1 commit into
SoroStream:mainfrom
Frezechi9999:test/328-withdraw-all-dust-reconciliation
Jul 30, 2026
Merged

test: cover withdraw() dust reconciliation at stream end (#328)#383
Chuks-coderr merged 1 commit into
SoroStream:mainfrom
Frezechi9999:test/328-withdraw-all-dust-reconciliation

Conversation

@Frezechi9999

@Frezechi9999 Frezechi9999 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #328.

At stream end, withdraw()'s claimable amount is derived from flow_rate = deposit / duration_seconds (integer division), which can truncate and leave a few stroops of "dust" that don't divide evenly. This adds explicit test coverage for that final reconciliation.

What was verified

Reading withdraw() in contracts/stream/src/lib.rs (the stream_ended branch, ~line 1776 on main), the contract's actual design is:

  • The recipient's final claim is flow_rate * duration (the streamed amount).
  • The leftover dust = deposit - flow_rate * duration is refunded to the sender, in the same call, right after the recipient's transfer.
  • Together, recipient_amount + dust == deposit, and the contract's token balance for that stream drops to zero — no value is permanently stranded.

Note this is a deliberate difference from the issue's literal wording ("recipient receives 100% of the deposit"): the contract returns unclaimed dust to the sender (the depositor), not the recipient. The acceptance criteria that matter operationally — no dust left in the contract, and a stream/duration/rate combination that produces fractional dust — are what these tests pin down.

Tests added (contracts/stream/src/test.rs)

  • test_withdraw_at_end_time_reconciles_full_deposit_with_dust — creates a stream with deposit = 100_003, duration = 1000 (flow_rate = 100, dust = 3), withdraws at end_time + 1, and asserts:
    • recipient balance == streamed share (100_000)
    • sender balance increases by exactly the dust (3)
    • recipient share + dust == full deposit
    • contract's token balance for the stream is 0
    • the stream record is removed (fully settled)
  • test_withdraw_long_after_end_time_matches_withdraw_at_end_time — same setup, but withdraws at end_time + 1000 instead of end_time + 1, and asserts an identical outcome (elapsed time is capped at end_time, so claiming later doesn't change the settled amounts).

Notes / caveats

  • Per instructions for this batch of work, I did not run cargo test / try to get CI green. Separately (and unrelated to this PR's diff), main currently has pre-existing compile errors in contracts/stream/src/errors.rs (duplicate StreamError variant names from what looks like a bad merge) and lib.rs (batch_create_stream's struct literal lists milestones twice) — neither touched by this change, but worth a follow-up fix so the crate builds again.

…ream#328)

Covers the final withdrawal at/after end_time for a deposit/duration
combination where flow_rate = deposit / duration truncates and leaves
rounding dust. Verifies the recipient receives the streamed share, the
dust is refunded to the sender, the contract's balance for that stream
reaches zero, and that claiming long after end_time settles identically
to claiming right at end_time + 1.
@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@Frezechi9999 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

@Chuks-coderr
Chuks-coderr merged commit 90fc98f into SoroStream:main Jul 30, 2026
0 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add test for withdraw_all claiming exactly the full remaining balance at stream end

2 participants