Setoff

Design

Architecture

One contract holds the truth. Everything off-chain is untrusted and replaceable: it can be slow or wrong, but it can't take anyone's money.

Setoff architecture: participants post IOUs through Arc's Memo contract and deposit through Multicall3From into the Setoff contract; an off-chain solver reads the pool and settles cycles through Memo; the dashboard reads events.PARTICIPANTSARC · ONCHAINOFF-CHAIN · UNTRUSTEDCreditorsends the invoiceDebtorapproves, funds its net1invoice linkfree signatureMemokeeps sender · adds noteMulticall3Frombatches, keeps sender2submit + note3approve + depositSetoff contractno owner · no admin keyIOU poolopen · part-paid · disputedLedger + credit linesbalances · limits · drawssettle() verifiernets sum to 0 · debits ≤ depositsERC-8004 registrynames for addressesUSDC · EURCmove only on deposit/withdrawSolverany wallet · cron jobDashboardevents + ERC-8004 names4read pool5memo(settle(ids, parties), cycle summary)6events
Numbers follow a bill: (1) invoice link, (2) post through Memo, (3) fund through Multicall3From, (4) the solver reads the pool, (5) it settles through Memo, (6) the dashboard reads events.

Components

ComponentWhereResponsibilityTrust
Setoff contractArcIOU pool (incl. partial payments and disputes), deposit ledger, credit lines, opt-in FX swaps, cycle verification and settlementThe only source of truth. No owner, no admin, no upgrade path.
MemoArc (system)Wraps calls so the sender is preserved and attaches an indexed noteArc protocol contract
Multicall3FromArc (system)Batches approve + deposit with the wallet as senderArc protocol contract
ERC-8004 registryArcNames for addresses; the dashboard verifies current ownershipDisplay only
SolverOff-chain cronChooses which IOUs go into a cycle, how much of each to pay, and which credit to drawUntrusted. Anyone can run one.
MCP serverAgent's machineGives AI agents Setoff tools with a spending capUntrusted. Uses the agent's own wallet.
DashboardStatic siteReads logs and contract state; prepares transactions for your walletUntrusted. Your wallet signs everything.

One cycle, step by step

A cycle: the solver reads the pool, picks a fundable set, and sends settle through Memo; Setoff checks and settles every IOU, then debits net debtors and credits net creditors atomically.SolverMemoSetoff1Read the poolIOU logs + deposits2Pick a fundable setgreedy, ~93% of optimal3memo(…)cycle summary attached4Apply each IOUpending? unexpired? net ±5Fund the netsdebit ≤ deposit · creditsettle(ids, parties)All or nothing: if any net debtor is short, the whole cycle reverts and nothing changes.
The solver only proposes. Every number the contract acts on is recomputed onchain from stored IOUs.

Key design decisions

Where the dashboard's data comes from

What you seeRead from
IOUs and their statusIOUSubmitted, IOUSettled, IOUCancelled events
Cycles, cleared vs. movedCycleSettled(gross[], netFunded[])
Invoice notes, cycle summariesMemo events where the target is Setoff
NamesERC-8004 Registered events, checked with ownerOf
Your depositsbalanceOf(account, token)