Skip to content
M Moby Market

A $100M SOL unwind, end-to-end: how the moby-market primitives compose

· Moby Market Team · use case · execution · engineering

Walk through a realistic large-position unwind on Solana from intake to settlement — RFQ check, TWAP scheduling, privacy mode, route splitting, and post-trade reporting — using the actual primitives in the moby-market workspace.

The most useful way to understand a protocol is to follow a real workload through it. This post walks through a $100 million SOL unwind from intake to settlement using the primitives exposed by the moby-market Rust workspace. The numbers are illustrative — they come from devnet runs against modelled liquidity, not live mainnet — but the structure of the workflow is exactly how a desk would execute the trade today.

The scenario is a fund that needs to convert a 1.4 million SOL position to USDC over a 48-hour window for a redemption deadline. The position was accumulated over six months and the desk does not want the unwind to become public knowledge or to move the SOL/USDC reference price by more than ten basis points. The unwind has to complete in time, fully filled, with auditable post-trade reporting for the fund’s prime broker.

That set of constraints is impossible on a single AMM, expensive on a naive aggregator, and uncomfortable on most existing OTC desks. It is a normal day on Moby Market.

Step one: intake and intent shape

The desk’s execution engineer opens a session against the protocol and constructs the intent in two passes. First, they check whether the OTC marketplace can take any of the size as a bilateral fill. RFQ requests go out to the participating market makers carrying a privacy flag — the request reveals the pair and a size band but not the precise amount or the requester identity.

In our scenario two MMs respond. One quotes for 200,000 SOL at a spread of seven basis points to the prevailing reference price; another quotes 150,000 SOL at twelve basis points. The desk accepts the tighter quote, locking 200,000 SOL into an OTCEscrow that will settle in the next slot. That immediately removes 14% of the parent order from the public execution path.

The remaining 1.2 million SOL becomes a TWAPOrder:

let parent = TWAPOrder {
    trader: desk_pubkey,
    token_in: SOL_MINT,
    token_out: USDC_MINT,
    total_amount: 1_200_000 * LAMPORTS_PER_SOL,
    time_window: 48 * 3600,
    num_splits: 288,
    randomness_factor: 42,
    price_deviation_limit: 25, // basis points
    min_output_per_interval: _,
};

288 splits over 48 hours puts a child order every ten minutes on average. The randomness factor of 42 means each child can drift up to roughly forty percent of the interval from its nominal slot, defeating pattern detection. The price deviation limit of 25 basis points means any child that would execute at a price more than 25 bps from the trailing-hour TWAP is deferred and rescheduled.

Step two: privacy configuration

The desk decides the unwind is strategy-bearing and elects to route it through the privacy pool. The TWAP order is wrapped with privacy requirements:

  • Each child’s amount is committed (Pedersen) on submission.
  • The receiving USDC accumulates at stealth addresses derived from the desk’s viewing key.
  • The intent’s pre-trade payload is encrypted; only solvers in the auction window can decrypt the subset relevant to their bid.

The cost of the privacy mode is a small per-child overhead — proof generation and verification add roughly a hundred milliseconds per child — and an additional 24-hour minimum on USDC withdrawal from the pool. For a 48-hour unwind that withdrawal delay does not slow the parent’s completion; the desk can sweep the accumulated USDC after the parent finishes.

Step three: solver auction and routing

For each child, the intent program runs a solver auction. Solvers commit sealed bids inside a 5-second window, then reveal. The winning solver routes the child across feasible venues — typically Serum, Raydium, Orca, Phoenix, and Lifinity for a SOL/USDC pair — splitting the child across multiple venues if any single venue’s depth is shallow at the child’s size.

For the scenario, the average child size is roughly 4,170 SOL. At that size, the router typically picks two or three venues per child. Across the full parent, the algorithm touches all five major Solana venues and rotates which venues see the largest share of any given child. The aggregate flow into any single venue is a small fraction of that venue’s natural daily volume, so the parent does not light up any venue’s monitoring.

Step four: real-time deviation control

Hours 6–11 of the unwind happen during a broader market downturn unrelated to the parent. SOL/USDC drops 90 basis points in fifteen minutes. The parent’s deviation gate kicks in: three consecutive children fail their deviation check and defer. The algorithm logs the deferrals, widens its acceptance band slightly (a configurable behaviour for desks that want to keep filling through volatility), and rebalances the schedule across the remaining hours to compensate.

The desk gets a real-time notification when the deferral threshold is hit. They can intervene — for instance, by lowering the deviation limit further or by pausing the algorithm — or let it self-correct. In the scenario the desk lets it self-correct; by hour 13 the market has recovered and the algorithm is back on schedule.

This kind of mid-flight reaction is the difference between a TWAP algorithm and a TWAP script. A script fires children blindly and learns about market conditions only when fills come back at bad prices. The protocol-level algorithm sees deviation in real time and reacts before it costs the desk basis points.

Step five: cross-chain edge case

Hour 22 brings an unrelated opportunity: the desk needs 50,000 of the unwound USDC to settle a position on Ethereum within the next hour. Instead of bridging out-of-band, the desk submits a CrossChainOrder against the privacy pool’s accumulated USDC:

let bridge_order = CrossChainOrder {
    source_chain: ChainId::Solana,
    destination_chain: ChainId::Ethereum,
    wormhole_message_hash: msg_hash,
    layerzero_packet_id: None,
    bridge_provider: BridgeProvider::Wormhole,
};

The order pulls from the stealth-address USDC accumulator on Solana, bridges atomically via Wormhole, and lands the USDC at a fresh stealth address on Ethereum. The parent TWAP is unaffected; the cross-chain sweep happens in parallel.

Step six: settlement and post-trade reporting

The parent finishes 1.5 hours inside its 48-hour window. The desk requests an execution report from the protocol. The report includes:

  • Per-child timestamp, size, venue split, realised price, and deviation from the child’s reference TWAP.
  • Aggregate slippage versus the parent’s pre-execution reference price.
  • A privacy-preserving summary suitable for the prime broker: total volume, weighted average price, and a selective-disclosure proof that every child executed inside the desk’s risk parameters.
  • A separate compliance-pack disclosure proving that the trade occurred entirely in the desk’s approved jurisdictions without revealing the underlying address structure.

The headline numbers for the scenario: 0.085% realised slippage against the pre-trade reference price, 0.93 basis points of variance across child fills, zero observable pattern in the child timing (the desk’s adversarial-detection script does not flag the schedule as a coherent parent), and no public attribution of the unwind to the desk’s identity.

By comparison, the same parent order routed naively through a single Raydium pool simulates to 11.4% slippage — roughly $11.4 million more cost — and would have been front-run inside the first minute by MEV bots watching the pool.

What the workflow demonstrates

Three points stand out from the walkthrough.

First, the OTC and algorithmic execution paths cooperate rather than compete. RFQ removes whatever size the MM network can swallow at a tight spread; the algorithm handles the residual. The desk does not have to choose between the two — the protocol composes them and the operator sees a single intent.

Second, privacy is not a separate workflow. The same intent that drives the TWAP carries the privacy configuration. The desk does not run a separate privacy ritual before or after the execution; the protocol does it inline.

Third, post-trade reporting is part of the protocol surface, not an after-thought. The selective-disclosure proofs let the desk satisfy the prime broker and the compliance officer without leaking the trade externally. That is the missing piece in most existing institutional execution stories — even when execution is private, reporting usually leaks. Moby Market handles both.

What the workflow does not cover

Two things worth naming.

The walkthrough assumes solver network depth sufficient to make commit-reveal auctions competitive. The current devnet network is thinner than mainnet will be; expect realised performance to converge to these numbers as the network matures, not to start there on day one.

The walkthrough also assumes the desk’s adversaries are sophisticated chain analysts but not protocol-level adversaries. A protocol-level adversary — one who controls a fraction of the solver network or the bridge validator set — is a different threat model and is handled by the security primitives in the protocol’s audit reports rather than by execution choices.

For the operational question that motivated the post — can a serious desk run a nine-figure unwind on-chain without losing money or strategy? — the answer that comes back from the workspace is yes, and the workflow above is the shape it takes.


Want this run against your flow?

The protocol is MIT and self-hostable. If you want the team to scope an engagement around your size, or write to hello@mobymarket.cryptuon.com.