Skip to content

Add strict payouts toggle via Sablier Lockup Tranched - #29

Merged
fielding merged 4 commits into
mainfrom
mate/evm-tranched-reloads
Sep 2, 2026
Merged

Add strict payouts toggle via Sablier Lockup Tranched#29
fielding merged 4 commits into
mainfrom
mate/evm-tranched-reloads

Conversation

@fielding

@fielding fielding commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Adds a payout-style toggle — Steady drip / Strict payouts — that applies to any preset or custom schedule. Strict writes createWithDurationsLT: the schedule's own cliff/window/cadence becomes an enforced tranche list, so the checkpoints the drip calculator displays are the actual on-chain unlock times. Nothing is claimable between payouts. First payout lands at cliff + one interval.

Details:

  • schedule.ts: computeTranches (even split, dust folds into last tranche, 500-count cap), sablierNetDeposit (replicates Sablier's UD60x18 floor broker-fee math — tranche sums must match exactly or the create reverts), strictDropCount (same floor math as the calculator display)
  • contracts.ts: presets carry intervalSeconds (also fixes the calculator assuming hourly cadence on daily presets)
  • abis.ts: createWithDurationsLT (selector verified in deployed Base mainnet bytecode)
  • create page: toggle under the schedule tabs; hidden for Lock-until (already one strict drop); Panic Lock falls back to drip with a note; over-cap combos (hourly × 30d = 720) blocked with an explanatory error; both lock call sites consolidated into one fireLock
  • EVM-only: deployed SolSab exposes no tranched instruction (verified in IDL + upstream repo)

Verification:

  • 125 unit tests, lint, prod build green; UI verified in-browser (toggle, strict preview, over-cap error)
  • eth_simulateV1 against the real Base Sepolia Sablier: faucet→approve→create succeeds with exact sums (fee-less and 0.5%-broker paths, dusty amounts), reverts when the sum is off by one unit
  • Tranche cap probed empirically: 500 creates (gas ~13.6M), 501 reverts

🤖 Generated with Claude Code

The hourly/daily presets stream linearly — claimable grows every second
and the interval is display-only. Real casino-style reloads need discrete
drops: nothing claimable between them, then the day's chunk lands at once.
The deployed v2.0 Lockup contract already exposes createWithDurationsLT
(selector verified in Base mainnet bytecode); the app just never called it.

- schedule.ts: computeTranches (even split, dust folds into the last
  tranche), sablierNetDeposit (replicates the contract's UD60x18 floor
  broker-fee math — tranche amounts must sum to it exactly or the create
  reverts), secondsUntilTimeOfDay (first drop anchors to the user's local
  time-of-day, rolling a day when closer than 15 minutes)
- abis.ts: createWithDurationsLT entry
- create page: fourth schedule tab (Daily reload) with drop-count and
  time-of-day inputs; both lock call sites consolidated into one fireLock
  so LL/LT branching can't drift; preview/calculator/confirm/success
  surfaces speak in drops with zero-between-drops copy per the honest-
  wording rule from the 2026-07-28 packet

Verified beyond unit tests via eth_simulateV1 against the deployed Base
Sepolia contract: faucet -> approve -> createWithDurationsLT succeeds with
exact sums (fee-less and 0.5%-broker paths, 12 dusty amount/day combos),
and reverts when the sum is off by one unit.

Solana is excluded deliberately: the deployed SolSab program exposes only
Lockup Linear instructions and upstream has no tranched work.
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ripguard Ready Ready Preview Sep 2, 2026 1:53am UTC
ripguard-sol Ready Ready Preview Sep 2, 2026 1:53am UTC
ripguard-testnet Ready Ready Preview Sep 2, 2026 1:53am UTC

Per review: instead of a separate daily-reload tab with its own inputs,
strict is now a payout-style toggle (Steady drip / Strict payouts) that
applies to whatever preset or custom schedule is picked. The tranche list
derives from the schedule's own cliff/window/cadence — the checkpoints the
drip calculator was already displaying become the enforced unlock times,
first payout at cliff + one interval.

Presets now carry intervalSeconds, which also fixes the calculator
previously assuming hourly cadence for the daily presets. Lock-until hides
the toggle (already a single strict drop); Panic Lock falls back to drip
with a note (no cadence to enforce). Sablier's tranche cap — verified
empirically at exactly 500 (501 reverts) — is enforced at the form level
with a clear error for over-cap combos like hourly x 30d.
The secondary-text ramp bottomed out at 0.60L on a 0.14L background —
below comfortable contrast for the 11-12px helper lines and footnotes it
colors, and captain-reported as hard to read on the payout-style helper.
Lift the whole ramp (muted 0.70→0.76, subtle 0.66→0.72, faint 0.60→0.68)
so hierarchy is preserved while the floor clears small-text legibility.

Also bump the two smallest type sizes app-wide: 11px→12px (text-xs) and
10px→11px. Nothing user-facing renders below 11px now.
Strict streams have exact unlock times, so the vault card can finally
answer 'when can I claim?' precisely: read getTranches once per stream
(immutable — cached forever; linear streams revert and map to null), show
'Next payout in Xm Ys' ticking against the next tranche, and 'All payouts
unlocked' when the schedule is done. Countdown gains a seconds tier so an
hourly cadence visibly moves. Fallback schedule label for tranched streams
without a stored preset label is 'Strict Payouts'.
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.

1 participant