Repository navigation
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR adds the two missing complete-set primitives to
market-core:split(mint one YES + one NO per unit of collateral) andmerge(burn one YES + one NO for one unit of collateral). Neither touches the FPMM pool, charges a fee, or moves the price. Alongside the entrypoints, this PR restates the core accounting invariants, adds amerge_maxhelper across the Rust/Python/TS models, exposes aquote_merge_maxview, publishesSetsSplit/SetsMergedevents, and hardenssell'ssets_mintedaccounting withchecked_sub.Related Issue
Changes
🔀 Split / merge entrypoints (
contracts/market-core/src/lib.rs)[ADD]
split(holder, market_id, amount)assert_not_pausedandassert_tradable(Open +now < close_time).holder.require_auth(); rejectsamount <= 0withInvalidAmount.sets_mintedwithchecked_add, enforcesMAX_SETS(MarketTooLarge), credits both legs withchecked_add, saves position/market, then transfers collateralholder -> contract(effects before interaction, matchingbuy).SetsSplit { market_id, holder, amount }.[ADD]
merge(holder, market_id, amount)MarketStatus::Openonly — allowed afterclose_timeand while paused (documented asymmetry: merge is a pure exit that cannot harm the pool).InsufficientShares(Make positions and LP ownership transferable to enable treasury migration #13);sets_minteddecremented viachecked_sub.contract -> holder, publishesSetsMerged { market_id, holder, amount }.[MODIFY]
sellnow useschecked_subform.sets_minted -= q.gross.[ADD]
quote_merge_max(market_id, holder) -> i128view wrappingmerge_maxoverget_position.[ADD]
#[contractevent] SetsSplit/SetsMergedwithmarket_idandholderas topics.🧮 Shared helper (
math.rs,model/fpmm_model.py,agents/core/fpmm.ts)merge_max(yes, no) = min(yes, no)in Rust, mirrored in the Python model and TS agent core so frontends and agents can offer "merge all" consistently.📚 Docs
[MODIFY]
docs/architecture.mdreserve_yes + Σ position.yes == sets_minted(and NO) andtoken.balance == sets_minted + fees_accrued.amounttosets_mintedand both leg sums; Resolved(Yes) pays exactlysets_minted; Void paysΣ floor((y_i+n_i)/2) + floor((r_y+r_n)/2) <= sets_minted.buyoverMarketTooLarge, but must lock real collateral and can merge out; documented as accepted risk pending a future per-market split cap.[MODIFY]
docs/frontend-integration.md— describessplit/merge/quote_merge_maxand the new events for the indexer.🔧 Bindings
packages/bindings/market-core/src/index.ts— regenerated to includesplit,merge,quote_merge_max, and theSetsSplit/SetsMergedevent spec.Verification Results
splitandmergeexist with documented auth, pause and lifecycle rulesreserve_yes,reserve_noorfees_accruedSetsSplit/SetsMergedevents published and in regenerated bindings specselluseschecked_subforsets_mintedwrong_caller_cannot_*tests with targetedmock_authsfor split and mergedocs/architecture.mdpackages/bindings/market-coreregeneratedcargo test --workspace,make lint, Python model, agents tests passdocs/architecture.mdlifecycle/invariants anddocs/frontend-integration.mdupdatedNotes / Non-goals
agent_split/agent_mergeforwarders are intentionally deferred to a follow-up.redeemalready covers that path.docs/wave-issues/02) is untouched; split/merge never touch the pool.Marketstruct layout.Closes #5