Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.remlo.xyz/llms.txt

Use this file to discover all available pages before exploring further.

StreamVesting lets employers pay employees continuously instead of in discrete pay periods. The contract calculates accrued balance from block.timestamp and lets employees claim any portion of the vested amount before payday.

How streams work

When an employer sets an employee on a streaming structure, they call createStream(recipient, totalAmount, startTime, endTime). The contract locks the total amount in the employer’s treasury sub-account and records the stream parameters. At any time t in [startTime, endTime], the accrued balance is:
accrued(t) = totalAmount * (t - startTime) / (endTime - startTime)
The employee can call claimAccrued(streamId) to receive accrued(t) - alreadyClaimed. The contract transfers the delta and updates alreadyClaimed. After endTime, the stream is fully vested and the employee can claim the remainder in one transaction.

Cancellation and refunds (audit fix H-2)

Employers can cancel a stream early via cancelStream(streamId). On cancel:
  1. The accrued portion goes to the employee.
  2. The unaccrued portion returns to the employer.
If the cancel time refund to the employer fails (e.g., the employer’s treasury account was deactivated), the unaccrued amount is enqueued in unclaimedEmployerRefunds[employer]. The employer can later call claimEmployerRefund() to recover those funds. Before this fix, a failed refund silently lost the unaccrued amount.

claimAccrued returns void

Audit fix H-3. The previous version returned the claimed amount, which encouraged callers to use the return value as state. The new version returns void and emits AccruedClaimed(streamId, amount, claimer). Off-chain consumers read the event log instead.

SafeTIP20 wrapper (audit fix H-1)

All token transfers go through the SafeTIP20 library wrappers (safeTransfer, safeTransferFrom, safeTransferWithMemo, safeTransferFromWithMemo). These handle non-compliant TIP-20 tokens that don’t return a boolean, preventing silent failure on a token that returns void where the spec expects bool success.

Why streaming

A monthly paycheck creates a 30 day liquidity gap. Employees borrow against future income at high APR through payday loans, BNPL, or credit cards. Streaming compresses the gap to seconds. The employee accesses their earned-but-not-paid balance whenever they need it, without an advance, a loan, or a credit check. For employers, streaming is the same total payroll spread over the same period. No additional cost. The cost shifts entirely to the employee in the form of certainty: they always know exactly what they’ve earned.

Live deployment

Tempo Moderato (chainId 42431):
0xEEd5bab5A4A09fd59610513C95E106D285c87A2F
View on explorer.