Join beta

Math you can trust.
Readable code.

Middn is not a custodian, not an order book, not a chat app. It is a small settlement layer that enforces one rule: no payment instructions before liquidity is reserved on-chain.

non-custodial contract gated vault-backed

Three invariants
the contract refuses to break.

enforced at the contract level
01 · liquidity

Every live offer is vault-backed.

A seller cannot post an offer for an amount they don't actually hold. The contract verifies vault balance = offer max before listing.

require(available >= offer.max)
02 · reservation

Funds freeze the moment a buyer takes.

Reserving an offer atomically moves USDT from available to reserved. The seller loses authority to withdraw it.

reserve() -> reserved += amount
03 · payment gate

No IBAN before reserve.

Payment instructions live behind a contract-gated reveal. The front-end fetches them only against a valid, on-chain reservation.

payInfo() -> if state != Reserved revert

Vault lifecycle

4 states · 3 transitions
01

Funded

USDT deposited. Available for the seller to withdraw or list.

vault.available +
02

Reserved

Buyer commits. Funds are locked for this deal and cannot be withdrawn by the seller while the deal is open.

vault.reserved +
03

Awaiting payment

IBAN + reference revealed to the buyer. The buyer has 30 minutes to mark payment sent; otherwise refund can be triggered.

payInfo unlocked · 30m
04

Released

After payment is marked, seller release or dispute resolution is required before USDT moves.

vault.reserved -> buyer

Public contract surface

solidity 0.8.x · audit-ready draft
contracts/Vault.sol
// Seller deposits stablecoin into their personal vault.
function deposit(uint256 amount) external;

// Seller publishes a vault-backed offer. Reverts if balance < max.
function publishOffer(Offer calldata o) external returns (bytes32 id);

// Buyer reserves liquidity. Atomically freezes the funds.
function reserve(bytes32 offerId, uint256 amount)
    external returns (bytes32 reservationId);

// Off-chain fetch — gated by reservation state on-chain.
function paymentInfo(bytes32 reservationId)
    external view returns (PayInfo memory);

// Atomic release. Both parties sign-off; USDT moves to buyer.
function release(bytes32 reservationId, bytes sigs) external;
01 Deposit

Seller funds a personal smart vault.

02 Publish

Offer reverts if vault balance is below the offer max.

03 Reserve

Buyer locks deal liquidity and unlocks payment details.

04 Release or refund

Seller release, dispute, or timeout path resolves the deal.

What you can build on top.

composability
primitive

Marketplace fronts

Read vault state, list offers, route reservations. Middn's own marketplace is one of many possible fronts.

primitive

OTC desks

Quote against vault liquidity, settle large blocks through the same reservation flow with custom escrow windows.

primitive

Settlement plumbing

Stablecoin clearing networks plug into vaults for programmable liquidity with on-chain proof.