From 90899ce006a84c16661f9168ba127670de91b378 Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Thu, 10 Sep 2026 03:41:34 +0000 Subject: [PATCH 1/4] options: draw each option's two futures the way the fundraiser draws its endings The four-column outcomes table was a form no other chapter uses. The token fundraiser draws its two endings as full account figures, Future A and Future B, each showing the deciding transfer with the end state in the boxes, and the options chapter now does the same: the call's two futures in the concept section, where Alice and Bob already exist, and the put's two in the put section, once Carol and Dave are introduced. Above the strike the call is exercised and the put expires; below it the put is exercised and the call expires. The table is gone. Claude-Session: https://claude.ai/code/session_014RdEWCoCChaoKPhvcftHVG --- .../figures/options-call-future-a.svg | 179 ++++++++++++++++++ .../figures/options-call-future-b.svg | 165 ++++++++++++++++ .../figures/options-payoff.svg | 56 ------ .../figures/options-put-future-a.svg | 164 ++++++++++++++++ .../figures/options-put-future-b.svg | 169 +++++++++++++++++ .../options.md | 14 +- 6 files changed, 689 insertions(+), 58 deletions(-) create mode 100644 building-financial-products-in-solana/figures/options-call-future-a.svg create mode 100644 building-financial-products-in-solana/figures/options-call-future-b.svg delete mode 100644 building-financial-products-in-solana/figures/options-payoff.svg create mode 100644 building-financial-products-in-solana/figures/options-put-future-a.svg create mode 100644 building-financial-products-in-solana/figures/options-put-future-b.svg diff --git a/building-financial-products-in-solana/figures/options-call-future-a.svg b/building-financial-products-in-solana/figures/options-call-future-a.svg new file mode 100644 index 00000000..fa690418 --- /dev/null +++ b/building-financial-products-in-solana/figures/options-call-future-a.svg @@ -0,0 +1,179 @@ + + Future A: NVDAx ends the week above $180 + + + + + + Solana Devnet + + + + + + NVDAx mint + + + + + + + USDC mint + + + + + + + Maria (admin) + + + + MARIA'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Maria's USDC + + + + + + + Alice (writer) + + + + ALICE'S ADDRESS + + TOKEN PROGRAM + + NVDAX MINT + + + Alice's NVDAx + + + + ALICE'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Alice's USDC + + + + "OPTION" + MARKET'S ADDRESS + + ALICE'S ADDRESS + ID + + + option + + id: 1 + market: the NVDAx/USDC market + writer: Alice + holder: Bob + kind: Call + status: Exercised + contracts: 5 + underlying_per_contract: 1 NVDAx + strike_per_contract: 180 USDC + premium: 25 USDC + expiry: one week out + + + + + + Bob (holder) + + 1 SOL + + + + BOB'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Bob's USDC + + 75 USDC + + + + BOB'S ADDRESS + + TOKEN PROGRAM + + NVDAX MINT + + + Bob's NVDAx + + 5 NVDAx + NEW + + + + + + options program + + initialize_market() + write_option() + buy_option() + cancel_option() + exercise_option() + collect_proceeds() + reclaim_collateral() + collect_fees() + + + + "MARKET" + NVDAX & + USDC MINT ADDRESSES + + + market + + admin: Maria + underlying_mint: NVDAx + quote_mint: USDC + underlying_locked: 0 NVDAx + quote_locked: 900 USDC + fees_owed: 0.25 USDC + fee_bps: 100 + + + + "UNDERLYING_VAULT" + + MARKET'S ADDRESS + + + + underlying vault + + 0 NVDAx + authority: the market + + + + "QUOTE_VAULT" + + MARKET'S ADDRESS + + + + quote vault + + 900.25 USDC + authority: the market + + + Bob exercises: 900 USDC + + + Bob receives + 5 NVDAx + + the 900 USDC is owed to Alice, + who collects it from the vault + diff --git a/building-financial-products-in-solana/figures/options-call-future-b.svg b/building-financial-products-in-solana/figures/options-call-future-b.svg new file mode 100644 index 00000000..4ff8af26 --- /dev/null +++ b/building-financial-products-in-solana/figures/options-call-future-b.svg @@ -0,0 +1,165 @@ + + Future B: NVDAx ends the week below $180 + + + + + + Solana Devnet + + + + + + NVDAx mint + + + + + + + USDC mint + + + + + + + Maria (admin) + + + + MARIA'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Maria's USDC + + + + + + Alice (writer) + + 1 SOL + + + + ALICE'S ADDRESS + + TOKEN PROGRAM + + NVDAX MINT + + + Alice's NVDAx + + 5 NVDAx + + + + ALICE'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Alice's USDC + + + + "OPTION" + MARKET'S ADDRESS + + ALICE'S ADDRESS + ID + + + option + + id: 1 + market: the NVDAx/USDC market + writer: Alice + holder: Bob + kind: Call + status: Held + contracts: 5 + underlying_per_contract: 1 NVDAx + strike_per_contract: 180 USDC + premium: 25 USDC + expiry: one week out + CLOSED + + + + + + + + + Bob (holder) + + + + BOB'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Bob's USDC + + + + + + options program + + initialize_market() + write_option() + buy_option() + cancel_option() + exercise_option() + collect_proceeds() + reclaim_collateral() + collect_fees() + + + + "MARKET" + NVDAX & + USDC MINT ADDRESSES + + + market + + admin: Maria + underlying_mint: NVDAx + quote_mint: USDC + underlying_locked: 0 NVDAx + quote_locked: 0 USDC + fees_owed: 0.25 USDC + fee_bps: 100 + + + + "UNDERLYING_VAULT" + + MARKET'S ADDRESS + + + + underlying vault + + 0 NVDAx + authority: the market + + + + "QUOTE_VAULT" + + MARKET'S ADDRESS + + + + quote vault + + + the call expires unused: + Alice reclaims 5 NVDAx + + Bob's 25 USDC bought + a right he never used; + Alice keeps it and her shares + diff --git a/building-financial-products-in-solana/figures/options-payoff.svg b/building-financial-products-in-solana/figures/options-payoff.svg deleted file mode 100644 index 102ad9aa..00000000 --- a/building-financial-products-in-solana/figures/options-payoff.svg +++ /dev/null @@ -1,56 +0,0 @@ - - Four ways the week can end for the 180 call - NVDAx ends the week below the strike - NVDAx ends the week above the strike - - the strike, $180 - $160 - Bob lets the call expire - Alice (writer) - keeps the 25 premium - keeps her 5 NVDAx - +25 USDC - - Bob (holder) - paid the 25 premium - buys nothing - −25 USDC - $180 - exercising would gain nothing - Alice (writer) - keeps the 25 premium - keeps her 5 NVDAx - +25 USDC - - Bob (holder) - paid the 25 premium - buys nothing - −25 USDC - $185 - Bob exercises: break-even - Alice (writer) - keeps the 25 premium - sells her 5 NVDAx for 900 - though they are worth 925 - 0 USDC - - Bob (holder) - paid the 25 premium - buys 5 NVDAx for 900 - they are worth 925 - 0 USDC - $200 - Bob exercises - Alice (writer) - keeps the 25 premium - sells her 5 NVDAx for 900 - though they are worth 1,000 - −75 USDC - - Bob (holder) - paid the 25 premium - buys 5 NVDAx for 900 - they are worth 1,000 - +75 USDC - each result is against doing nothing, Alice keeping her shares and Bob his USDC; in every column the two sum to zero - diff --git a/building-financial-products-in-solana/figures/options-put-future-a.svg b/building-financial-products-in-solana/figures/options-put-future-a.svg new file mode 100644 index 00000000..1d4be22a --- /dev/null +++ b/building-financial-products-in-solana/figures/options-put-future-a.svg @@ -0,0 +1,164 @@ + + Future A: NVDAx ends the week above $150 + + + + + + Solana Devnet + + + + + + NVDAx mint + + + + + + + USDC mint + + + + + + + Maria (admin) + + + + MARIA'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Maria's USDC + + + + + + Carol (writer) + + 1 SOL + + + + CAROL'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Carol's USDC + + 1,019.80 USDC + + + + "OPTION" + MARKET'S ADDRESS + + CAROL'S ADDRESS + ID + + + option + + id: 2 + market: the NVDAx/USDC market + writer: Carol + holder: Dave + kind: Put + status: Held + contracts: 5 + underlying_per_contract: 1 NVDAx + strike_per_contract: 150 USDC + premium: 20 USDC + expiry: one week out + CLOSED + + + + + + + + + Dave (holder) + + + + DAVE'S ADDRESS + + TOKEN PROGRAM + + NVDAX MINT + + + Dave's NVDAx + + + + DAVE'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Dave's USDC + + + + + + options program + + initialize_market() + write_option() + buy_option() + cancel_option() + exercise_option() + collect_proceeds() + reclaim_collateral() + collect_fees() + + + + "MARKET" + NVDAX & + USDC MINT ADDRESSES + + + market + + admin: Maria + underlying_mint: NVDAx + quote_mint: USDC + underlying_locked: 0 NVDAx + quote_locked: 0 USDC + fees_owed: 0.45 USDC + fee_bps: 100 + + + + "UNDERLYING_VAULT" + + MARKET'S ADDRESS + + + + underlying vault + + + + "QUOTE_VAULT" + + MARKET'S ADDRESS + + + + quote vault + + 0.45 USDC + authority: the market + + + the put expires unused: + Carol reclaims 750 USDC + + Dave's 20 USDC bought insurance + against a fall that never came + diff --git a/building-financial-products-in-solana/figures/options-put-future-b.svg b/building-financial-products-in-solana/figures/options-put-future-b.svg new file mode 100644 index 00000000..71d129af --- /dev/null +++ b/building-financial-products-in-solana/figures/options-put-future-b.svg @@ -0,0 +1,169 @@ + + Future B: NVDAx ends the week below $150 + + + + + + Solana Devnet + + + + + + NVDAx mint + + + + + + + USDC mint + + + + + + + Maria (admin) + + + + MARIA'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Maria's USDC + + + + + + + Carol (writer) + + + + CAROL'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Carol's USDC + + + + "OPTION" + MARKET'S ADDRESS + + CAROL'S ADDRESS + ID + + + option + + id: 2 + market: the NVDAx/USDC market + writer: Carol + holder: Dave + kind: Put + status: Exercised + contracts: 5 + underlying_per_contract: 1 NVDAx + strike_per_contract: 150 USDC + premium: 20 USDC + expiry: one week out + + + + + + Dave (holder) + + 1 SOL + + + + DAVE'S ADDRESS + + TOKEN PROGRAM + + NVDAX MINT + + + Dave's NVDAx + + 0 NVDAx + + + + DAVE'S ADDRESS + + TOKEN PROGRAM + + USDC MINT + + + Dave's USDC + + 1,730 USDC + + + + + + options program + + initialize_market() + write_option() + buy_option() + cancel_option() + exercise_option() + collect_proceeds() + reclaim_collateral() + collect_fees() + + + + "MARKET" + NVDAX & + USDC MINT ADDRESSES + + + market + + admin: Maria + underlying_mint: NVDAx + quote_mint: USDC + underlying_locked: 5 NVDAx + quote_locked: 0 USDC + fees_owed: 0.45 USDC + fee_bps: 100 + + + + "UNDERLYING_VAULT" + + MARKET'S ADDRESS + + + + underlying vault + + 5 NVDAx + authority: the market + + + + "QUOTE_VAULT" + + MARKET'S ADDRESS + + + + quote vault + + 0.45 USDC + authority: the market + + + Dave exercises: 5 NVDAx + + + Dave receives + 750 USDC + + the 5 NVDAx are owed to Carol, + who collects them from the vault + diff --git a/building-financial-products-in-solana/options.md b/building-financial-products-in-solana/options.md index a2746c44..1143bb9c 100644 --- a/building-financial-products-in-solana/options.md +++ b/building-financial-products-in-solana/options.md @@ -23,7 +23,11 @@ The two sides have different shapes, and the shapes are the whole subject: - **The writer** keeps the premium whatever happens, and in exchange takes on an obligation: to sell the underlying at the strike (a call) or to buy it at the strike (a put) whenever the holder asks. The writer's gain is capped at the premium, and the writer's obligation is not. - **The holder's** loss is capped at the premium whatever happens, and the holder's gain is open-ended. -![Four ways the week can end, and what each side has at the end of it, against doing nothing. Below the strike the writer keeps the premium and the holder loses it. Above it the holder's gain grows with the price and the writer's loss grows with it, and in every column the two sum to zero.](figures/options-payoff.svg) +Alice's call has exactly two endings, and both are decided by where NVDAx is when the week runs out. + +![Future A: NVDAx ends the week above the strike. Bob exercises, paying the 900 USDC strike into the vault and taking the 5 NVDAx, and the strike is owed to Alice, who collects it. Bob's gain grows with the price; Alice's was capped at the premium the moment she sold.](figures/options-call-future-a.svg) + +![Future B: NVDAx ends the week below the strike. Bob lets the call expire and Alice reclaims her 5 NVDAx. Bob's 25 USDC bought a right he never used, and Alice keeps it and her shares.](figures/options-call-future-b.svg) Traditional options venues let a writer take on that obligation with only a fraction of it posted as **margin**, and then watch the position every day to make sure the fraction still covers it. This program does something simpler. **A writer posts the whole obligation, up front, into the vault.** @@ -145,7 +149,7 @@ Alice calls `collect_proceeds()`. The handler requires the option to be `Exercis ![collect_proceeds() pays Alice the 900 USDC strike from the quote vault and closes the option, rent back to her; only Maria's 0.25 USDC fee is left in the vault.](figures/options-collect-proceeds.svg) -Alice sold her five NVDAx for 900 USDC and had already been paid 24.75 USDC for agreeing to. She holds 1,924.75 USDC, an effective $184.95 a share against the $200 they now trade at. The $15.05 a share she gave up is the writer's side of the four-ways figure, its last column: the premium was all she could make, and she made it. +Alice sold her five NVDAx for 900 USDC and had already been paid 24.75 USDC for agreeing to. She holds 1,924.75 USDC, an effective $184.95 a share against the $200 they now trade at. The $15.05 a share she gave up is the writer's side of Future A: the premium was all she could make, and she made it. ## A Put Writer Posts Cash, and the Option Expires Unexercised @@ -157,6 +161,12 @@ Dave holds five NVDAx and wants insurance against a fall below $150 for the week ![Dave's buy_option() pays Carol 19.80 USDC and Maria 0.20 USDC; the 750 USDC of collateral does not move.](figures/options-buy-put.svg) +The put's two endings run the other way from the call's: it is a fall that pays the holder. + +![Future A: NVDAx ends the week above the strike. Dave lets the put expire and Carol reclaims her 750 USDC. Her return is the premium, and Dave's insurance cost him 20 USDC and paid nothing.](figures/options-put-future-a.svg) + +![Future B: NVDAx ends the week below the strike. Dave exercises, delivering his 5 NVDAx into the vault and taking the 750 USDC strike, and the shares are owed to Carol, who bought at $150 what the market now sells for less.](figures/options-put-future-b.svg) + The week passes with NVDAx above $150, and Dave does nothing: selling at 150 when the market pays more would be a gift to Carol. Once the expiry has passed, Carol calls `reclaim_collateral()`. The handler checks two things and then unwinds the option: - The option must be `Held`, because an exercised option has no collateral left to reclaim (`OptionNotHeld`). From 2eb837e73e25cfc58781d3133a3faeaaf52d5d5c Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Fri, 18 Sep 2026 20:18:28 +0000 Subject: [PATCH 2/4] Options: draw each ending the option did not take under the paragraph that describes it Main has since moved the fundraiser's two endings out of its opening and under the steps that draw them, and dropped the captions that recite their figures. Follow it. The concept section keeps one sentence saying every option has two endings and the price at expiry picks one; the outcomes table and the opening pair of figures go. The walkthrough already draws the call being exercised and the put expiring, so the two endings the story does not take get a figure each, under the paragraph that says what would have happened: the call expiring unused, with Alice reclaiming her shares, and Dave exercising the put. The put figure's holder-to-vault arrow takes the route its three sibling figures already take, and joins them on the geometry checker's named list. Claude-Session: https://claude.ai/code/session_014RdEWCoCChaoKPhvcftHVG --- ...-future-b.svg => options-call-expires.svg} | 4 +- .../figures/options-call-future-a.svg | 179 ------------------ ...future-b.svg => options-put-exercised.svg} | 4 +- .../figures/options-put-future-a.svg | 164 ---------------- .../options.md | 12 +- scripts/check-figure-geometry.mjs | 1 + 6 files changed, 14 insertions(+), 350 deletions(-) rename building-financial-products-in-solana/figures/{options-call-future-b.svg => options-call-expires.svg} (98%) delete mode 100644 building-financial-products-in-solana/figures/options-call-future-a.svg rename building-financial-products-in-solana/figures/{options-put-future-b.svg => options-put-exercised.svg} (99%) delete mode 100644 building-financial-products-in-solana/figures/options-put-future-a.svg diff --git a/building-financial-products-in-solana/figures/options-call-future-b.svg b/building-financial-products-in-solana/figures/options-call-expires.svg similarity index 98% rename from building-financial-products-in-solana/figures/options-call-future-b.svg rename to building-financial-products-in-solana/figures/options-call-expires.svg index 4ff8af26..2f97db2b 100644 --- a/building-financial-products-in-solana/figures/options-call-future-b.svg +++ b/building-financial-products-in-solana/figures/options-call-expires.svg @@ -1,5 +1,5 @@ - Future B: NVDAx ends the week below $180 + The call expires unused @@ -155,7 +155,7 @@ quote vault - + the call expires unused: Alice reclaims 5 NVDAx diff --git a/building-financial-products-in-solana/figures/options-call-future-a.svg b/building-financial-products-in-solana/figures/options-call-future-a.svg deleted file mode 100644 index fa690418..00000000 --- a/building-financial-products-in-solana/figures/options-call-future-a.svg +++ /dev/null @@ -1,179 +0,0 @@ - - Future A: NVDAx ends the week above $180 - - - - - - Solana Devnet - - - - - - NVDAx mint - - - - - - - USDC mint - - - - - - - Maria (admin) - - - - MARIA'S ADDRESS + - TOKEN PROGRAM + - USDC MINT - - - Maria's USDC - - - - - - - Alice (writer) - - - - ALICE'S ADDRESS + - TOKEN PROGRAM + - NVDAX MINT - - - Alice's NVDAx - - - - ALICE'S ADDRESS + - TOKEN PROGRAM + - USDC MINT - - - Alice's USDC - - - - "OPTION" + MARKET'S ADDRESS + - ALICE'S ADDRESS + ID - - - option - - id: 1 - market: the NVDAx/USDC market - writer: Alice - holder: Bob - kind: Call - status: Exercised - contracts: 5 - underlying_per_contract: 1 NVDAx - strike_per_contract: 180 USDC - premium: 25 USDC - expiry: one week out - - - - - - Bob (holder) - - 1 SOL - - - - BOB'S ADDRESS + - TOKEN PROGRAM + - USDC MINT - - - Bob's USDC - - 75 USDC - - - - BOB'S ADDRESS + - TOKEN PROGRAM + - NVDAX MINT - - - Bob's NVDAx - - 5 NVDAx - NEW - - - - - - options program - - initialize_market() - write_option() - buy_option() - cancel_option() - exercise_option() - collect_proceeds() - reclaim_collateral() - collect_fees() - - - - "MARKET" + NVDAX & - USDC MINT ADDRESSES - - - market - - admin: Maria - underlying_mint: NVDAx - quote_mint: USDC - underlying_locked: 0 NVDAx - quote_locked: 900 USDC - fees_owed: 0.25 USDC - fee_bps: 100 - - - - "UNDERLYING_VAULT" + - MARKET'S ADDRESS - - - - underlying vault - - 0 NVDAx - authority: the market - - - - "QUOTE_VAULT" + - MARKET'S ADDRESS - - - - quote vault - - 900.25 USDC - authority: the market - - - Bob exercises: 900 USDC - - - Bob receives - 5 NVDAx - - the 900 USDC is owed to Alice, - who collects it from the vault - diff --git a/building-financial-products-in-solana/figures/options-put-future-b.svg b/building-financial-products-in-solana/figures/options-put-exercised.svg similarity index 99% rename from building-financial-products-in-solana/figures/options-put-future-b.svg rename to building-financial-products-in-solana/figures/options-put-exercised.svg index 71d129af..778f5762 100644 --- a/building-financial-products-in-solana/figures/options-put-future-b.svg +++ b/building-financial-products-in-solana/figures/options-put-exercised.svg @@ -1,5 +1,5 @@ - Future B: NVDAx ends the week below $150 + Dave exercises the put @@ -157,7 +157,7 @@ 0.45 USDC authority: the market - + Dave exercises: 5 NVDAx diff --git a/building-financial-products-in-solana/figures/options-put-future-a.svg b/building-financial-products-in-solana/figures/options-put-future-a.svg deleted file mode 100644 index 1d4be22a..00000000 --- a/building-financial-products-in-solana/figures/options-put-future-a.svg +++ /dev/null @@ -1,164 +0,0 @@ - - Future A: NVDAx ends the week above $150 - - - - - - Solana Devnet - - - - - - NVDAx mint - - - - - - - USDC mint - - - - - - - Maria (admin) - - - - MARIA'S ADDRESS + - TOKEN PROGRAM + - USDC MINT - - - Maria's USDC - - - - - - Carol (writer) - - 1 SOL - - - - CAROL'S ADDRESS + - TOKEN PROGRAM + - USDC MINT - - - Carol's USDC - - 1,019.80 USDC - - - - "OPTION" + MARKET'S ADDRESS + - CAROL'S ADDRESS + ID - - - option - - id: 2 - market: the NVDAx/USDC market - writer: Carol - holder: Dave - kind: Put - status: Held - contracts: 5 - underlying_per_contract: 1 NVDAx - strike_per_contract: 150 USDC - premium: 20 USDC - expiry: one week out - CLOSED - - - - - - - - - Dave (holder) - - - - DAVE'S ADDRESS + - TOKEN PROGRAM + - NVDAX MINT - - - Dave's NVDAx - - - - DAVE'S ADDRESS + - TOKEN PROGRAM + - USDC MINT - - - Dave's USDC - - - - - - options program - - initialize_market() - write_option() - buy_option() - cancel_option() - exercise_option() - collect_proceeds() - reclaim_collateral() - collect_fees() - - - - "MARKET" + NVDAX & - USDC MINT ADDRESSES - - - market - - admin: Maria - underlying_mint: NVDAx - quote_mint: USDC - underlying_locked: 0 NVDAx - quote_locked: 0 USDC - fees_owed: 0.45 USDC - fee_bps: 100 - - - - "UNDERLYING_VAULT" + - MARKET'S ADDRESS - - - - underlying vault - - - - "QUOTE_VAULT" + - MARKET'S ADDRESS - - - - quote vault - - 0.45 USDC - authority: the market - - - the put expires unused: - Carol reclaims 750 USDC - - Dave's 20 USDC bought insurance - against a fall that never came - diff --git a/building-financial-products-in-solana/options.md b/building-financial-products-in-solana/options.md index f7c512d6..1a0fe392 100644 --- a/building-financial-products-in-solana/options.md +++ b/building-financial-products-in-solana/options.md @@ -24,7 +24,7 @@ The two sides have different shapes, and the shapes are the whole subject: - **The writer** keeps the premium whatever happens, and in exchange takes on an obligation: to sell the underlying at the strike (a call) or to buy it at the strike (a put) whenever the holder asks. The writer's gain is capped at the premium, and the writer's obligation is not. - **The holder's** loss is capped at the premium whatever happens, and the holder's gain is open-ended. -![](figures/options-payoff.svg) +Every option has exactly two endings, and the price at expiry decides which: the holder exercises, or the option expires and the writer takes the collateral back. The chapter draws both for the call and both for the put. Traditional options venues let a writer take on that obligation with only a fraction of it posted as **margin**, and then watch the position every day to make sure the fraction still covers it. This program does something simpler. **A writer posts the whole obligation, up front, into the vault.** @@ -134,7 +134,9 @@ NVIDIA reports earnings and NVDAx moves to $200. Bob calls `exercise_option()` b ![](figures/options-exercise.svg) -Bob now holds 5 NVDAx worth $1,000 and has spent 925 USDC to get them, 25 of premium and 900 of strike. His 1,000 USDC is 75 USDC. Had NVDAx stayed at $165, he would not have exercised (paying 900 for shares the market sells for 825), and the 25 USDC would have been his whole loss. +Bob now holds 5 NVDAx worth $1,000 and has spent 925 USDC to get them, 25 of premium and 900 of strike. His 1,000 USDC is 75 USDC. Had NVDAx stayed at $165, he would not have exercised (paying 900 for shares the market sells for 825), and the 25 USDC would have been his whole loss. The call would have expired, and once the week was out Alice would have called `reclaim_collateral()` for her 5 NVDAx, keeping the premium and the shares. + +![](figures/options-call-expires.svg) The strike payment stays in the vault, owed to Alice, rather than being sent to her directly. Paying the writer inside the exercise would mean requiring the writer's token account to exist at that moment, and a writer who closed it could then block the holder from ever exercising. The vault holds it instead, and the writer comes to get it. @@ -146,7 +148,7 @@ Alice calls `collect_proceeds()`. The handler requires the option to be `Exercis ![](figures/options-collect-proceeds.svg) -Alice sold her five NVDAx for 900 USDC and had already been paid 24.75 USDC for agreeing to. She holds 1,924.75 USDC, an effective $184.95 a share against the $200 they now trade at. The $15.05 a share she gave up is the writer's side of the four-ways figure, its last column: the premium was all she could make, and she made it. +Alice sold her five NVDAx for 900 USDC and had already been paid 24.75 USDC for agreeing to. She holds 1,924.75 USDC, an effective $184.95 a share against the $200 they now trade at. The $15.05 a share she gave up is the writer's side of the trade: the premium was all she could make, and she made it. ## A Put Writer Posts Cash, and the Option Expires Unexercised @@ -168,6 +170,10 @@ The week passes with NVDAx above $150, and Dave does nothing: selling at 150 whe Carol's return is the 19.80 USDC premium on a purchase that never happened. Dave's insurance cost him 20 USDC and paid nothing. Both got what they paid for. +Had NVDAx fallen below $150, Dave would have exercised instead: his 5 NVDAx into the underlying vault, the 750 USDC out to him, and the shares owed to Carol, who would have bought at $150 what the market then sold for less. + +![](figures/options-put-exercised.svg) + ## The Operator Collects the Fees Maria calls `collect_fees()`. The handler pays her `fees_owed`, 0.45 USDC across the two sales, zeroes the counter, and refuses to run when there is nothing to collect (`NothingToCollect`). The vaults are empty: every token that entered has left to the party it was owed to. diff --git a/scripts/check-figure-geometry.mjs b/scripts/check-figure-geometry.mjs index b3d99dbe..52207217 100644 --- a/scripts/check-figure-geometry.mjs +++ b/scripts/check-figure-geometry.mjs @@ -446,6 +446,7 @@ for (const file of selected) { "building-financial-products-in-solana/figures/options-buy-call.svg 462,523 slides", "building-financial-products-in-solana/figures/options-buy-put.svg 462,522 slides", "building-financial-products-in-solana/figures/options-exercise.svg 462,522 slides", + "building-financial-products-in-solana/figures/options-put-exercised.svg 462,431 slides", "building-financial-products-in-solana/figures/options-write-put.svg start 316,171 corner", // the base vault's payout to Bob runs up his column with 3 units between stem and box; it slides along Bob's NVDAx "building-financial-products-in-solana/figures/order-book-settle.svg 229,148 slides", From f9a138d8508527e3357bdec5659db0b028d382ac Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Fri, 18 Sep 2026 21:31:02 +0000 Subject: [PATCH 3/4] Options: keep the four-ways table alongside the two ending figures The table and the account figures answer different questions. The table shows how much each side makes across four closing prices, with the break-even and the flat column at the strike; the figures show the token movements and account changes of each ending. Keep both: the table in the concept section, the two endings under the paragraphs that describe them. Claude-Session: https://claude.ai/code/session_014RdEWCoCChaoKPhvcftHVG --- .../figures/options-payoff.svg | 56 +++++++++++++++++++ .../options.md | 6 +- 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 building-financial-products-in-solana/figures/options-payoff.svg diff --git a/building-financial-products-in-solana/figures/options-payoff.svg b/building-financial-products-in-solana/figures/options-payoff.svg new file mode 100644 index 00000000..102ad9aa --- /dev/null +++ b/building-financial-products-in-solana/figures/options-payoff.svg @@ -0,0 +1,56 @@ + + Four ways the week can end for the 180 call + NVDAx ends the week below the strike + NVDAx ends the week above the strike + + the strike, $180 + $160 + Bob lets the call expire + Alice (writer) + keeps the 25 premium + keeps her 5 NVDAx + +25 USDC + + Bob (holder) + paid the 25 premium + buys nothing + −25 USDC + $180 + exercising would gain nothing + Alice (writer) + keeps the 25 premium + keeps her 5 NVDAx + +25 USDC + + Bob (holder) + paid the 25 premium + buys nothing + −25 USDC + $185 + Bob exercises: break-even + Alice (writer) + keeps the 25 premium + sells her 5 NVDAx for 900 + though they are worth 925 + 0 USDC + + Bob (holder) + paid the 25 premium + buys 5 NVDAx for 900 + they are worth 925 + 0 USDC + $200 + Bob exercises + Alice (writer) + keeps the 25 premium + sells her 5 NVDAx for 900 + though they are worth 1,000 + −75 USDC + + Bob (holder) + paid the 25 premium + buys 5 NVDAx for 900 + they are worth 1,000 + +75 USDC + each result is against doing nothing, Alice keeping her shares and Bob his USDC; in every column the two sum to zero + diff --git a/building-financial-products-in-solana/options.md b/building-financial-products-in-solana/options.md index 1a0fe392..6c22ad54 100644 --- a/building-financial-products-in-solana/options.md +++ b/building-financial-products-in-solana/options.md @@ -24,7 +24,9 @@ The two sides have different shapes, and the shapes are the whole subject: - **The writer** keeps the premium whatever happens, and in exchange takes on an obligation: to sell the underlying at the strike (a call) or to buy it at the strike (a put) whenever the holder asks. The writer's gain is capped at the premium, and the writer's obligation is not. - **The holder's** loss is capped at the premium whatever happens, and the holder's gain is open-ended. -Every option has exactly two endings, and the price at expiry decides which: the holder exercises, or the option expires and the writer takes the collateral back. The chapter draws both for the call and both for the put. +Every option has exactly two endings, and the price at expiry decides which: the holder exercises, or the option expires and the writer takes the collateral back. Where the price lands inside each ending decides how much each side made. + +![](figures/options-payoff.svg) Traditional options venues let a writer take on that obligation with only a fraction of it posted as **margin**, and then watch the position every day to make sure the fraction still covers it. This program does something simpler. **A writer posts the whole obligation, up front, into the vault.** @@ -148,7 +150,7 @@ Alice calls `collect_proceeds()`. The handler requires the option to be `Exercis ![](figures/options-collect-proceeds.svg) -Alice sold her five NVDAx for 900 USDC and had already been paid 24.75 USDC for agreeing to. She holds 1,924.75 USDC, an effective $184.95 a share against the $200 they now trade at. The $15.05 a share she gave up is the writer's side of the trade: the premium was all she could make, and she made it. +Alice sold her five NVDAx for 900 USDC and had already been paid 24.75 USDC for agreeing to. She holds 1,924.75 USDC, an effective $184.95 a share against the $200 they now trade at. The $15.05 a share she gave up is the writer's side of the four-ways figure, its last column: the premium was all she could make, and she made it. ## A Put Writer Posts Cash, and the Option Expires Unexercised From 443ee6ce10ef0191de51441be930642b9329241b Mon Sep 17 00:00:00 2001 From: Mike MacCana Date: Fri, 18 Sep 2026 21:37:36 +0000 Subject: [PATCH 4/4] Options: set the two ending figures in main's restyled figure conventions Main has since set figure text in the sans and seed lists in Andale Mono, raised the curve and its dots, centred each icon and title on its title bar, and dropped bold from balances and field values. The two new figures were drawn before that and failed the checker's new rules in CI. They are regenerated from a generator brought up to the new conventions, verified by regenerating the nine lifecycle figures and finding them identical to main's outside the arrows main retouched by hand. Claude-Session: https://claude.ai/code/session_014RdEWCoCChaoKPhvcftHVG --- .../figures/options-call-expires.svg | 100 +++++++-------- .../figures/options-put-exercised.svg | 116 +++++++++--------- 2 files changed, 108 insertions(+), 108 deletions(-) diff --git a/building-financial-products-in-solana/figures/options-call-expires.svg b/building-financial-products-in-solana/figures/options-call-expires.svg index 2f97db2b..1aa824cf 100644 --- a/building-financial-products-in-solana/figures/options-call-expires.svg +++ b/building-financial-products-in-solana/figures/options-call-expires.svg @@ -1,76 +1,76 @@ - + The call expires unused - - Solana Devnet - + + Solana Devnet + - + NVDAx mint - + - + USDC mint - + - + Maria (admin) - MARIA'S ADDRESS + - TOKEN PROGRAM + - USDC MINT + MARIA'S ADDRESS + + TOKEN PROGRAM + + USDC MINT Maria's USDC - + - - Alice (writer) + + Alice (writer) 1 SOL - ALICE'S ADDRESS + - TOKEN PROGRAM + - NVDAX MINT + ALICE'S ADDRESS + + TOKEN PROGRAM + + NVDAX MINT - - Alice's NVDAx + + Alice's NVDAx - 5 NVDAx + 5 NVDAx - ALICE'S ADDRESS + - TOKEN PROGRAM + - USDC MINT + ALICE'S ADDRESS + + TOKEN PROGRAM + + USDC MINT Alice's USDC - "OPTION" + MARKET'S ADDRESS + - ALICE'S ADDRESS + ID + "OPTION" + MARKET'S ADDRESS + + ALICE'S ADDRESS + ID - - option + + option id: 1 market: the NVDAx/USDC market @@ -87,27 +87,27 @@ - + - + Bob (holder) - BOB'S ADDRESS + - TOKEN PROGRAM + - USDC MINT + BOB'S ADDRESS + + TOKEN PROGRAM + + USDC MINT Bob's USDC - + - - options program + + options program initialize_market() write_option() @@ -120,37 +120,37 @@ - "MARKET" + NVDAX & - USDC MINT ADDRESSES + "MARKET" + NVDAX & + USDC MINT ADDRESSES - - market + + market admin: Maria underlying_mint: NVDAx quote_mint: USDC - underlying_locked: 0 NVDAx + underlying_locked: 0 NVDAx quote_locked: 0 USDC fees_owed: 0.25 USDC fee_bps: 100 - "UNDERLYING_VAULT" + - MARKET'S ADDRESS - + "UNDERLYING_VAULT" + + MARKET'S ADDRESS + - - underlying vault + + underlying vault - 0 NVDAx + 0 NVDAx authority: the market - "QUOTE_VAULT" + - MARKET'S ADDRESS - + "QUOTE_VAULT" + + MARKET'S ADDRESS + quote vault diff --git a/building-financial-products-in-solana/figures/options-put-exercised.svg b/building-financial-products-in-solana/figures/options-put-exercised.svg index 778f5762..f077603e 100644 --- a/building-financial-products-in-solana/figures/options-put-exercised.svg +++ b/building-financial-products-in-solana/figures/options-put-exercised.svg @@ -1,71 +1,71 @@ - + Dave exercises the put - - Solana Devnet - + + Solana Devnet + - + NVDAx mint - + - + USDC mint - + - + Maria (admin) - MARIA'S ADDRESS + - TOKEN PROGRAM + - USDC MINT + MARIA'S ADDRESS + + TOKEN PROGRAM + + USDC MINT Maria's USDC - + - + Carol (writer) - CAROL'S ADDRESS + - TOKEN PROGRAM + - USDC MINT + CAROL'S ADDRESS + + TOKEN PROGRAM + + USDC MINT Carol's USDC - "OPTION" + MARKET'S ADDRESS + - CAROL'S ADDRESS + ID + "OPTION" + MARKET'S ADDRESS + + CAROL'S ADDRESS + ID - - option + + option id: 2 market: the NVDAx/USDC market writer: Carol holder: Dave kind: Put - status: Exercised + status: Exercised contracts: 5 underlying_per_contract: 1 NVDAx strike_per_contract: 150 USDC @@ -73,40 +73,40 @@ expiry: one week out - + - - Dave (holder) + + Dave (holder) 1 SOL - DAVE'S ADDRESS + - TOKEN PROGRAM + - NVDAX MINT + DAVE'S ADDRESS + + TOKEN PROGRAM + + NVDAX MINT - - Dave's NVDAx + + Dave's NVDAx - 0 NVDAx + 0 NVDAx - DAVE'S ADDRESS + - TOKEN PROGRAM + - USDC MINT + DAVE'S ADDRESS + + TOKEN PROGRAM + + USDC MINT - - Dave's USDC + + Dave's USDC - 1,730 USDC + 1,730 USDC - + - - options program + + options program initialize_market() write_option() @@ -119,42 +119,42 @@ - "MARKET" + NVDAX & - USDC MINT ADDRESSES + "MARKET" + NVDAX & + USDC MINT ADDRESSES - - market + + market admin: Maria underlying_mint: NVDAx quote_mint: USDC - underlying_locked: 5 NVDAx - quote_locked: 0 USDC + underlying_locked: 5 NVDAx + quote_locked: 0 USDC fees_owed: 0.45 USDC fee_bps: 100 - "UNDERLYING_VAULT" + - MARKET'S ADDRESS - + "UNDERLYING_VAULT" + + MARKET'S ADDRESS + - - underlying vault + + underlying vault - 5 NVDAx + 5 NVDAx authority: the market - "QUOTE_VAULT" + - MARKET'S ADDRESS - + "QUOTE_VAULT" + + MARKET'S ADDRESS + - - quote vault + + quote vault - 0.45 USDC + 0.45 USDC authority: the market