Skip to content

Add Cash-Secured Puts (Contracts + Full Off-Chain Stack + Frontend)#270

Merged
ewitulsk merged 8 commits into
stagingfrom
claude/cash-secured-puts-plan-c47fu6
Jun 28, 2026
Merged

Add Cash-Secured Puts (Contracts + Full Off-Chain Stack + Frontend)#270
ewitulsk merged 8 commits into
stagingfrom
claude/cash-secured-puts-plan-c47fu6

Conversation

@ewitulsk

@ewitulsk ewitulsk commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Implements cash-secured puts end-to-end as the structural mirror of the existing covered-call system: collateral is settlement cash, exercise delivers underlying for cash, and redeem returns underlying for the assigned range / cash for the unassigned range. The FIFO cursor, Position, and Quote are reused unchanged; puts are additive — every call path keeps working.

No Jira ticket was created for this branch — please link one (epic SO-8 Protocol) per .claude/PRs.md before merge. Vaults are intentionally out of scope (no put vault), so vault-only components (vault-sim, backtester, price-charting APY, the /vault page) are untouched; the vault keeper/tx builders are already product-agnostic.

Contracts (Move)

  • put_bucket.movePutBucket<U,S,Put>: create/execute_write (writer+trader)/write_collateralized/exercise (deliver underlying → cash)/redeem/burn/cleanup/invalidate. Reuses Position, Quote, Account, Treasury, bucket::FlowKind, skim_fee.
  • rfq_put.move — cash-collateral ascending-premium auction (mirror of rfq).
  • session_put_bucket.move — siws session twins.
  • bucket.move exposes pow10; new Put* events + put_collateral_mismatch error.
  • Pricing/rounding (documented in put_bucket.move): collateral in rounds up (apply_strike_ceil), every cash payout rounds down (apply_strike_floor) ⇒ provably solvent; bounded dust swept at cleanup. Underlying leg is exact.
  • 165 Move tests pass (136 baseline + 29 new, incl. a fractional-strike solvency + dust-sweep test).

Off-chain (Rust)

  • pricingput_price_per_unit, put_delta, put_assignment_prob, put_greeks, put_break_even (parity + bump-and-reprice tests).
  • protocol-types — 13 Put* event mirrors + ChainEvent variants.
  • sui-txexecute_write_put (both legs Coin<Settlement>), rfq_put builders, coin_pkg::create_put_buckets_and_pools.
  • api-service-clientBucketPricing.is_put + put_collateral(), open_put_rfqs().
  • indexer (+ indexer-graphql)option_kind discriminator on buckets/positions/rfqs/rfq_bids (migration 000008_put_options), 13 Put* event decoders + materializers, GraphQL optionKind field/filter.
  • api-service — unified /buckets gains option_type (series) + option_coin_type (bucket); /buckets/:id gains option_coin_type/option_kind; /rfqs?kind=put.
  • quoting-servicereservation_for branches on option_kind: a put trader-flow signer reserves ceil(amount×strike) settlement collateral instead of underlying. Wire format & quote signing unchanged.
  • mm-botprice_rfq dispatches to put Black-Scholes by is_put; new onchain_put_rfq bidder (premium escrow, identical accounting); [onchain_put_rfq] config.
  • option-schedulerProductType{Call,Put} threaded config→roller→codegen (put_<i>/PUT_<i> coin modules), create_put_buckets, migration 0004_product_type widening the active-slot uniqueness.
  • tools--product call|put on exchange/writer/trader/mm-quote (+ rfq-monitor option_kind).
  • keeper — unchanged by design (vault-coupled cranks only; puts have no vault; standalone put RFQs settle permissionlessly via the rfq_put::settle builder).

Frontend

  • Call·Put toggle in the Composer; put PTB builders (composer_put.ts cash-collateral write/buy, dashboard_put.ts exercise-delivers-underlying / redeem), session_put_bucket wrappers, useOwnedPutOptions, put-aware ITM/intrinsic/payoff + modal copy. Series.option_type/Bucket.option_coin_type modeled optional (fall back to call) so the call UI is unaffected.

Verification

  • Move: sui move test165/165 pass.
  • Rust: cargo check --workspace --all-targets0 errors (entire workspace incl. all test modules). Unit tests run green where disk allowed: pricing, protocol-types (45), api-service-client, mm-bot (49), option-scheduler (60), indexer-graphql (2), quoting-service (36). indexer/api-service test-binary linking hit a sandbox disk limit (ENOSPC) — their cargo check --all-targets passes, so the code (incl. tests) compiles; running those suites is a CI follow-up.
  • Frontend: tsc -b --noEmit + vite build → clean.

Sandbox note: the MystenLabs/sui cargo git dep was fetched via the transparent HTTPS proxy (the scoped git relay 403s non-ewitulsk repos) using a scoped GIT_CONFIG_GLOBAL, without touching the global git config.

🤖 Generated with Claude Code

Cash-secured puts as the structural mirror of the covered-call bucket:
same FIFO cursor / Position / Quote, with the asset legs flipped
(collateral is settlement cash; exercise delivers underlying for cash).

Contracts:
- put_bucket.move: PutBucket<U,S,Put> with create/execute_write (writer &
  trader flows)/write_collateralized/exercise/redeem/burn_expired/cleanup/
  invalidate. Reuses Position, Quote, Account, Treasury, FlowKind, skim_fee.
- rfq_put.move: ascending escrowed-premium auction whose collateral leg is
  cash; mirrors rfq.move including the coupled-venue path.
- session_put_bucket.move: siws session twins of the put flows.
- bucket.move: expose pow10 as public(package) for shared scaling math.
- events.move / errors.move: distinct put events + put_collateral_mismatch.

Pricing / rounding (documented in put_bucket.move): the cash leg rounds so
the bucket is provably solvent — collateral IN rounds UP (apply_strike_ceil),
every cash payout rounds DOWN (apply_strike_floor). Aggregate outflow can
never exceed collateral; the bounded rounding remainder ("dust") is swept to
the admin at cleanup.

Tests (29 new, full suite 165 passing): put_bucket happy paths, FIFO
assignment, exercise/redeem/expiry guards, a fractional-strike solvency +
dust-sweep test; put RFQ create/bid/settle/refund/expired; session
writer/trader/exercise/redeem.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sui-options Ready Ready Preview, Comment Jun 28, 2026 2:47pm

Request Review

claude added 2 commits June 28, 2026 14:10
- pricing: put_price_per_unit, put_delta, put_assignment_prob, put_greeks,
  put_break_even (Black-Scholes mirror), with put-call-parity + bump-and-
  reprice tests.
- protocol-types: 13 Put* event mirrors + ChainEvent variants, matching the
  on-chain events.move field order (collateral / dust_swept extras).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
- sui-tx: execute_write_put (writer/trader flows, both legs Coin<Settlement>),
  rfq_put (bid/settle/settle_expired/create with explicit notional + cash
  collateral), coin_pkg::create_put_buckets_and_pools (shared impl, calls
  put_bucket::create_put_bucket). Registered new modules in tx/mod.rs.
- api-service-client: BucketPricing.is_put + put_collateral(ceil), option_kind/
  option_coin_type wire fields, open_put_rfqs().

Verified: cargo build -p sui-tx and cargo test -p api-service-client green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
Call/Put toggle in Composer; put PTB builders (composer_put.ts write/buy with
cash collateral, dashboard_put.ts exercise-delivers-underlying / redeem),
session_put_bucket wrappers, useOwnedPutOptions, put-aware ITM/intrinsic/copy
in Dashboard + Action/Confirm modals. Series.option_type / Bucket.option_coin_type
modeled optional (fall back to call) so the call UI is unaffected.

Verified: npx tsc -b --noEmit and vite build both clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
…oting/tools

In-progress multi-component put work landed by parallel implementation passes:
- indexer + indexer-graphql: option_kind discriminator, 13 Put* event decoders,
  materializers, migration 000008_put_options, GraphQL field.
- api-service: option_type/option_coin_type on /buckets, /rfqs?kind=put.
- mm-bot: put pricing dispatch + onchain_put_rfq bidder.
- option-scheduler: ProductType thread + put codegen + create_put_buckets,
  migration 0004_product_type.
- quoting-service: put collateral reservation branch.
- tools: --product flag on exchange/writer/trader/mm-quote/rfq-monitor.

Checkpoint commit — full-workspace integration build + fixes follow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
…option_kind

Checkpoint — quoting+keeper agent's quoting reservation branch; indexer-graphql
option_kind in progress. Integration build + fixes follow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
Checkpoint of parallel implementation progress. Integration build follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
Bucket test literals in rfq/mod.rs and rfq/bulk_view.rs needed the new
option_kind (and a dropped deepbook_pool_id) field.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VX6MEUC9jqRQmXN4xfCg6Q
@ewitulsk ewitulsk changed the title Add Cash-Secured Puts (Bucket, RFQ, Session Twins) Add Cash-Secured Puts (Contracts + Full Off-Chain Stack + Frontend) Jun 28, 2026
@ewitulsk ewitulsk merged commit bd9a305 into staging Jun 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants