Setoff

Overview

How it works

A bill's life in Setoff: from an invoice link to a settled cycle and a withdrawal.

IOU lifecycle: a submitted IOU is pending; cycles can pay it in parts until it is settled; either party can dispute it, which freezes it until both offer the same amount; it can also be cancelled, or expire at its deadline.Draftinvoice link, off-chainPendingin the public poolDisputedfrozen until both agreeSettledpaid in fullCancelledby debtor or creditorExpireddeadline passedsubmit()signed or by debtorpartial paymentsettle() pays the restcancel()time passesdispute()matching offers
Every IOU is in exactly one state. Only pending IOUs can enter a cycle.

1. Add a bill

Send an invoice (gasless for the debtor)

The creditor fills in who owes, how much, the currency and what it's for. Setoff builds the IOU and sends it to the debtor's Setoff app: a Memo transaction (a fraction of a cent) that only the named creditor can send. The debtor sees it under Waiting for you on the Bills page, with a badge on Bills and an optional browser notification, and approves it with an EIP-712 signature, which is free and needs no USDC. Nothing is owed until then. There's also a link to share any other way.

If both sides have private notes on, the note is encrypted before it's sent. Declining just hides the invoice for you; nothing changes onchain.

Record what you owe

A debtor can also post an IOU directly. Because the debtor is the sender, no signature is needed.

Both paths go through Arc's Memo contract, so the invoice note is stored onchain alongside the IOU and the dashboard can show it later.

2. Fund your net

Before a cycle, each party's position is simply owed to you − you owe per currency. Only net debtors need to deposit, and only the shortfall. The Wallet page computes it and offers a one-click deposit. Approve and deposit are batched into one transaction through Arc's Multicall3From, which keeps your wallet as the sender.

3. A cycle settles

A solver reads the pool and the deposits, chooses the set of pending IOUs that deposits can fully fund, and calls settle. The contract then:

4. Withdraw

Credits sit in your Setoff balance. Withdraw whenever you like, or leave them in to fund your next cycle. Tokens leave the contract only on withdraw; settlement itself never transfers tokens.

Paying in parts

If you can't cover a whole bill, a cycle can pay part of it, as much as your deposit allows, and the rest stays open for the next cycle. Your bills show the progress (for example "Part paid · 1.50 of 4.00"). A bill is only marked settled once it's paid in full, and no cycle can ever pay more than is owed.

Disputes

If something's wrong with a bill, either side can dispute it. That freezes it: no cycle can pay it. Then each side proposes how much is still owed. As soon as both proposals match, the bill reopens at that amount, or is cancelled if you agree on 0. Anything already paid stays paid.

Credit lines

A business can let a partner it trusts overdraw up to a limit. If that partner is short when a cycle runs, the gap is paid from the lender's own deposit and recorded as owed back to the lender. The partner repays from their Setoff balance whenever they like. The lender can lower the limit, or set it to 0 to stop new draws, at any time.

USDC ↔ EURC netting (opt-in)

Bills are netted per currency, so being owed 10 EURC doesn't help pay 10.70 USDC you owe. If you opt in, a cycle can swap that leftover with another opted-in party whose leftover is the opposite, so neither of you deposits it. You opt in per direction (for example "give up EURC for USDC") with a minimum rate, set on the Wallet page, a little below market.

Private notes

Invoice notes can be encrypted so only the debtor and creditor can read them. Each wallet turns this on once from Profile in the account menu (top right), or right in the invoice form: a free signature creates its key, and a tiny transaction publishes the public half through Memo. When both parties have it on, "Keep this note private" is ticked by default.

Currencies

USDC and EURC net independently. Owing 5 USDC and being owed 5 EURC is still a 5 USDC debt. Converting across currencies through StableFX is on the roadmap.