otcvault settles otc deals nobody has to trust
OTC today runs on trust. Trust is the attack surface.
Most token deals outside exchanges still happen in a chat: someone sends first, someone hopes. The failure modes are well known.
Fake stablecoins. A token called "USDT" with the right logo and the wrong address. By the time you check the explorer, the real tokens are gone. Who sends first? Every OTC deal has a moment where one side is fully exposed. Escrow agents solve it by adding a third party you also have to trust.
Vesting on a handshake. Discounted tokens usually come with a lock-up — enforced by a promise. Buyers dump early; sellers stop delivering. Neither side has recourse. Risk in the middleman. Centralised OTC desks and escrow services hold your funds, can freeze them, and can disappear. Several have.
OTCVault removes the trusted party instead of adding one.

Four states. One contract. No one in the middle.
Every deal is a single entry in the escrow contract and moves through four states. The state you see on a deal page is read directly from the chain.
- 01OPEN
Maker creates and deposits
The maker names the counterparty, both legs, the delivery schedule and an expiry. Their side is pulled into escrow in the same transaction.
createDeal() - 02FUNDED
Taker deposits
The named taker sees exactly what is escrowed — real address, live symbol and decimals, whitelist and registry status — and deposits their side. A 24-hour cool-off starts.
fund() - 03CONFIRMED
Both verify and confirm
Each party checks the other's deposit and types the last 4 characters of the counterparty's token address. The first confirm is recorded; the second one settles.
confirm() - 04SETTLED
Atomic delivery
Stablecoins go to the seller minus 0.375%. The token goes to the buyer — immediately, or into a Sablier vesting stream that cannot be cancelled by anyone.
confirm() → _settle()
Exit. CANCELLED — maker cancels while open; mutual cancel while funded; unilateral withdrawal after the 24h cool-off; or anyone triggers a refund after expiry. Every deposit returns in full. No fee on cancelled deals.
Trust the contract you can read, not the people you can't.
- 01
Both legs are escrowed.
Nobody sends first. The contract holds both deposits and releases both — or neither.
- 02
No admin key can touch your funds.
No rescue, sweep, pause or upgrade function. The owner can only set the fee (capped at 1%) and the vesting rail for future deals.
- 03
Non-upgradeable, verified source.
Five plain contracts, no proxies, source verified on Arbiscan. What you read is what runs — forever.
- 04
One leg is always a real stablecoin.
Every deal must include USDC or USDT from the on-chain registry. A fake "USDT" cannot be the stable leg — by construction.
- 05
The token leg is whitelisted.
Reviewed for verified source, no transfer tax, no blacklist or pause functions, sane holder distribution.
- 06
Vesting is a Sablier stream, not a promise.
Delivered as a Sablier Lockup v4 stream created with cancelable = false. The seller cannot claw it back; the buyer cannot skip the schedule.
Fee, rail and schedule are snapshotted per deal: what you confirm is what settles.

0.75%, split evenly. Nothing else.
Charged only on the stablecoin leg and only when a deal settles. Cancelled and expired deals cost nothing beyond gas.
- Buyer pays
- stable amount + 0.375%
- Seller receives
- stable amount − 0.375%
- Protocol receives
- 0.75% of the stable amount
- Charged on the token leg
- Never
- Charged on cancel / refund
- Never
- Maximum fee, ever
- 1.00% — MAX_FEE_BPS_X2 = 200, immutable
Worked example — $100,000 deal
Alice sells 250,000 XYZ to Bob for 100,000 USDC, vesting linearly over 12 months.
Bob deposits 100,375 USDC (100,000 + 375 fee). Alice deposits 250,000 XYZ.
On settlement: Alice receives 99,625 USDC. Bob receives a Sablier stream of 250,000 XYZ over 12 months. The fee vault receives 750 USDC.
If either side walks away before both confirm: Bob gets back exactly 100,375 USDC, Alice exactly 250,000 XYZ.
Listing fee. Adding a new token to the whitelist costs 1,000 USDC, paid to the fee vault when you request a review. It pays for the review; it does not guarantee approval.
Where fees go. Fees accumulate in the FeeVault contract. Planned use: buy-back-and-burn of a future protocol token. Until then, the balance is publicly visible on-chain. View vault

Built for both sides of the table.
For sellers — you hold the token
- Get paid in real USDC or USDT — the registry, not a logo, decides what counts.
- Set the vesting terms yourself: liquid, cliff, or linear with cliff and daily/weekly unlocks.
- Your tokens never leave escrow until the buyer's stablecoins are in escrow too.
- Walk away any time before both confirmations — full refund after the 24h cool-off.
- You receive the stable leg the instant the deal settles.
For buyers — you hold the stablecoins
- See the exact token contract before you commit: address, live metadata, whitelist status, and red flags such as proxy or pausable bytecode.
- Vested tokens arrive as a Sablier NFT — the seller cannot cancel or alter the stream.
- Claim as tokens unlock at app.sablier.com, with no dependency on OTCVault.
- If the seller never confirms, withdraw your stablecoins after 24 hours.
- Pay 0.375% — the same as the seller.
Where we are, honestly.
Pre-audit · v1 · Use with amounts you can afford to lose
OTCVault is live on Arbitrum One with real funds and has not yet been audited by an external firm. We would rather say that plainly than imply otherwise.
- 97 Foundry tests. Unit, fuzz, invariant and Arbitrum fork tests against the real Sablier Lockup v4. Core invariant: escrow balance ≥ sum of deposits for OPEN and FUNDED deals; settled deals deliver exactly stable − fee and exactly the asset amount.
- Slither static analysis. 0 High. 1 Medium (strict-equality sentinel in the registry) triaged as false positive; 1 Low reentrancy note accepted — state is SETTLED before any external call and confirm is nonReentrant.
- Verified source. All five contracts verified on Arbiscan. No proxies.
- Minimal admin surface. Owner can set the fee (≤1%), the rail for future deals, manage whitelist and registry (48h timelock on additions), sweep earned fees. Cannot move escrowed deposits.
- Deposit measurement. Every deposit is measured balanceAfter − balanceBefore and reverts on shortfall, so fee-on-transfer tokens fail loudly.
- External audit. Scheduled before the per-deal cap is lifted. Until then, treat the protocol as beta.
- Multisig ownership. The owner is currently a single key. Transfer to a multisig is planned before audit.
- Bug bounty. To follow the audit.
Questions people actually ask.
Once a deal is FUNDED, a 24-hour cool-off starts. If both parties have not confirmed by then, either party can call Cancel and both deposits are refunded in full. Before the cool-off ends, a cancel request is recorded; if the other party also requests cancel, refunds happen immediately (mutual cancel).
What's next.
- Now
- Arbitrum One · named-counterparty deals · Sablier Lockup v4 rail · USDC/USDT · token whitelist
- Next
- External audit → per-deal cap lifted · ownership to multisig · Base deployment
- Then
- Ethereum mainnet · BNB Chain · open offers · Hedgey TokenLockupPlans as an alternative rail
- Later
- Protocol token + buy-back-and-burn from FeeVault · governance over fee, registry and whitelist · Hebrew interface
Five contracts. Verify them yourself.
Verify the contracts yourself
ready when both of you are.
Create a deal