尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
SharedArc: a shared USDC stream for collectives on Arc. One rate, N shares, live runway.
翻譯準備中
正在載入完整 README。 以下為已儲存的摘錄。
A shared USDC stream for collectives on Arc: one rate, N shares, live runway.
SharedArc is an MIT-licensed building block, not a SaaS. A pre-funded pool pays USDC per second, split among
members by mutable integer shares. Joining, leaving or re-weighting mid-stream is one O(1) write that touches
nobody else's storage. When the pool runs dry the stream freezes by itself and resumes on the next deposit, so
it can never owe more than it holds — and the owner can never touch what members have already earned.檢視完整 README ↗A shared USDC stream for collectives on Arc: one rate, N shares, live runway.
SharedArc is an MIT-licensed building block, not a SaaS. A pre-funded pool pays USDC per second, split among members by mutable integer shares. Joining, leaving or re-weighting mid-stream is one O(1) write that touches nobody else's storage. When the pool runs dry the stream freezes by itself and resumes on the next deposit, so it can never owe more than it holds — and the owner can never touch what members have already earned.
It has three parts: one immutable singleton contract (DripPool), a TypeScript SDK that mirrors the accrual
math so a UI ticks per second without RPC calls, and a static reference app, "Collective Payroll".
Status: live on Arc mainnet since 2026-09-18.
DripPoolis deployed at0x92b8fdB2c457b64d4510aC980A84283356D8A44fand verified on Sourcify (exact match). All ten proof rows are recorded below. Unaudited and experimental: keep amounts small.
Name: the project was called ArcDrip until 2026-09-18 and was renamed to avoid a clash with an unrelated product of the same name on Arc. That is why the CREATE2 salt is
keccak256("arcdrip.v1"); the contract, its address and every recorded transaction are unchanged.
| Contract | DripPool 0x92b8fdB2c457b64d4510aC980A84283356D8A44f — Sourcify exact match, deployments/arc-mainnet.json |
| Project page | https://r4topunk.github.io/sharedarc/ |
| App | https://r4topunk.github.io/sharedarc/app/ — apps/web static export against the mainnet DripPool (pool 1: /app/pool/?id=1) |
| Chain | Arc mainnet, chainId 5042, USDC 0x3600000000000000000000000000000000000000 (ERC-20 view, 6 decimals) |
An owner creates a pool with a ratePerSecond for the whole pool and gives each member an integer number
of shares. Anyone can deposit USDC into it. From then on every member's claimable balance grows every second,
in proportion to their shares, with no keeper and no per-period transaction. A member withdraws their own
balance, or anyone can push a payout to every member in one transaction ("Pay everyone").
The pool is the unit of accounting, so the treasury has one number to watch: balance / rate is the
runway, in days, for the whole collective at once.
| Guarantee | Mechanism |
|---|---|
| Earned is earned | owed (streamed and not yet withdrawn) is untouchable. withdrawUnstreamed and cancel are bounded by balance − ceilDiv(owed, 1e12). Invariant I4 asserts that no owner action — setRate, setShares on another member, withdrawUnstreamed, cancel, ownership transfer — ever decreases any member's claimable. |
| Never owes more than it holds | _accrue caps elapsed time at available / rate. That cap is the freeze: an empty pool stops streaming instead of promising. Invariant I2: owed ≤ balance × 1e12. |
| No back-pay after a freeze | Frozen time is never recovered. A deposit resumes streaming from the deposit's own timestamp. |
| Rounding always favours the pool | Every division floors. Members collectively receive at most what was streamed; the remainder is dust that stays in owed (bounded below 1 wad = 1e-18 USDC per accrual by MAX_TOTAL_SHARES). Invariant I1 bounds the dust, and a fuzz run (I5) checks every payout against an exact-rational reference model. |
| O(1) membership changes | Accumulated-index accounting: setShares settles one member and updates totalShares. No loop over members, so the cost of adding the 100th member is the cost of adding the first. |
| Payouts go to the member | withdrawFor and withdrawForBatch are permissionless, but funds always go to the member's payout address, never to the caller. A member with no gas still gets paid by someone else. |
| One blocked member cannot stall the rest | withdrawForBatch wraps each transfer in a try: on a revert or a false return it restores that member's pending and the pool's owed/balance and emits WithdrawSkipped. The batch never reverts because of one member. |
| Money never streams into the void | With totalShares == 0 nothing accrues and no funds are consumed. |
No token, no yield, no fees, no admin key over the contract, no upgradeability. Not a Sablier clone: there are no per-recipient streams, only pools with shares. Not a splitter: nothing is distributed on arrival, only over time. The owner's ability to pause, re-weight or cancel the future stream is deliberate — this is a payroll, not an escrow.
One pool stores ratePerSecond (wad/s), totalShares, balance (USDC units), owed (wad already streamed
and not yet withdrawn) and accIndex (wad per share, ×1e18). A member stores shares, index and pending.
Internal amounts are wad = USDC units × 1e12, so 1 USDC/month is 385,802,469,135 wad/s rather than 0.
以上為 README 的開頭部分。其餘內容請閱讀原文。 檢視完整 README ↗
Removal is setShares(member, 0): the accrued balance stays withdrawable forever, including after the pool is cancelled. |
| No admin over the contract | DripPool has no owner, no pause, no fee and no upgrade path. Each pool has its own owner (two-step transfer) and that owner's power is bounded by the rows above. |