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.
Components
| Component | Where | Responsibility | Trust |
|---|---|---|---|
| Setoff contract | Arc | IOU pool (incl. partial payments and disputes), deposit ledger, credit lines, opt-in FX swaps, cycle verification and settlement | The only source of truth. No owner, no admin, no upgrade path. |
| Memo | Arc (system) | Wraps calls so the sender is preserved and attaches an indexed note | Arc protocol contract |
| Multicall3From | Arc (system) | Batches approve + deposit with the wallet as sender | Arc protocol contract |
| ERC-8004 registry | Arc | Names for addresses; the dashboard verifies current ownership | Display only |
| Solver | Off-chain cron | Chooses which IOUs go into a cycle, how much of each to pay, and which credit to draw | Untrusted. Anyone can run one. |
| MCP server | Agent's machine | Gives AI agents Setoff tools with a spending cap | Untrusted. Uses the agent's own wallet. |
| Dashboard | Static site | Reads logs and contract state; prepares transactions for your wallet | Untrusted. Your wallet signs everything. |
One cycle, step by step
Key design decisions
- Settlement moves no tokens.
settleonly updates the internal ledger; tokens move ondepositandwithdraw. On Arc, USDC is also the gas token and has a blocklist. If cycles pushed transfers, one blocklisted creditor could revert everyone's settlement. With pull-based withdrawals that can't happen. - The pool lives onchain. IOUs are stored in contract storage, not an off-chain order book. On Arc storing one costs a fraction of a cent, and in return there is no database to run and anyone can build a competing solver from public data.
- Sorted parties instead of a hashmap. The solver passes the parties in strictly ascending order. The contract finds each party by binary search and the strict ordering proves no one is listed twice. No storage-heavy maps during settlement.
- No backend. The dashboard rebuilds everything from contract events and Memo events: IOUs, cycles, invoice notes, names. It can be hosted as static files anywhere.
Where the dashboard's data comes from
| What you see | Read from |
|---|---|
| IOUs and their status | IOUSubmitted, IOUSettled, IOUCancelled events |
| Cycles, cleared vs. moved | CycleSettled(gross[], netFunded[]) |
| Invoice notes, cycle summaries | Memo events where the target is Setoff |
| Names | ERC-8004 Registered events, checked with ownerOf |
| Your deposits | balanceOf(account, token) |