Skip to content

predict: add frozen-grid inventory impact - #1252

Draft
sdelo wants to merge 8 commits into
mainfrom
predict/frozen-grid-inventory-impact
Draft

sdelo wants to merge 8 commits into
mainfrom
predict/frozen-grid-inventory-impact

Conversation

@sdelo

@sdelo sdelo commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Live mint and close now compute an inventory-impact charge from a frozen 100-bucket capital coordinate (K = average(top 5 bucket maxima) − E) and a capped convex potential. The configured rate is zero, so the path is live and the charge is still zero.
  • initialize_inventory_grid / refresh_inventory_grid are authenticated keeper entry points. Callers submit 99 interior strike/forward ratios; the contract materializes the absolute ladder against its own forward and checks each bucket mass in [0.99%, 1.01%].
  • Refresh rebuilds from an inline 2048-cell geometric array rather than walking payout-tree dynamic fields, so a full book stays under the object-cache ceiling.

Why

Inventory impact prices the extra concentrated capital a mint or close leaves on the book. The earlier L-based design with rebates was withdrawn; this replacement freezes a 1%-mass grid at initialize/refresh and charges only when centered capital rises. The rate stays at zero so the machinery can land and be gas-tested without turning the fee on. Refresh used to walk the payout tree and hit the object-cache wall around 1,000 nodes; the inline cell array is the path that completes a full book.

Linear / Context

Key decisions

  • Default-off. inventory_impact_max_rate = 0. This is not a turn-on. Calibration of B_K / r_K is out of scope.
  • Frozen grid, not a live tree walk for the charge coordinate. The 100-bucket 1%-mass ladder is frozen at initialize/refresh. Incremental mint/close apply quantity into the cells and re-cut buckets from that snapshot.
  • Ratio boundaries, not absolute strikes. The caller submits 99 interior ratios so the contract can re-anchor the ladder to the pricer's forward and reject a mass-check miss.
  • Inline cell array instead of payout-tree refresh. A 16 KB inventory_cells vector lives on the market object so refresh reads zero payout-tree children. Incremental E uses the same snapped cell-span probability as apply, so refresh onto the same snapshot does not jump K.
  • No rebates, no escrow. The charge is ordinary expiry cash. E at close is re-derived from the current frozen snapshot, not stored at mint.

Scope / Descoped

  • In scope: Move source, unit and flow tests, sessions max_cost wiring, harness keeper / PTB / campaign traces, simulation event decode for the new charge field.
  • Out of scope: public design docs, notebooks, figure assets, predeploy evidence and register updates (left uncommitted).
  • Deferred: nonzero rate, B_K / r_K calibration, flat-vs-convex policy, liquidation inventory-charge policy, late-life cell resolution, nonzero-rate quote gas.

Test plan

  • sui move test --path packages/predict --gas-limit 100000000000 — 513 passed, including inventory-grid, inventory-cells, and inventory-impact flow tests.
  • sui move test --path packages/sessions --gas-limit 100000000000 — 24 passed (redeem_live now takes max_cost).
  • sui move build --path packages/predict --warnings-are-errors — clean.
  • Localnet capacity-tree with KEEPER_INVENTORY_GRID=1 — grid init ~40M compute; refresh at a full book peaked at 626M compute (13% of the 5,000M cap) and did not abort on the object-cache wall.

Risk / Rollout

  • Public markets stay at rate zero. A misconfigured nonzero rate would start charging live mint/close; protocol config still owns the bound.
  • Refresh can abort inventory_grid:2 if a submitted ratio ladder fails the mass check after an SVI roll; the next keeper tick retries.
  • Sessions redeem_live gained a max_cost argument. Callers of that entry must update with this package upgrade.
  • Rollback is a package revert; no on-chain inventory-grid state exists on currently deployed markets until a keeper initializes one.

Made with Cursor

Charge live mint and close transitions from a frozen 100-bucket
capital coordinate. Refresh rebuilds from an inline cell array so a
full book stays under the object-cache ceiling. The configured rate
defaults to zero.

Co-authored-by: Cursor <cursoragent@cursor.com>
Store the 99 rungs as strike/forward and slide them at quote time so spot
drift no longer needs a keeper refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sdelo sdelo reopened this Aug 22, 2026
sdelo and others added 6 commits August 24, 2026 10:54
The first mint already has a live pricer, so init and that trade are one
transaction. The empty-book race and the grid keeper both go away.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the mechanism and tests; the notebooks and public write-up were bloating the PR.

Co-authored-by: Cursor <cursoragent@cursor.com>
P-32 still treated keeper refresh, off-chain cuts, and a reused D033 as live work. Record the first-mint invert as D034 and leave only calibration and liquidation as remaining gates.

Co-authored-by: Cursor <cursoragent@cursor.com>
Later mints cut the ratio ladder once from stored logs and center K
on the stored incremental E, so the user path no longer walks every
cell edge. Mint, close, and create events now carry the K pair and
scale so a later tape can retune the rate.

Co-authored-by: Cursor <cursoragent@cursor.com>
Warm-start each later rung from the last step and stop at 0.5 bp so the first charged mint no longer bisects against 10,000× forward.

Co-authored-by: Cursor <cursoragent@cursor.com>
On-chain invert spent most of the computation cap. The keeper now
supplies the 1% ladder; create only verifies 1% ± 1 bp.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tonylee08
tonylee08 marked this pull request as draft September 1, 2026 18:11
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.

1 participant