No audit
No third-party security audit has been performed. The property tests, the pool invariant and the randomized sequence suite are evidence of care, not a substitute for review.
The two terms change every frame. Their sum does not move by one stroop.
Fluxora is a payment streaming primitive for Soroban. A sender funds a stream with a start, an end, and optionally a cliff; value accrues against ledger time; the recipient withdraws whatever has accrued, whenever they want. Streams can be paused, topped up, transferred, and cancelled with exact settlement.
It is infrastructure, not an application. Payroll, vesting, grant disbursement and subscription billing are thin layers over the same contract.
Ordered — each state follows the last
The sender locks the full deposit. Start, end, and cliff are fixed. So are three capability flags — cancellable, pausable, transferable — which can never change afterwards, so a recipient can verify what the sender is able to do before accepting.
The cliff gates the payout; it does not delay accrual. At cliff_time the recipient becomes entitled to everything accrued since start_time, not merely what accrues after. Pass cliff_time == start_time for no cliff.
Value accrues against ledger time and is computed on read. Nothing runs in the background — Stellar has no scheduler. The recipient calls withdraw and the contract works out what they have earned at that instant.
At end_time the whole deposit is vested. Accrual stops there and is clamped; no amount of elapsed time produces one stroop more than was deposited.
Either the recipient draws the balance to zero and the stream is depleted, or the sender cancels and the unvested remainder is refunded exactly. A cancelled stream stays cancelled even once drained, so the two endings stay distinguishable.
The settlement guarantee
vested(t) + refundable(t) = deposited
Exactly, at every instant — no dust term. Vesting is recomputed from the cumulative schedule on every call rather than accumulated from per-interval deltas, so truncation error is re-derived from scratch each time instead of building up. Rounding is always down, in the recipient's disfavour, so the pool can never owe more than it holds. When a stream settles the residue is zero rather than small.
Live on testnet
The contract is deployed and callable now. There is no SDK yet, so this uses the Stellar CLI directly.
# Read a live stream from the deployed testnet contract.
# Requires stellar-cli 27.x — the CLI major must match the network protocol.
stellar contract invoke \
--id CBCGTSCJXBMPPPE4BPDIPYZXPE2J5TQEKD2KCS7VQF533NKKEYGUTHXW \
--source-account <your-key> \
--network testnet \
--send=no \
-- get_stream --stream_id 0
# Returns the full Stream struct: deposited, withdrawn, start_time, end_time,
# cliff_time, the three capability flags, paused_at, paused_total, status.
#
# Derive vested, withdrawable and refundable from that single response rather
# than making three calls — a public RPC URL is an endpoint, not a node, and
# separate calls can land on different ledgers.Contract CBCGTSCJXBMPPPE4BPDIPYZXPE2J5TQEKD2KCS7VQF533NKKEYGUTHXW on stellar.expert. Full function surface in theABI reference.
159 tests · 20,000 property cases nightly
| Claim | How it is verified | Figure |
|---|---|---|
| vested(t) + refundable(t) = deposited, exactly | Property test over random schedules, plus asserted after every operation in the suite | 20,000 cases |
| No operation reduces vested(t) for a fixed t | Every entry point measured with the clock frozen, in five stream states, across all 720 orderings of the six mutating operations | 4,320 measurements |
| Pooled balance always covers every stream's liability | Re-checked after every single operation in randomized sequences, seeded for replay | 400 seeds nightly |
| The deployed contract matches the audited source | Interface spec of the deployed contract compared byte-for-byte with the local build | sha256 match |
| Behaviour on a real network matches the test suite | Every entry point called against live testnet, with assertions on on-chain state | 35 / 35 passing |
| A full batch stays inside protocol limits | Measured against protocol 27 mainnet limits; the binding constraint is the event budget, not entry reads | 8,192 / 16,384 bytes |
Deployment provenance
The interface of the deployed contract was compared byte-for-byte with the local build. Pin the wasm hash and treat a change in it as requiring a fresh read of the ABI.
What a green test suite does not prove
No third-party security audit has been performed. The property tests, the pool invariant and the randomized sequence suite are evidence of care, not a substitute for review.
The SDK's test host silently auto-restores expired persistent entries instead of failing, so the suite proves that crossing the archive and restore boundary preserves accounting — but not the real sequence, where the read fails and the caller must resubmit with aRestoreFootprint operation. A canary entry was planted on testnet and archives around 19 August 2026. Until that round trip runs, treat TTL as half-proven.
The cap of 16 is bounded by the contract event budget, and roughly half of the per-stream cost is the token's own transfer event rather than Fluxora's. It was measured against the Stellar Asset Contract; a token with a heavier event payload shifts the ceiling down.
Measurements register contracts natively, so Wasm instantiation and execution costs are skipped and reported instruction counts are lower than production. Entry counts and event bytes — what the batch cap actually derives from — are accurate.
This is a summary. The full file is reproduced verbatim on theknown limitations page, and is maintained as KNOWN-LIMITATIONS.mdin the contracts repository.
Plainly