OTCVenue — is a singleton deployed on Robinhood Chain (Chain ID 4663, Arbitrum Orbit). A companion ClaimToken (one per series) is deployed lazily by the venue on first deferred fill.
Trade Types
Spot trades (unlockTime == 0) execute as atomic swaps at fill time. When a buyer calls fill on an active spot offer, the contract simultaneously transfers the agreed asset amount from escrow to the buyer and routes the quote token payment directly to the seller. No claim tokens are issued, and no unlock time check is required. The entire exchange settles in a single transaction.
Deferred (forward) trades (unlockTime > 0) use an escrow-and-claim model. The seller deposits collateral upfront; when a buyer fills the offer, the contract mints ERC-20 claim tokens to the buyer rather than immediately releasing the collateral. Quote token payment flows directly to the seller at fill time — the protocol never custodies quote tokens. After the unlockTime timestamp passes, any claim token holder can call the redeem function to burn their tokens and receive the underlying collateral on a strict 1:1 basis. This design lets buyers trade their future claim freely as a standard ERC-20 in the interim.
Series Model
Every deferred offer belongs to a series defined by the pair(asset, unlockTime). When the first deferred offer is filled for a unique pair, the OTCVenue automatically deploys a new ERC-20 ClaimToken contract for that series. All subsequent fills for offers sharing the same (asset, unlockTime) mint claim tokens from that same contract, creating a single fungible instrument backed by pooled escrow.
Each series maintains a backing counter that tracks the total collateral currently backing outstanding claim tokens. Because series are isolated, a liquidity or accounting event in one series can never affect another.
The series identifier (seriesId) is derived deterministically:
The series key is
(asset, unlockTime) — not (asset, quoteToken, unlockTime). This means all deferred offers for the same asset with the same unlock time share a single claim token, regardless of which quote token is used for payment. This is what makes claim tokens fungible across different offers.Offer Lifecycle
Every offer has an expiry timestamp (the deadline after which no fills are accepted) and an optional unlock time (zero for spot, non-zero for deferred). Key constraints at creation:expirymust be in the future (expiry > block.timestamp)- For deferred offers,
unlockTimemust also be in the future andexpiry <= unlockTime
Key Design Invariants
The Canopy protocol is built around invariants that hold for every offer and series at all times:- Collateral-first creation. Offers can only be created with collateral already deposited in the same transaction. The escrow transfer and offer registration happen atomically — there is no promise-based path.
-
Series solvency. For every series,
claimToken.totalSupply() == series.backing, and the venue’s balance of the asset covers all backing and all active offer escrow. This is enforced by delta-measured deposits, which correctly handle fee-on-transfer tokens. -
No double spend of escrow.
assetRemainingis decremented before any transfer or mint (checks-effects-interactions). Cancel zeroes it before returning collateral. - Quote tokens are never custodied. When a buyer fills an offer, quote tokens are transferred directly to the seller and fee recipient in the same transaction. The venue holds no quote token balance at any point.
-
Redemption is permissionless and unpausable. Once
block.timestamp >= unlockTime, any address holding claim tokens can redeem them. No whitelist, no operator approval, and no seller action is required. The admin has no power over redemption or escrow. -
Decimal-correct pricing. Quote cost uses cumulative full-precision
mulDiv, so split fills settle to the same aggregate price as a single fill.
OTCVenue inherits ReentrancyGuard and Ownable2Step. ClaimToken restricts mint and burn to the venue (onlyVenue) but is otherwise a standard ERC-20. Integrators can use any EVM library (ethers.js, viem, web3.py).
Next Steps
Data Structures
Explore the Offer and Series structs, field semantics, and on-chain storage layout.
Events Reference
Browse every emitted event with parameter docs for indexers and frontends.
Creating Offers
Step-by-step guide to creating spot and deferred offers.
Security Model
Understand the trust assumptions, access controls, and invariant proofs.