diff --git a/building-financial-products-in-solana/betting-market.md b/building-financial-products-in-solana/betting-market.md
index 042e5ed2..90346fa2 100644
--- a/building-financial-products-in-solana/betting-market.md
+++ b/building-financial-products-in-solana/betting-market.md
@@ -3,7 +3,7 @@
What is going to be the top-grossing film this month? You have an opinion, and so does everyone else. There are two main ways to let everyone put money on it:
- **With a bookmaker.** The house quotes odds, locks them in when each bet is placed, and takes the other side of every bet, so it carries the risk of paying winners more than the losers staked. This is fixed-odds betting, the model of a high-street betting shop or a sportsbook.
-- **Without a bookmaker.** Bettors are matched against each other, and the house takes a fee instead of a position. **Parimutuel** betting, also called pool betting or, in Britain and the Commonwealth, the tote, was devised in 1867 by Joseph Oller, who ran a horse-race betting office in Paris. It reached Churchill Downs in Kentucky by 1878 and spread to racetracks around the world. France's law of 2 June 1891 banned bookmakers there and left authorized parimutuel pools as the only legal way to bet on horses. Prediction markets such as Polymarket and Kalshi use a similar system: there is no bookmaker, and bettors bet against each other.
+- **Without a bookmaker.** Bettors are matched against each other, and the house takes a fee instead of a position. **Parimutuel** betting, also called pool betting or, in Britain and the Commonwealth, the tote, was devised in 1867 by Joseph Oller, who ran a horse-race betting office in Paris. It reached Churchill Downs in Kentucky by 1878 and spread to racetracks around the world. France had banned bookmakers the year before its law of 2 June 1891 gave authorized racing societies the right to run parimutuel pools, which left the pool as the only legal way to bet on horses there.[^parimutuel-dates] Prediction markets such as Polymarket and Kalshi use a similar system: there is no bookmaker, and bettors bet against each other.
This chapter builds a parimutuel market. The program lives at `finance/betting-market` in the companion repository. Structurally it is the *Escrow* chapter with many parties and one new, serious question: who decides what happened in the real world?
@@ -17,7 +17,7 @@ In a parimutuel market, all stakes on all outcomes go into one vault, and when t
## The Operator Creates the Market
-Maria is the admin. Her public key is recorded in the program's config, and only she can create events, add outcomes, open betting, settle, and cancel; her revenue is a 2% fee, charged only on the losing pool. She runs `initialize_config()` once, naming herself admin, USDC as the token, herself as fee recipient, and 200 **basis points** (2%) as the fee. For this month's market she runs `initialize_event()` with a description ("top-grossing film this month") and a `betting_closes_at` of midnight on the last day of the month. A close time already in the past fails with `CloseTimeInPast`. The event starts as a Draft, and Maria calls `add_outcome()` twice: "Glowbugs 3" and "The Quiet Floor". Then she calls `open_betting()`, which moves the event to Open. The first signer of `initialize_config()` becomes the admin. Every handler after it checks the signer against that address and rejects anyone else with `Unauthorized`; `test_only_admin_can_initialize_event` and the last step of `test_open_betting_needs_two_outcomes` check it.
+Maria is the admin. Her public key is recorded in the program's config, and only she can create events, add outcomes, open betting, settle, cancel, and close a finished event's accounts; her revenue is a 2% fee, charged only on the losing pool. She runs `initialize_config()` once, naming herself admin, USDC as the token, herself as fee recipient, and 200 **basis points** (2%) as the fee. For this month's market she runs `initialize_event()` with a description ("top-grossing film this month") and a `betting_closes_at` of midnight on the last day of the month. A close time already in the past fails with `CloseTimeInPast`. The event starts as a Draft, and Maria calls `add_outcome()` twice: "Glowbugs 3" and "The Quiet Floor". Then she calls `open_betting()`, which moves the event to Open. The first signer of `initialize_config()` becomes the admin. Every handler after it checks the signer against that address and rejects anyone else with `Unauthorized`; `test_only_admin_can_initialize_event` and the last step of `test_open_betting_needs_two_outcomes` check it.

@@ -73,7 +73,7 @@ For Alice: 300 + floor(300 × 196 ÷ 400) = 300 + 147 = **447 USDC**. For Bob: 1
None of these payouts depended on when anyone bet. Had Alice bet first, when Glowbugs 3 held only her stake, or last, after Bob, she would still receive 447 USDC, because the payout reads the pools at the close. A racetrack's tote board works the same way: the odds it shows keep moving until the race starts, and every winning ticket is paid at the final odds.
-The multiply runs in u128 and divides exactly once, after the multiplication, so the result is floored a single time; dividing first would throw away precision on every claim. The floor means the payouts can fall a few minor units short of the distributable pool; that dust stays in the vault, and no claimant receives it.
+The multiply runs in u128 and divides exactly once, after the multiplication, so the result is floored a single time; dividing first would throw away precision on every claim. The floor means the payouts can fall a few minor units short of the distributable pool; that dust stays in the vault, where no claimant can reach it, until the event closes and `close_event()` pays it to the fee recipient.
The claim closes the bet account, refunding its rent to the bettor. **A closed account stops a double claim**: Alice claiming twice fails because the bet account the second claim needs is already gone (checked by `test_double_claim_fails`), and there is no `claimed` flag to forget to check.
@@ -83,7 +83,11 @@ The claim closes the bet account, refunding its rent to the bettor. **A closed a
Carol's losing bet pays nothing, but its account still holds her rent. She calls `close_losing_bet()`, which checks the event is settled and her outcome is not the winner (a winner trying to use this path for losing bets rejects with `BetWon` and must use `claim_winnings()`), then closes the account and returns the rent to her. `test_close_losing_bet_only_after_settle_and_only_for_losers` checks that both attempts fail.
-An Open event can also be voided: if the studio pulls both films from release, there is no result to settle. `cancel_event()`, admin-only, flips the status to Cancelled, and every bettor reclaims their exact stake through `claim_refund()`, no fee taken, using the same close-the-account-to-prevent-double-claims mechanic (checked by `test_cancel_and_refund`). `cancel_event()` works on a Draft too, which is how Maria abandons a market she set up wrong before anyone has staked on it. Settled and Cancelled are the two ways an Open event ends, and in both every bet account has a handler that pays it out or closes it.
+Bob claims his 149 USDC the same way, and once Carol's account closes no bet of the event is open. Maria then closes what the event created, children first, because each account's address derives from its parent's: a bet's from its outcome's, an outcome's from the event's. She calls `close_outcome()` once per outcome. It refuses while the event is still a Draft or Open (`EventNotFinished`) and while any bet is open (`BetsStillOpen`), because a bet's claim or refund needs its outcome account to check against; otherwise it closes the outcome account and returns its rent to her. Then she calls `close_event()`, which makes the same two checks and also refuses while any outcome is open (`OutcomesStillOpen`): an outcome account left behind would be found again, with its old `total_amount`, by a later event created with the same event ID. It pays whatever the vault still holds to the fee recipient's token account, closes the vault, and closes the event account, returning both rents to her. The event knows whether it may close from two counters: `open_outcomes`, which `add_outcome()` raises and `close_outcome()` lowers, and `open_bets`, which `place_bet()` raises for each bet account it creates (a top-up reuses the account) and `claim_winnings()`, `claim_refund()`, and `close_losing_bet()` each lower. In this market the vault is already empty: 147 and 49 divided exactly. Where the floors leave dust, `close_event()` sends it to Maria along with the fee. `test_close_event_pays_dust_to_fee_recipient_and_returns_rent` runs a market whose shares do not divide exactly, and checks that the one minor unit left reaches the fee recipient, that every closed account is gone, and that each rent returns to the admin.
+
+
+
+An Open event can also be voided: if the studio pulls both films from release, there is no result to settle. `cancel_event()`, admin-only, flips the status to Cancelled, and every bettor reclaims their exact stake through `claim_refund()`, no fee taken, using the same close-the-account-to-prevent-double-claims mechanic (checked by `test_cancel_and_refund`, which then closes the canceled event's accounts, with nothing left in the vault to pay). `cancel_event()` works on a Draft too, which is how Maria abandons a market she set up wrong before anyone has staked on it. Settled and Cancelled are the two ways an Open event ends, and in both every bet account has a handler that pays it out or closes it. Every account the event created names its closer, as the *State Machines* chapter asks: a bet closes through `claim_winnings()`, `close_losing_bet()`, or `claim_refund()`; an outcome through `close_outcome()`; the vault and the event through `close_event()`. The config is Maria's state for the whole deployment, and no handler closes it.

@@ -104,6 +108,7 @@ Every checked operation maps to `MathOverflow`. There are no rates and no curves
- The winning pool, the distributable losing pool, and the fee always sum exactly to the pre-settlement total pool: 400 + 196 + 4 = 600.
- A winner's payout is never less than their stake.
- One bet account per bettor per outcome, and no bet account survives its payout, refund, or close.
+- `open_bets` counts the event's bet accounts and `open_outcomes` its outcome accounts; no outcome closes while a bet is open, and the event does not close while an outcome is.
- The outcome list never changes once the event is Open, and no stake enters the pool at or after `betting_closes_at`.
- Only the admin's signature can settle or cancel, and only the payout formula decides amounts.
@@ -112,24 +117,28 @@ Every checked operation maps to `MathOverflow`. There are no rates and no curves
- **The resolution itself.** Maria could settle the wrong outcome, maliciously or by mistake, and the decision is hers alone. This program is deliberately the simplest case; the *Offchain Truth* chapter covers what it costs a trusted party to lie, and how to replace a single signer with several.
- **Settling an empty outcome** would divide by zero in every claim; rejected at the source with `OutcomeHasNoBets`.
- **Double claims** fail because the bet account is gone, as the claim step showed.
+- **Closing an account a claim still needs** fails too. `close_outcome()` and `close_event()` refuse while the event is a Draft or Open (`EventNotFinished`) or any bet is open (`BetsStillOpen`), and `close_event()` refuses while any outcome is (`OutcomesStillOpen`). So no claim is left with nothing to claim against, and no stale outcome waits for a later event with the same ID (checked by `test_close_event_refused_while_a_bet_is_open` and `test_close_event_refused_while_event_is_open`). Only Maria's signature closes anything (`test_only_admin_can_close_outcomes_and_event`).
- **Changing the terms after betting opens** is impossible: the outcome list, the fee, and the close time are all fixed before the first bet can land.
- **Betting on a known result**: a bettor who learns the result before Maria settles cannot stake on it, because `place_bet()` stops at `betting_closes_at` with `BettingClosed`. The program cannot tell when the result becomes public, so choosing a close time before that moment is Maria's job.
- **Betting after settlement or cancellation** rejects with `EventNotOpen`, whether the event was settled or canceled.
## Testing Considerations
-The suite builds all state through the program's own handlers, and its centerpiece is `test_full_lifecycle`, config through claims. It uses the same pools as the story above (400 on the winner, 200 on the loser, a 4 USDC fee) and asserts balances after the bets, the settlement, and the claims. Around it, one test per failure mode: the admin-only handlers, the outcome list locking when betting opens, the two-outcome minimum, both edges of the close time, a close time in the past, bet-after-settle, double claims, empty-outcome settlement, and cancel-and-refund. `test_close_losing_bet_only_after_settle_and_only_for_losers` checks that `close_losing_bet()` works only on a settled event and only for a bet that lost. When you write your own market, copy the shape: the happy path checks the math, and every adversarial code path gets a test whose name says what it refuses to allow.
+The suite builds all state through the program's own handlers, and its centerpiece is `test_full_lifecycle`, config through claims. It uses the same pools as the story above (400 on the winner, 200 on the loser, a 4 USDC fee) and asserts balances after the bets, the settlement, and the claims. Around it, one test per failure mode: the admin-only handlers, the outcome list locking when betting opens, the two-outcome minimum, both edges of the close time, a close time in the past, bet-after-settle, double claims, empty-outcome settlement, and cancel-and-refund. The last of those also closes the canceled event once its refunds are in. `test_close_losing_bet_only_after_settle_and_only_for_losers` checks that `close_losing_bet()` works only on a settled event and only for a bet that lost. `test_close_event_pays_dust_to_fee_recipient_and_returns_rent` closes a settled event whose payouts left dust, and `test_close_event_refused_while_a_bet_is_open`, `test_close_event_refused_while_event_is_open`, and `test_only_admin_can_close_outcomes_and_event` check the three ways a close is refused. When you write your own market, copy the shape: the happy path checks the math, and every adversarial code path gets a test whose name says what it refuses to allow.
## What You Learnt from Building the Betting Market
A racetrack's parimutuel pool needs a tote board, a licensed operator, and a payout window. Here a vault and four expressions of arithmetic do those jobs: the pool is the odds, the program carries no risk, and the house takes a fee only from the losers.
-This chapter added five concepts:
+This chapter added six concepts:
- **The parimutuel structure.** All stakes pool together; winners split the losing pool in proportion to their stakes, so a larger stake wins more and no one sets odds.
- **A designated signer decides the result.** The operator acts as the oracle, and the program's job is making that trust visible and narrow: their signature picks the winner and does nothing else.
- **Terms locked before bettors commit stakes.** The outcome list, the fee, and the close time are all fixed before the first stake lands, so the question bettors staked on cannot be rewritten.
- **Account closure as the double-claim defense.** A paid-out bet has no account left to claim with.
- **Cancellation refunds every stake.** Draft and Open events can be canceled, and stakes in a canceled event are refunded in full, so a voided event strands nobody's stake.
+- **Every account names its closer.** A bet closes when it pays out or is refunded, and the admin closes the outcomes and the event once no bet is open, children before parents, so no rent stays locked and no stale account can be found by a later event.
In the *Order Book Exchange* chapter we will build an exchange. Instead of paying into one pool, traders post orders at the prices they want, backed by tokens moved into a vault when the order is placed, and the program matches each new order against the best resting one. You will see how orders are stored, matched, and paid out onchain, where every step costs compute. The pooled payout formula and the trusted signer both return later, in the *Lending and Borrowing* and *Perpetual Futures* chapters, where the trusted signature is a price feed and settlement runs continuously instead of once.
+
+[^parimutuel-dates]: Oller's 1867 system is recorded in the Encyclopaedia Universalis entry on him, at [universalis.fr/encyclopedie/joseph-oller](https://www.universalis.fr/encyclopedie/joseph-oller/); the 1878 Churchill Downs introduction by the Kentucky Derby, at [kentuckyderby.com/horses/news/how-kentucky-derby-betting-traditions-have-changed-over-time-since-1875](https://www.kentuckyderby.com/horses/news/how-kentucky-derby-betting-traditions-have-changed-over-time-since-1875/); and the law of 2 June 1891, whose article 5 lets approved societies organize the pari mutuel, at [weka.fr/base-juridique-weka/loda/JORFTEXT000000512373](https://www.weka.fr/base-juridique-weka/loda/JORFTEXT000000512373).
diff --git a/building-financial-products-in-solana/escrow.md b/building-financial-products-in-solana/escrow.md
index f0bcd440..88e79ae5 100644
--- a/building-financial-products-in-solana/escrow.md
+++ b/building-financial-products-in-solana/escrow.md
@@ -20,7 +20,7 @@ Alice starts, like every character in this book, with one SOL and 1,000 USDC; sh
The naive version is that Alice sends Bob her USDC and waits. But what if Bob takes the USDC and leaves? An **escrow** lets Alice and Bob swap without having to trust each other.
-Traditional finance solves this with a trusted third party. Alice sends her funds to the third party, which holds them in escrow until Bob has done the same, then distributes both sides to their destinations. And, as anyone who has sent money overseas knows, the third party takes a percentage of the amount for itself: even a plain transfer through an intermediary costs 6.5% on average worldwide, and more than 20% on the worst corridors.[^remittance-cost]
+Traditional finance solves this with a trusted third party. Alice sends her funds to the third party, which holds them in escrow until Bob has done the same, then distributes both sides to their destinations. And, as anyone who has sent money overseas knows, the third party takes a percentage of the amount for itself: even a plain transfer through an intermediary costs about 6.4% on average worldwide, and more than 20% on the worst corridors.[^remittance-cost]

diff --git a/building-financial-products-in-solana/figures/betting-alice-claim.svg b/building-financial-products-in-solana/figures/betting-alice-claim.svg
index 2d3bd388..a55b5eaf 100644
--- a/building-financial-products-in-solana/figures/betting-alice-claim.svg
+++ b/building-financial-products-in-solana/figures/betting-alice-claim.svg
@@ -112,7 +112,7 @@
-
+ betting program
@@ -126,56 +126,58 @@
close_losing_bet()cancel_event()claim_refund()
+ close_outcome()
+ close_event()
-
- "CONFIG"
-
-
- config
+
+ "CONFIG"
+
+
+ config
-
- "EVENT" + EVENT ID
-
-
- event
-
- status: Settled
- winning_outcome_index: 0
- winning_pool: 400
- distributable_losing_pool: 196
+
+ "EVENT" + EVENT ID
+
+
+ event
+
+ status: Settled
+ winning_outcome_index: 0
+ winning_pool: 400
+ distributable_losing_pool: 196
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 0: Glowbugs 3
-
- total_amount: 400
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 0: Glowbugs 3
+
+ total_amount: 400
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 1: The Quiet Floor
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 1: The Quiet Floor
-
- EVENT'S ADDRESS +
- TOKEN PROGRAM + USDC MINT
-
-
- vault: the event's USDC
-
- 149 USDC
- authority: the event PDA
-
-
+
+ EVENT'S ADDRESS +
+ TOKEN PROGRAM + USDC MINT
+
+
+ vault: the event's USDC
+
+ 149 USDC
+ authority: the event PDA
+
+ 1. claim_winnings() · 447 USDCsigned by the event PDA
diff --git a/building-financial-products-in-solana/figures/betting-maria-close.svg b/building-financial-products-in-solana/figures/betting-maria-close.svg
new file mode 100644
index 00000000..faf4b007
--- /dev/null
+++ b/building-financial-products-in-solana/figures/betting-maria-close.svg
@@ -0,0 +1,169 @@
+
diff --git a/building-financial-products-in-solana/figures/betting-maria-setup.svg b/building-financial-products-in-solana/figures/betting-maria-setup.svg
index 51fca82a..56f0235f 100644
--- a/building-financial-products-in-solana/figures/betting-maria-setup.svg
+++ b/building-financial-products-in-solana/figures/betting-maria-setup.svg
@@ -71,7 +71,7 @@
-
+ betting program
@@ -85,66 +85,68 @@
close_losing_bet()cancel_event()claim_refund()
+ close_outcome()
+ close_event()
-
- "CONFIG"
-
-
- config
-
- admin: Maria
- token_mint: USDC
- fee_recipient: Maria
- default_fee_bps: 200 (2%)
- NEW
+
+ "CONFIG"
+
+
+ config
+
+ admin: Maria
+ token_mint: USDC
+ fee_recipient: Maria
+ default_fee_bps: 200 (2%)
+ NEW
-
- "EVENT" + EVENT ID
-
-
- event
-
- status: Open
- total_pool: 0
- fee_bps: 200
- betting_closes_at: month end
- NEW
+
+ "EVENT" + EVENT ID
+
+
+ event
+
+ status: Open
+ total_pool: 0
+ fee_bps: 200
+ betting_closes_at: month end
+ NEW
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 0: Glowbugs 3
-
- total_amount: 0
- NEW
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 0: Glowbugs 3
+
+ total_amount: 0
+ NEW
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 1: The Quiet Floor
-
- total_amount: 0
- NEW
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 1: The Quiet Floor
+
+ total_amount: 0
+ NEW
-
- EVENT'S ADDRESS +
- TOKEN PROGRAM + USDC MINT
-
-
- vault: the event's USDC
-
- 0 USDC
- authority: the event PDA
- NEW
+
+ EVENT'S ADDRESS +
+ TOKEN PROGRAM + USDC MINT
+
+
+ vault: the event's USDC
+
+ 0 USDC
+ authority: the event PDA
+ NEWevery later call checks Maria's signature against config.admin;anyone else gets Unauthorized
diff --git a/building-financial-products-in-solana/figures/betting-place-bets.svg b/building-financial-products-in-solana/figures/betting-place-bets.svg
index e1857750..397fc7cc 100644
--- a/building-financial-products-in-solana/figures/betting-place-bets.svg
+++ b/building-financial-products-in-solana/figures/betting-place-bets.svg
@@ -125,7 +125,7 @@
-
+ betting program
@@ -139,59 +139,61 @@
close_losing_bet()cancel_event()claim_refund()
+ close_outcome()
+ close_event()
-
- "CONFIG"
-
-
- config
+
+ "CONFIG"
+
+
+ config
-
- "EVENT" + EVENT ID
-
-
- event
-
- status: Open
- total_pool: 600
- fee_bps: 200
+
+ "EVENT" + EVENT ID
+
+
+ event
+
+ status: Open
+ total_pool: 600
+ fee_bps: 200
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 0: Glowbugs 3
-
- total_amount: 400
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 0: Glowbugs 3
+
+ total_amount: 400
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 1: The Quiet Floor
-
- total_amount: 200
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 1: The Quiet Floor
+
+ total_amount: 200
-
- EVENT'S ADDRESS +
- TOKEN PROGRAM + USDC MINT
-
-
- vault: the event's USDC
-
- 600 USDC
- authority: the event PDA
-
-
-
-
+
+ EVENT'S ADDRESS +
+ TOKEN PROGRAM + USDC MINT
+
+
+ vault: the event's USDC
+
+ 600 USDC
+ authority: the event PDA
+
+
+
+ 300 USDC100 USDC200 USDC
diff --git a/building-financial-products-in-solana/figures/betting-settlement.svg b/building-financial-products-in-solana/figures/betting-settlement.svg
index a2a8f5f9..276a1a3f 100644
--- a/building-financial-products-in-solana/figures/betting-settlement.svg
+++ b/building-financial-products-in-solana/figures/betting-settlement.svg
@@ -107,7 +107,7 @@
-
+ betting program
@@ -121,61 +121,63 @@
close_losing_bet()cancel_event()claim_refund()
+ close_outcome()
+ close_event()
-
- "CONFIG"
-
-
- config
-
- admin: Maria
- token_mint: USDC
- fee_recipient: Maria
- default_fee_bps: 200 (2%)
+
+ "CONFIG"
+
+
+ config
+
+ admin: Maria
+ token_mint: USDC
+ fee_recipient: Maria
+ default_fee_bps: 200 (2%)
-
- "EVENT" + EVENT ID
-
-
- event
-
- status: Settled
- winning_outcome_index: 0
- winning_pool: 400
- distributable_losing_pool: 196
+
+ "EVENT" + EVENT ID
+
+
+ event
+
+ status: Settled
+ winning_outcome_index: 0
+ winning_pool: 400
+ distributable_losing_pool: 196
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 0: Glowbugs 3
-
- total_amount: 400
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 0: Glowbugs 3
+
+ total_amount: 400
-
- "OUTCOME" + EVENT
- ADDRESS + INDEX
-
-
- outcome 1: The Quiet Floor
+
+ "OUTCOME" + EVENT
+ ADDRESS + INDEX
+
+
+ outcome 1: The Quiet Floor
-
- EVENT'S ADDRESS +
- TOKEN PROGRAM + USDC MINT
-
-
- vault: the event's USDC
-
- 596 USDC
- authority: the event PDA
-
-
+
+ EVENT'S ADDRESS +
+ TOKEN PROGRAM + USDC MINT
+
+
+ vault: the event's USDC
+
+ 596 USDC
+ authority: the event PDA
+
+ 4 USDC (the fee)signed by the event PDAMaria signs settle_event(): Glowbugs 3 wins
diff --git a/building-financial-products-in-solana/figures/order-book-alice-ask.svg b/building-financial-products-in-solana/figures/order-book-alice-ask.svg
index c1a41315..2952775e 100644
--- a/building-financial-products-in-solana/figures/order-book-alice-ask.svg
+++ b/building-financial-products-in-solana/figures/order-book-alice-ask.svg
@@ -162,7 +162,7 @@
-
+ order book program
@@ -172,24 +172,26 @@
cancel_order()settle_funds()withdraw_fees()
+ pause_market()
+ resume_market()
-
- "MARKET" + NVDAX MINT +
- USDC MINT ADDRESS
-
-
- market
-
- authority: Maria
- base_mint: NVDAx
- quote_mint: USDC
- fee_basis_points: 25
- tick_size: 1
- min_order_size: 1
- base_lot_size: 100
- quote_lot_size: 1
- is_active: true
+
+ "MARKET" + NVDAX MINT +
+ USDC MINT ADDRESS
+
+
+ market
+
+ authority: Maria
+ base_mint: NVDAx
+ quote_mint: USDC
+ fee_basis_points: 25
+ tick_size: 1
+ min_order_size: 1
+ base_lot_size: 100
+ quote_lot_size: 1
+ is_active: true
diff --git a/building-financial-products-in-solana/figures/order-book-cancel.svg b/building-financial-products-in-solana/figures/order-book-cancel.svg
index 3f325fca..716083f9 100644
--- a/building-financial-products-in-solana/figures/order-book-cancel.svg
+++ b/building-financial-products-in-solana/figures/order-book-cancel.svg
@@ -175,7 +175,7 @@
-
+ order book program
@@ -185,24 +185,26 @@
cancel_order()settle_funds()withdraw_fees()
+ pause_market()
+ resume_market()
-
- "MARKET" + NVDAX MINT +
- USDC MINT ADDRESS
-
-
- market
-
- authority: Maria
- base_mint: NVDAx
- quote_mint: USDC
- fee_basis_points: 25
- tick_size: 1
- min_order_size: 1
- base_lot_size: 100
- quote_lot_size: 1
- is_active: true
+
+ "MARKET" + NVDAX MINT +
+ USDC MINT ADDRESS
+
+
+ market
+
+ authority: Maria
+ base_mint: NVDAx
+ quote_mint: USDC
+ fee_basis_points: 25
+ tick_size: 1
+ min_order_size: 1
+ base_lot_size: 100
+ quote_lot_size: 1
+ is_active: true
diff --git a/building-financial-products-in-solana/figures/order-book-initialize-market.svg b/building-financial-products-in-solana/figures/order-book-initialize-market.svg
index 74a7256f..d216f624 100644
--- a/building-financial-products-in-solana/figures/order-book-initialize-market.svg
+++ b/building-financial-products-in-solana/figures/order-book-initialize-market.svg
@@ -112,7 +112,7 @@
-
+ order book program
@@ -122,25 +122,27 @@
cancel_order()settle_funds()withdraw_fees()
+ pause_market()
+ resume_market()
-
- "MARKET" + NVDAX MINT +
- USDC MINT ADDRESS
-
-
- market
-
- authority: Maria
- base_mint: NVDAx
- quote_mint: USDC
- fee_basis_points: 25
- tick_size: 1
- min_order_size: 1
- base_lot_size: 100
- quote_lot_size: 1
- is_active: true
- NEW
+
+ "MARKET" + NVDAX MINT +
+ USDC MINT ADDRESS
+
+
+ market
+
+ authority: Maria
+ base_mint: NVDAx
+ quote_mint: USDC
+ fee_basis_points: 25
+ tick_size: 1
+ min_order_size: 1
+ base_lot_size: 100
+ quote_lot_size: 1
+ is_active: true
+ NEW
diff --git a/building-financial-products-in-solana/figures/order-book-match.svg b/building-financial-products-in-solana/figures/order-book-match.svg
index 9be11d7b..386f5bd4 100644
--- a/building-financial-products-in-solana/figures/order-book-match.svg
+++ b/building-financial-products-in-solana/figures/order-book-match.svg
@@ -190,7 +190,7 @@
-
+ order book program
@@ -200,24 +200,26 @@
cancel_order()settle_funds()withdraw_fees()
+ pause_market()
+ resume_market()
-
- "MARKET" + NVDAX MINT +
- USDC MINT ADDRESS
-
-
- market
-
- authority: Maria
- base_mint: NVDAx
- quote_mint: USDC
- fee_basis_points: 25
- tick_size: 1
- min_order_size: 1
- base_lot_size: 100
- quote_lot_size: 1
- is_active: true
+
+ "MARKET" + NVDAX MINT +
+ USDC MINT ADDRESS
+
+
+ market
+
+ authority: Maria
+ base_mint: NVDAx
+ quote_mint: USDC
+ fee_basis_points: 25
+ tick_size: 1
+ min_order_size: 1
+ base_lot_size: 100
+ quote_lot_size: 1
+ is_active: true
diff --git a/building-financial-products-in-solana/figures/order-book-settle.svg b/building-financial-products-in-solana/figures/order-book-settle.svg
index 97f4e54a..20b22d60 100644
--- a/building-financial-products-in-solana/figures/order-book-settle.svg
+++ b/building-financial-products-in-solana/figures/order-book-settle.svg
@@ -177,7 +177,7 @@
-
+ order book program
@@ -187,24 +187,26 @@
cancel_order()settle_funds() ×2withdraw_fees()
+ pause_market()
+ resume_market()
-
- "MARKET" + NVDAX MINT +
- USDC MINT ADDRESS
-
-
- market
-
- authority: Maria
- base_mint: NVDAx
- quote_mint: USDC
- fee_basis_points: 25
- tick_size: 1
- min_order_size: 1
- base_lot_size: 100
- quote_lot_size: 1
- is_active: true
+
+ "MARKET" + NVDAX MINT +
+ USDC MINT ADDRESS
+
+
+ market
+
+ authority: Maria
+ base_mint: NVDAx
+ quote_mint: USDC
+ fee_basis_points: 25
+ tick_size: 1
+ min_order_size: 1
+ base_lot_size: 100
+ quote_lot_size: 1
+ is_active: true
diff --git a/building-financial-products-in-solana/figures/order-book-withdraw-fees.svg b/building-financial-products-in-solana/figures/order-book-withdraw-fees.svg
index 1bf89099..d4963ecc 100644
--- a/building-financial-products-in-solana/figures/order-book-withdraw-fees.svg
+++ b/building-financial-products-in-solana/figures/order-book-withdraw-fees.svg
@@ -164,7 +164,7 @@
-
+ order book program
@@ -174,24 +174,26 @@
cancel_order()settle_funds()withdraw_fees()
+ pause_market()
+ resume_market()
-
- "MARKET" + NVDAX MINT +
- USDC MINT ADDRESS
-
-
- market
-
- authority: Maria
- base_mint: NVDAx
- quote_mint: USDC
- fee_basis_points: 25
- tick_size: 1
- min_order_size: 1
- base_lot_size: 100
- quote_lot_size: 1
- is_active: true
+
+ "MARKET" + NVDAX MINT +
+ USDC MINT ADDRESS
+
+
+ market
+
+ authority: Maria
+ base_mint: NVDAx
+ quote_mint: USDC
+ fee_basis_points: 25
+ tick_size: 1
+ min_order_size: 1
+ base_lot_size: 100
+ quote_lot_size: 1
+ is_active: true
diff --git a/building-financial-products-in-solana/figures/perps-create-pool.svg b/building-financial-products-in-solana/figures/perps-create-pool.svg
index 99f7b08a..39c0940b 100644
--- a/building-financial-products-in-solana/figures/perps-create-pool.svg
+++ b/building-financial-products-in-solana/figures/perps-create-pool.svg
@@ -109,7 +109,7 @@
"POOL" + COLLATERAL MINT +ORACLE FEED ADDRESS
-
+ Pool
@@ -122,6 +122,8 @@
short_size: 0cumulative_funding: 0average_price: $100
+ price_feed_program:
+ mock-price-feed
diff --git a/building-financial-products-in-solana/figures/prop-amm-open-market.svg b/building-financial-products-in-solana/figures/prop-amm-open-market.svg
index d9b38d1b..e1f3f201 100644
--- a/building-financial-products-in-solana/figures/prop-amm-open-market.svg
+++ b/building-financial-products-in-solana/figures/prop-amm-open-market.svg
@@ -1,4 +1,4 @@
-