How it works
Invia is one Anchor program with three account types and four instructions. Every offer creates a small set of program-owned accounts; every fill is one Solana transaction that either succeeds in full or reverts in full.
The accounts
Each offer materializes three accounts owned by the program. Nothing else moves until one of the four instructions is called.
The vaults are PDAs derived from the offer. Only the program can sign for them, and only inside one of the four instructions below.
The four instructions
Atomic settlement, in one paragraph
A fill is a single Solana transaction. Inside that transaction the program moves tokens from the asset vault to the taker, moves payment from the taker to the maker, skims the 0.20% fee to the treasury, and decrements the offer. There is no point inside that transaction at which one side has paid and the other has not. Either every step lands on chain together or none of them land. The maker cannot ghost mid-trade because there is no mid-trade.
Default risk is the entire reason OTC desks exist. By making settlement atomic at the protocol level, Invia removes the role of the desk. The trust model collapses to: do you trust the program bytecode? You can read it yourself.
Worked example: a sell-side fill
A maker lists 1,000,000 of token MEME at 0.0001 SOL per token, min fill
50,000, expiry 7d. The program now holds 1,000,000 MEME in the asset
vault.
A taker comes in to buy 200,000:
- Taker submits
take_offer(offer, fill_amount=200_000). - The program validates: offer not expired,
200_000 >= min_fill,200_000 <= remaining_size. - Taker pays
200_000 * 0.0001 = 20 SOLfrom their wallet. - The program splits the payment:
19.96 SOLto the maker's wallet,0.04 SOL(20 bps) to the treasury. - The program transfers 200,000
MEMEfrom the asset vault to the taker's ATA. remaining_sizedrops to 800,000.
Every step is in the same transaction. If any check fails or the taker's wallet rejects, the entire transaction reverts and no state changes.
What changes after the offer is closed
When remaining_size reaches zero, or the maker calls cancel_offer, or
anyone calls expire_offer after the deadline, the offer PDA and both
vaults close. The rent for those accounts is refunded to the maker (or, in
the expire case, the SOL bounty goes to the caller and the rest goes to the
maker). The offer is no longer visible on chain, it has been physically
removed.