Problem
`lib/stream-utils.ts` (lines 9-23) computes unlocked amount as `elapsed * stream.amountPerSecond`, using a rate pre-derived by dividing amount by duration. The on-chain contract computes `(elapsed * linear_amount) / duration` in one operation (`contracts/streaming/src/lib.rs:1221-1222`). These are different formulas under integer arithmetic.
Location
`lib/stream-utils.ts:9-23`, `contracts/streaming/src/lib.rs:1214-1230` (line 1222)
Impact
The live "unlocked so far" UI counter can diverge from the actual on-chain withdrawable amount, with rounding error compounding over a long-running stream.
Suggested fix
Change the client-side formula to match the contract's exact order of operations (`(elapsed * total_amount) / duration`) so the UI always matches what the contract will compute.
Problem
`lib/stream-utils.ts` (lines 9-23) computes unlocked amount as `elapsed * stream.amountPerSecond`, using a rate pre-derived by dividing amount by duration. The on-chain contract computes `(elapsed * linear_amount) / duration` in one operation (`contracts/streaming/src/lib.rs:1221-1222`). These are different formulas under integer arithmetic.
Location
`lib/stream-utils.ts:9-23`, `contracts/streaming/src/lib.rs:1214-1230` (line 1222)
Impact
The live "unlocked so far" UI counter can diverge from the actual on-chain withdrawable amount, with rounding error compounding over a long-running stream.
Suggested fix
Change the client-side formula to match the contract's exact order of operations (`(elapsed * total_amount) / duration`) so the UI always matches what the contract will compute.