Skip to content

Share security capacity across questions with individual principal and lazy settlement - #1164

Open
KillariDev wants to merge 17 commits into
mainfrom
t3code/multi-question-security-pool
Open

KillariDev wants to merge 17 commits into
mainfrom
t3code/multi-question-security-pool

Conversation

@KillariDev

@KillariDev KillariDev commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Result

Multiple questions use one security pool, with separate outcome tokens and question settlement. Buyers choose the question and amount. REP providers deposit once, authorize a standing underwriting commitment, and choose their own health target. Paid purchases automatically consume shared capacity; buyers do not select individual vaults.

This PR replaces allocation ownership snapshots and pooled NAV shares with exact individual principal and commitments. One vault's liquidation cannot subtract another vault's principal. Central custody and indexed accounting remove the need for every provider to process every question or perform migration jobs for other providers.

Capital, health and exits

Each owner has one aggregate principal C, one total ETH-denominated commitment K, and at most one live commitment position. Every deposited REP backs that owner's entire live commitment. REP is idle only when the owner has no commitment; separate free and pledged balances cannot hide collateral from health, fee eligibility, capacity or liquidation checks. The owner selects a health factor h. Changing that target alone does not change the commitment or add collateral. Required REP uses upward-rounded arithmetic with the accepted REP/ETH price, the pool security multiplier and the owner's health target. Portfolio backing uses the greater of the native pool multiplier and 105%; an owner's health factor is separate and can be selected from 100% upward. The chosen target adds an authorization buffer; liquidation eligibility uses the protocol collateral floor.

A deposit creates an exact principal claim; it does not buy previously earned income or another owner’s losses. depositFor(owner, amount) retains its interface but requires owner == msg.sender: owners deposit only into their own account. This prevents a third-party dust deposit from changing the principal that a keeper consented to use under maximumOwnRep. Deposits immediately strengthen an existing commitment without increasing K. authorize(commitment) sets total K using all deposited principal; the separate pledge amount and top-up API are removed. Newly authorized commitment can earn future releases from an already funded vesting stream.

ownerCollateral(owner) is the canonical principal, commitment and safe-withdrawal view, including principal released through lazy retirement accounting. withdrawPrincipal(amount, recipient) permits surplus withdrawals while a live commitment retains the protocol floor at a fresh accepted price. A withdrawal can reduce the owner's saved health buffer. Stale, frozen, importing, exported or forked live commitments expose no withdrawable surplus; once K is zero, principal can leave without a fresh price. Owners request retirement of their single position and must cancel pending retirement before authorizing commitment again. Partial retirement reduces K while the remaining live commitment keeps all owner principal behind it. Aggregate settlement releases capacity to retirement before new purchases, and each owner later claims their own release. Returning complete sets reduces aggregate demand immediately, making retirement possible without assigning question positions to individual owners. Complete exits can wait for outstanding liabilities to shrink.

Liquidation targets an unhealthy position. A cure removes unused commitment when aggregate spare capacity permits it; a partial cure can leave the position unhealthy. A takeover transfers commitment to a receiver that meets its chosen health target across its total principal and combined commitment. A receiver without a live position commits all idle principal, bounded by its explicit maximumOwnRep consent. An existing receiver can merge only within the same cohort; its existing principal plus the award must support the combined commitment. An owner already retiring cannot accept new active commitment. Liquidation awards and execution rewards come from the target's principal/reserve. Other owners retain their principal. A minimum progress size and proportional execution reserve prevent repeated dust actions from collecting full rewards. Credits are pulled by recipients, so a rejecting recipient cannot veto progress. A recovered position starts a fresh liquidation interval if it later becomes unhealthy. This applies to reauthorization, deposits into the live position, takeover receivers, rounding that repairs a partial takeover source, and oracle-only recovery. Price observations update healthy ranges lazily in the live index; same-block recovery is distinguished by an observation counter. Updates that leave a position unhealthy preserve its existing interval.

Questions and fees

The creator fixes an admission-policy contract exposing isQuestionAllowed(portfolio, universeId, questionId). The UI supports Open questions and a permanently Fixed question list. Custom contracts remain possible at the protocol layer. Policies are rechecked for purchases, including descendants; denial blocks new underwriting, not exits. Registering a question moves no capital and does not create work for every owner.

Creator-configured economics include the purchase percentage and minimum, annual fee rate, minimum commitment, minimum execution reserve, minimum outcome retention rate, and reward vesting duration. Every purchase pays the same backing-value-based fee rule, including reuse of available capacity. The buyer caps the fee and minimum shares, with unused ETH refunded. The annual rate is immutable for the portfolio, avoiding a temporary-capacity manipulation that discounted existing obligations.

Time fees use each question's actual calendar end and funded balance. Fork pauses never extend the event end or backcharge inactive periods. Old income is checkpointed before changes in price or eligible commitments. Fees are distributed to healthy commitments through indexed accounting; purchase fees and reporting income vest. New deposits and newly authorized commitments cannot claim already earned income.

Reporter stake is separate from provider principal. Irrevocable ordinary reporting surplus becomes vested REP income in a portfolio. In a standalone pool it increases existing backing, or burns if no backing owners exist. Ordinary final settlement reserves all winning liabilities and burns terminal residual without waiting for every reporter to claim.

Forks and recovery

One owner chooses one branch for their single live commitment position and all its principal. The fixed schedule is eight weeks for choices, one week for recapitalization, then one week for response before another child fork may begin. A shared branch migration moves capital once and initializes persistent accounting roots. Each chosen branch inherits the full live, unsettled nominal question liabilities and ETH collateral proportional to chosen REP divided by frozen REP; it can therefore need recapitalization.

Only unchosen REP is offered by the recapitalization auction. Buyers receive atomic price, quantity, own-collateral and commitment limits. Recapitalization uses the owner's existing principal, acquired REP and bounded extra wallet REP to meet the chosen health target for combined commitment; it cannot add active commitment to an owner already retiring. Chosen principal is excluded from recapitalization sales; it still backs commitments and remains subject to later liquidation. Each choice imports that owner’s single position and all its committed principal immediately. Activation finalizes shared capital and opens the child price feed. Already frozen final claims remain in their original settlement book. Native winning-share redemption and partial or full complete-set returns checkpoint these claims without attempting to reopen their fee stream; a later child cannot duplicate the source cash. Voluntary collateral repair is an explicit donation: it creates no principal claim, shares or repayment promise. Protocol-owned retained capital and maintenance income have separate accounting. A single retained-capital reserve waits behind both private retirement queues and supplies no capacity for new purchases. Partial releases preserve its earned fees; takeovers create ordinary private active positions. Released reserve principal and income remain collectible after a later fork, and released REP is burned.

Missing the choice deadline forfeits the committed principal's individual branch fallback. Idle parent REP and previously earned fees remain separately claimable. Actual native outcome-token migration still follows each intervening fork; the design does not pretend those token rights can skip history.

Native preparation creates child dependencies separately and installs one of the three outcome histories per transaction. Carry funding uses authenticated actual escrow after prior surplus routing and burns, not nominal historical principal. Frozen payout curves and claim checkpoints preserve split-independent payouts and prevent ancestor/descendant replay. Complete-set recovery has an independent right so recovering cash cannot consume child outcome-token rights.

Integration and gas

The SDK, Statoblast UI, simulation, Trading fee projection, scanner, event replay, Chaos bot, shared bot ABIs, deployment scripts, verification manifests and canonical HTML references consume the new interfaces. The branch also integrates main’s separate OpenOracle app and Yes/No genesis universes. Portfolio preferences are scoped by genesis REP address. Deployment validation covers all six network/genesis profiles and their generated runtime hashes; final results are recorded below. Portfolio deployment uses three resumable setup stages. Immutable deployment helpers and split creation-code stores keep runtime and init code within EVM limits. Imported compatibility contracts are unchanged.

Oracle exposure is the live maximum of total commitment and settlement demand. Price acceptance checkpoints mandatory accounting before accepting the price; optional question callbacks cannot undo that checkpoint. Queue pagination follows active cursors, and owner-specific lookups avoid scans of consumed history.

Required work does not loop over every question, owner, historical allocation or retirement cohort. Owner operations touch at most one live position, including retirement, fee claims and fork export/import. Commitment indexes take logarithmic work in live positions; timestamp and persistent maps use fixed-width keys. Native carry initialization is split into bounded transactions. Storage and full offchain enumeration still grow, and callers choose pagination sizes.

Measured adversarial scenarios with 768 owners and 128 question histories include native oracle settlement at 5,467,187 gas and the full owner claim with pending health observations at 3,449,622 gas. Maximum native carry preparation/outcome operations remain below the 16,777,216 transaction limit. These measurements are regression evidence, not a proof that every representable state fits every callback budget. Keeper profitability also depends on gas prices, configured reserves and REP value. The existing automated liquidator explicitly supports standalone pools only; portfolio cure/takeover transactions are permissionless and available through the SDK.

Review fixes

  • Owner health now compares all deposited principal against total commitment. The single-position model keeps fee eligibility, capacity, safe withdrawals, partial retirement, liquidation and fork accounting consistent. SDK and UI use the canonical collateral view; deposit and authorization reviews explain their exact principal consent.

  • Deposits are restricted to the depositing owner without changing the depositFor ABI, preventing third-party dust from invalidating a keeper's bounded all-principal takeover consent.

  • Finalized native winning-share redemption and partial/full complete-set returns now preserve the immutable final cash and fee record. Repeated refreshes and a later child fork cannot reopen the stream or duplicate source cash.

  • The single protocol-owned retained-capital reserve retires behind both private owner queues, cannot support fresh demand, and preserves fee ownership during partial release or takeover. Previously released principal remains collectible and burnable after another fork.

  • Deployment-status assertions follow canonical registry indices, OpenOracle's development import map includes both current shared modules, and the simulation test uses the current individual-capital description.

  • Production browser workflows use their workflow bootstrap budget. The long reporting/migration scenario alone gets a 900-second overall budget, based on a hosted timeout at 35/38 assertions and complete local runs taking 493–548 seconds. All transaction assertions and individual action timeouts remain unchanged; other workflows retain 600 seconds and smoke checks 120 seconds.

  • Dependency audits are repaired with exact overrides for follow-redirects 1.16.1 and Vite 8.3.3, including only their required lockfile updates. No new advisory exceptions were added.

  • Fork security tests now reach the intended pool authorization and child-lineage guards instead of passing on missing mock methods. Their original fund-conservation assertions remain. The liquidation preview fixture now uses consistent aggregate REP and separately tests the pool-wide withdrawal limit.

  • Initial loading, seeded navigation, and seeded-pool reads now share the selected bootstrap budget. Full navigation waits for the new document before accepting readiness; stale content cannot bypass the wait. Explicit bootstrap failures still reject immediately. Failure-first clock tests cover a 180-second bootstrap, stale documents, same-document navigation, and exact deadlines. Transaction-action waits and all outer budgets remain unchanged.

Validation and review

  • Final head: 8e3f2465b7b68c0969e5bbcbca357f8493165f78.
  • Final validation: Final compilation and full bun run tsc pass. The final ledger/auction/fork run passes 47 tests and 218 assertions, including 15 owner-collateral tests with failure-first reproductions. Commitment-index coverage passes 19 tests and 2,539 assertions; all 53 owning portfolio integration cases passed across bounded runs. Affected SDK/UI coverage passes 50 tests and 234 assertions, scanner ABI coverage 13 tests and 271 assertions, and source-policy coverage 10 tests and 40 assertions. bun run format:check, full bun run check, both bun run knip modes, and bun run check:generated-clean pass. Final working, staged and whole-PR git diff --check pass.
  • Scope-based skips: The current repair was traced through all owner-capital API consumers, portfolio integrations, ABI metadata and deterministic deployment boundaries. Unchanged standalone/trading behavior, bot business logic, external routing, and long browser runner workflows retain the prior complete 40-job CI evidence; those unrelated suites were not rerun locally for this bounded repair. Mutable live-mainnet/Uniswap checks are excluded because external routing is unchanged. Fresh portfolio browser QA covers the changed forms and transactions; tracked documentation screenshots depict unchanged standalone screens, so changed prose received separate desktop/mobile captures.
  • CapitalLedger runtime: 24,542 bytes, with 34 bytes below the unchanged 24,576-byte EIP-170 limit. All six network/genesis profiles deployed locally with code, initcode and Osaka gas limits enforced: 212 successful receipts and 120 descendant runtime-hash observations. Four canonical deployment manifests and creation-code pins match the rebuilt contracts; four runtime-validation tests pass. The source-maintenance allowance is ratcheted from 624 to 618 noncomment lines.
  • Final hosted CI: CI run 39794979371 has started for this head; results are pending. The prior CI evidence on 434d7925162d2544b8b1521dd2409846f09c7d3b predates this owner-collateral correction and is not evidence for the final head.
  • Final independent review: 89/100, no findings.
  • Documentation review: 95/100, no findings.
  • Visual review: 94/100, no findings.
  • Finding dispositions: The prior economic review identified third-party dust deposits invalidating keeper collateral consent. Owner-only deposits and two failure-first regressions fix it; a fresh economic review scores 93/100 with no findings. No findings are deferred.
  • Branch-current status: Fetched origin/main; zero commits behind 7948d75c9cc73f9c1161ca0baa2f8fb16608aaf9.

Completed scoped consumer validation for the owner-collateral change: 50 SDK/UI tests and 234 assertions, plus the production-contract SDK integration with six assertions. Scoped TypeScript, Biome and diff checks passed. The deterministic contract and shared API changes have failure-first regression evidence; the final audit regression and whole-change validation are recorded above.

Current Chromium QA uses the production contracts in the walletless portfolio scenario, which includes the securitypoolx2 seed. At 1440×900 and 390×844, the flow verified deposit, all-principal authorization, surplus withdrawal, retirement and cancellation, a stale-price failure after opening transaction review, branch choice/preparation/activation, child import, empty-owner rendering, and the exported-source reserve guard. A 3 REP deposit increased existing principal from 5,000 to 5,003; authorization to 11 ETH retained all that principal; a 1 REP withdrawal left 5,002. Partial retirement retained that principal, and the activated child imported all 5,002 REP into one position. Stale child collateral exposed zero withdrawal allowance. No console/runtime errors or horizontal overflow occurred in these states. Recap purchase was not executed in this scenario because all owner principal chose the branch, leaving no sale inventory; aggregate recap quote behavior is covered by SDK and contract tests.

UI evidence

Current Chromium captures from the real browser-local EVM simulation. Desktop 1440×900; mobile 390×844. The capital summary shows aggregate principal and canonical withdrawable surplus. Authorization explicitly reviews the total commitment, all deposited principal and the saved health target.

Desktop owner principal and withdrawable surplus

Mobile owner principal and withdrawable surplus

Desktop authorization review using all deposited principal

Mobile authorization review using all deposited principal

@KillariDev KillariDev changed the title Add multi-question security pools and automatic REP allocation Share REP backing across questions and preserve independent fork recovery Oct 15, 2026
@KillariDev KillariDev changed the title Share REP backing across questions and preserve independent fork recovery Share REP reserves across questions with lazy ownership and recovery Oct 16, 2026
@KillariDev
KillariDev marked this pull request as draft October 18, 2026 01:57
@KillariDev
KillariDev marked this pull request as ready for review October 18, 2026 14:02
@KillariDev KillariDev changed the title Share REP reserves across questions with lazy ownership and recovery Share REP reserves across questions with configurable policies and lazy recovery Oct 19, 2026
@KillariDev KillariDev changed the title Share REP reserves across questions with configurable policies and lazy recovery Share security capacity across questions with individual principal and lazy settlement Oct 20, 2026

This branch has not been deployed

No deployments
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