clipboardAdditional notes

  • The best market making setup involves implementing an indexer that can maintain the live replica of your on-chain maker book and subscribe to its state via gRPC stream of block updates. This is so that you can be state-aware of your inventory and open orders. You can then design the backend system to intelligently choose what type of order update needs to be pushed. For example, in scenarios where no specific order levels need to change, and only mid price needs to be shifted, you can decide choose to send an update mid price instruction over update book instruction, because of extremely high efficiency of the former instruction.

  • The update book instruction consumes compute units proportional to the number of levels to be modified. So updating all 32 max no. of order levels will cost ~4500 compute units whereas updating 1 order level (one of bid or ask) can only cost ~700 compute units.

  • Bid levels must be strictly decreasing in price; ask levels must be strictly increasing. No crossing allowed (best bid < best ask). The program will reject updates that violate this. Makers should validate this client-side before sending.

  • When actively market making on Solana, most market makers have ran into properly sequencing mid price updates because there's a possibility that a mid price at t0 lands or is included after the mid price update made at t1, where the difference in time could be just a few milliseconds. Archer provides a solution to this: Maker books provide a field called last_updated_sequence_number, which is simply an incremented count of the maker book being updated. Every UpdateBook call requires a sequence_number strictly greater than last_updated_sequence_number on-chain. If a maker sends two updates and they land out of order, the stale one is rejected. Makers should use a monotonically increasing counter and be prepared to handle this rejection gracefully. This is critical for high-frequency updating.

  • The maker book tracks quote_locked / quote_free and base_locked / base_free. Locked = reserved for open orders, free = available for withdrawal. When you update mid price or book levels, the program recalculates locked amounts. Withdrawals can only draw from the free balance.

  • The update mid price instruction lets maker to change the mid price and recenter all order levels around the newer price. But there's an edge case where the price change is drastically higher than the previous one, and the maker does not have sufficient liquidity to cover the bids. In that case, the program will reject those updates with errors. It is recommended to always have more quote token funds deposited in your maker book account than your bids sizes for avoiding this scenario. Asks are not affected from this for obvious reasons.

  • The matching engine works on price priority pro rata execution. For example, during matching, if these are the order levels in the unified aggregated order book from three makers: Asks ( Price - [ maker - size ])

    100 - [maker A - 10]

    101 - [maker A - 20, maker B - 20, maker C - 40]

    If the taker order is a BUY order of size 30 units, then the 10 units will be filled from the ask at lowest ask price of 100 filling maker A 100% on that order level. The next remaining 20 units are filled at price 101 as:

    maker A - 5 units maker B - 5 units maker C - 10 units

    This is because maker C has twice as liquidity available at that price level than maker A and B. This helps us create a market structure where makers are not competing on latency and simply competing on providing tighter spreads and higher depth. We call it Increase Depth Reduce Spreads (IDRS)

  • At any given price level, resting limit orders fill first (FIFO), then makers fill pro-rata with the remainder. This means maker fill rates are reduced when limit orders exist at the same price. Makers should be aware of the taker order book state when quoting.

  • The sync_spread_ticks parameter lets a maker specify how much should their order levels by widened by for serving the synchronous (atomic) flow on hybrid markets. Hybrid markets are where both atomic and async order flow can be served. A market maker looking to opt out of serving atomic sync flow can set sync_spread_ticks = u16::MAX and the matching engine will take care of avoiding those maker books for sync flow on hybrid markets.

  • For hybrid markets, the market admin sets a sync_fee_multiplier (1-7x) that multiplies the base taker_fee_ppm for sync swaps. Makers should understand that their sync_spread_ticks is one layer of protection, and the multiplied fee is another - both work together to disincentivize toxic sync flow.

  • The delegation of a public key address over maker book can be set and unset by the maker owning the book. The delegation can only cancel all orders, update mid prices or order levels, and update the sync spread ticks. They cannot deposit or withdraw the funds. Use the delegation carefully and at your own risk. Example use cases of delegation: Letting AI agents do market making on your behalf, or deposit/withdrawals from your cold wallet but market making with your hot wallet, and more.

  • Important: The market authority has the ability to suspend a market makers' book upon finding unethical and toxic behavior. All suspended maker books are skipped from matching any taker orders.

  • There are two use-cases for priority fees on Solana in general. One for block inclusion, and second for the position of your transaction in the block. Archer's maker books have zero contention so there's no priority fee that a maker has to pay from write contention at all. But paying minimal to some priority fees while sending updates still help because it increases the likelihood of block inclusion or bring your transaction update to top of the block much easier. The extreme efficiency of maker book operations make sure that you can get at top of the block with minimal priority fees in micro lamports per CU because the CU consumption itself is extremely low.

Last updated