▍ collective payroll, streamed

One stream.
Split by shares,
every second.

SharedArc pays a whole team from one pre-funded pool. One rate goes in; shares decide who gets what. Change anyone’s share and everyone re-prices from that second — nothing already earned moves.

STREAMING example pool · live model, try it
rate

Example numbers, not a live pool. The ticking uses the same accrual math as the contract.

01 / the problem

Paying a team onchain today means picking a compromise.

Streams know about time but not about teams. Splitters know about teams but not about time. Manual transfers know about neither. SharedArc is the merge: a split that happens over time.

MANUAL TRANSFERSSomeone signs every period.Miss one and payroll is late. Amounts live in a spreadsheet. Runway is a guess.
ONE STREAM PER PERSONN streams, N balances.Changing one weight means rebuilding every stream. The treasury’s runway is scattered across N deposits.
SPLITTERDivides what arrives, at once.Great for revenue, wrong for salaries: there’s no notion of time, so nothing is earned per second.
SHAREDARCA split that streams.One balance and one runway. Re-weighting is one write. Anyone can press pay, and money always lands at the member’s address.
02 / how it works

The rate is constant.
The slices move.

Read it left to right: the pool’s whole rate is the height of the band, and each color is one member’s slice. Every event below is a single transaction.

Stacked chart of each member’s slice of the stream over time, across four events. rate time → FROZEN nothing streams, nothing is owed 1 2 3 4 A · 3 shares · 42.9% B · 2 · 28.6% D joins · 1 share D · 16.7% C · 2 · 28.6% createPool · deposit · setSharesBatch Stacked chart of each member’s slice of the stream over time, across four events. FROZEN 1 2 3 4 A · 3B · 2D · 1 C · 2 time → rate ↑ constant
1 · setShares(D, 1)Someone joins mid-streamEveryone’s slice shrinks from this second. One write; nobody else’s storage is touched.
2 · balance hits zeroThe pool freezes by itselfNo keeper, no debt. It can never owe more than it holds.
3 · deposit(amount)Anyone tops it upStreaming resumes from the deposit’s timestamp. Frozen time isn’t back-paid.
4 · setShares(C, 0)Someone leavesC stops earning, but everything C already accrued stays withdrawable forever.
The pool’s index rises over time; a member’s pay is the gap between the index now and the index when they joined. accIndex · USDC earned per share since start time → frozen D joins → stores index_D Δ now slope = rate ÷ totalShares The pool’s index rises over time; a member’s pay is the gap between the index now and the index when they joined. accIndex · earned per share frozen D joins → stores index_D Δ now time →
claimableD = sharesD × Δ
03 / the math

Why one write is enough.

The pool keeps a single running number: how much one share has earned since the start. Each member only remembers where that number was when they joined. Their pay is the gap, times their shares.

O(1)Join, leave or re-weight settles one member and touches nobody else.
18 dpKept in wad internally, so 1 USDC a month never rounds to zero.
floor ↓Every rounding favours the pool, never a member.
Full spec and the Solidity →
04 / guarantees

What’s earned is theirs.

An owner can pause, re-weight or cancel the future. Nothing can touch the past. Each rule is a Foundry invariant, checked after every step of randomized runs.

I1 · no over-accountingWhat members can claim never exceeds what streamed.
I2 · solventA pool never owes more than its balance.
I3 · backedAll pools together are covered by the contract’s USDC.
I4 · owner-proofNo owner action ever lowers anyone’s claimable.
I5 · never over-paysChecked against an exact rational reference model.
skip ≠ revertIn “Pay everyone”, a blocked address is skipped and its balance restored. The rest still get paid.
0 admin keysOne immutable contract. No upgrade, no token, no fees. Pool owners can be an EOA, a Safe or a DAO.
05 / what’s built

Open source, tested, headed to mainnet.

An MIT-licensed building block: the contract, an SDK and the app that drives it. No token, no sale, no yield, no fees.

PARTWHAT IT DOESTESTS
DripPool.solImmutable singleton holding many pools: index accrual, freeze on empty, pull withdrawals, blocklist-safe batch payout, cancel, two-step ownership182 (4 fork skipped)
@sharedarc/sdkviem actions, Zod schemas, the accrual math mirrored offchain, member discovery from logs217
apps/web“Collective Payroll”: create, fund, weight, watch, pay everyone. Static export, EN and PT-BRsee repo
docs/Spec, threat model, measured gas table and the CCTP finding for Arc mainnet—
Mainnet deploy in progress

Every package builds and its tests pass locally, including the invariant suite. The address and each proof transaction fill in as the deployment lands. Every wallet in the proof run belongs to the author.

  • DripPool0x92b8…A44f
  • Deploy, verified on Sourcifydeploy tx · Sourcify
  • Proof pool, first depositin progress
  • withdrawFor paid by someone elsein progress
  • Join, freeze, resume, no back-payin progress
  • Pay everyone in one transactionin progress
  • Cancel, member withdraws anywayin progress
~0.002USDC to withdraw. On Arc, gas is paid in USDC.
< 1 sFinality, so the live ticker and the chain agree.
1 assetTreasury, salary and gas are all native USDC.
greenfieldAs of September 2026, no Sablier, Superfluid or 0xSplits on Arc.

Open the tap.
Shares do the rest.

$ git clone https://github.com/r4topunk/sharedarc
$ cd sharedarc && pnpm install
$ pnpm check            # build + tests + lint
$ pnpm --filter @sharedarc/web dev