> ## Documentation Index
> Fetch the complete documentation index at: https://getequity.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Market-Making Pools

> How the per-asset venue lets approved market makers create and redeem stock with the vault, and quote investors a two-way price.

Every RWA asset can have a **venue**: a market-making pool where approved market makers
trade with the asset's vault and quote investors a two-way price. It complements the
[Market](/docs/onchain/introduction), where investors buy from and sell to the vault at one
price.

A venue is a meeting place, not a counterparty. It holds no balances of its own and
issues nothing: every trade moves tokens directly between the maker, the vault and the
investor.

<Warning>
  **Testnets only today.** Venues are deployed on **Base Sepolia** and **Solana devnet**.
  They are not deployed on either mainnet yet, and no market maker is approved anywhere.
</Warning>

## Two markets in one venue

| | Primary | Secondary |
| - | - | - |
| Who trades | A maker and the asset's vault | An investor and a named maker |
| What happens | **Create**: the maker pays cNGN and receives stock from the vault. **Redeem**: the maker returns stock and is paid cNGN. | The investor buys from or sells to a maker at the maker's quoted spread |
| Price | The asset's live accrued price | The live price ± the maker's spread |

Every price in the venue is the asset's **live accrued price**, the same one the Market
uses (EVM: `Market.currentPriceScaled(token)`; see
[yield and accrual](/docs/onchain/yield-and-accrual)).

## Create

`create(cashIn, minStockOut)`: the maker pays cNGN and receives existing vault stock at
the live price. Nothing is minted. A creation fee and a protocol fee come off `cashIn`;
the rest buys stock. Creation is capped per firm per day (reset at 00:00 UTC); a create
that would cross the cap reverts with `DailyCapExceeded` (no partial fills).

## Redeem

A redemption returns stock to the vault in exchange for cNGN. The stock moves to the
vault **at request**, and the price and fees are **locked** then.

<Steps>
  <Step title="Request">
    `requestRedeem(amount, minPayout, deadline)`. Reverts with `SlippageExceeded` if the
    locked payout is under `minPayout`, and `DeadlineExpired` past `deadline` (0 is not
    allowed). A maker can have **one redemption** outstanding at a time
    (`AlreadyQueued`); the slot frees when that redemption is resolved.
  </Step>

  <Step title="Paid now, or queued">
    On Base, the request pays at once when the queue is empty and the vault's available
    cash covers it. Otherwise it joins a strict first-in-first-out queue. On Solana,
    requests always queue; clients send `request_redeem` and `claim_redeem` together
    when the pair would succeed.
  </Step>

  <Step title="Claim">
    `claimRedeem(id)` pays the redemption at the head of the queue (`NotAtQueueHead`
    otherwise) from the vault's available cash (`InsufficientFloat` if short). Before
    the auto-return window anyone may claim; after it, only the maker.
  </Step>

  <Step title="Resolve, after the force-resolve window">
    `claimRedeem` now reverts with `UseResolve`. Anyone may call `resolveRedeem(id)`
    (`TooEarlyToResolve` before the window). The vault's cash decides the outcome: the
    maker is paid at the locked price if it can be covered, otherwise the stock is
    returned. If the price has risen since the request, the stock returned is capped at
    `amount × lockedPrice ÷ livePrice`, so a delayed redemption is never worth more than
    the payout it replaced. There is no compensation for waiting.
  </Step>

  <Step title="Withdraw what is owed">
    `resolveRedeem` only records the outcome. `withdrawOwed(maker)` delivers it
    (or `withdrawOwedStock` / `withdrawOwedCash` separately). Anyone may call it; it always
    pays the maker.
  </Step>
</Steps>

**Available cash ("float")** = the vault's cNGN minus a fixed retail reserve (kept for
investors selling on the Market), capped by the vault's allowance to the venue.

**Pause.** When a venue is paused, creates and new redemption requests stop, but queued
redemptions can still be claimed and resolved.

## Secondary trading

A maker quotes a **spread** around the live price, not a price:

* `setQuote(bidSpreadBps, askSpreadBps, validUntil)`: each spread must be within the
  venue's maximum (`QuoteTooWide`), and `validUntil` within its validity cap
  (`ValidityTooLong`).
* Investors trade with a named maker: `buyFrom(maker, amount, maxCost)` and
  `sellTo(maker, amount, minPayout)`. Trades against an expired quote revert with
  `QuoteExpired`. Both legs move directly between investor and maker.
* A maker's **depth** on each side is the smaller of its balance and its allowance to the
  venue, so the maker controls depth through its token approvals.

A newly created venue has every secondary-trading limit at zero until GetEquity sets them.

## Makers trade through the venue

An approved maker **cannot sell on the Market**: the Market reverts with
`MakersMustUseTheVenue` (Solana: `rwa_market` error 6025) and the maker redeems through
the venue instead. This keeps maker flow out of the retail book. The restriction lifts if
the maker is stood down.

## Parameters

Each venue's parameters are set by GetEquity's multisig and can be read on chain. The
pilot values intended for mainnet:

| Parameter | Pilot value |
| - | - |
| Maximum spread (hard band) | 200 bps |
| Spread obligation ceiling | 100 bps |
| Minimum quoted depth per side | ₦250,000 (reported, not enforced) |
| Creation fee | \~8 bps |
| Protocol fee | 5 bps |
| Daily creation cap per firm | ₦50,000,000 |
| Quote validity cap | 1 hour |
| Auto-return window | \~7 days |
| Force-resolve window | \~10 days |

On the testnets the windows are much shorter (300 s and 900 s) so the full redemption
lifecycle can be exercised in minutes.

## Errors

| Error | Meaning |
| - | - |
| `NotAnActiveMaker` | The caller is not approved for the firm, or not active on this asset |
| `AssetNotTradeable` | The asset is not tradeable on the Market |
| `DailyCapExceeded` | The create would cross the firm's daily cap |
| `SlippageExceeded` | Payout under `minPayout`, or stock under `minStockOut` |
| `DeadlineExpired` | Past the request deadline |
| `AlreadyQueued` | The maker already has a redemption outstanding |
| `NotAtQueueHead` | Only the head of the queue can be claimed |
| `InsufficientFloat` | The vault's available cash cannot pay this claim yet |
| `UseResolve` / `TooEarlyToResolve` | Past / before the force-resolve window |
| `NothingOwed` | `withdrawOwed` with nothing to deliver |
| `NotYourRedemption` | A maker-only step called by someone else |
| `QuoteTooWide` / `ValidityTooLong` / `QuoteExpired` | Quote outside the venue's limits, or stale |
| `IsPaused` (Solana: `Paused`) | The venue is paused |
| `AllowanceExceeded` | Raised by the **vault**: the trade would draw more than the vault allows |

Solana's `rwa_venue` program uses the same names (error codes 6000–6023 in its
[IDL](/docs/onchain/solana-programs)).

## Next

<CardGroup cols={2}>
  <Card title="Become a market maker" icon="handshake" href="/docs/onchain/become-a-market-maker">
    Approval, setup and every maker call on both chains.
  </Card>

  <Card title="Venue addresses" icon="list" href="/docs/onchain/ethereum-addresses#market-making-venues">
    Base Sepolia venues by asset; Solana venue derivation.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.