Position Entry Flow¶
Trigger: Operator identifies a suitable prediction market and is ready to deploy idle capital. Caller: Governance (operator)
Pre-Conditions¶
Before calling openPosition(), the operator must verify all market selection criteria off-chain:
- Market has ≥ 30 days to resolution and ≤ 120 days
- Expected entry price is in the \(0.88–\)0.95 range
- NO side liquidity depth is ≥ 5× intended position size within 2% of current price
- Position will not exceed 10% of NO-side open interest
- Position is uncorrelated with other active vault positions
Steps¶
-
Operator identifies market meeting all selection criteria.
-
Operator deploys
MarketAdaptercontract pointed at the venue and specific market. - Set
vault = vaultAddress(immutable, vault-authorized calls only) - Set
marketIdto the target market identifier -
Verify adapter is functional:
adapter.currentPrice()returns a reasonable value -
Operator calls
vault.openPosition(slotIndex, adapterAddress, assets, maturity). -
Vault validates (on-chain):
positions[slotIndex].status == EMPTYassets <= idleReserve - (aggMarketNAV * reserveTargetBps / 10000)— reserve constraint usesaggMarketNAVas TVL basisadapteris a valid non-zero contract address-
maturity > block.timestamp -
Vault calls
(sharesAcquired, executionPrice) = adapter.buyNoShares(assets). Adapter acquires NO shares on the venue and returns both the shares acquired and the weighted average execution price as a named tuple. -
Vault assigns
position.entryPrice = executionPrice. The operator never supplies this value — it comes directly from the adapter's execution. -
Vault records position in registry:
-
PositionOpened(slot, adapter, assets, entryPrice, maturity)emitted. -
Position begins accruing in modeled NAV immediately from
executionPrice.
Slippage Control¶
Maximum recommended entry slippage: 50 bps (0.5%). The adapter must revert if execution would exceed the slippage tolerance. The operator should then either:
- Reduce the position size
- Wait for better market conditions
Entry price is automatic
Because entryPrice is sourced from adapter.buyNoShares() — not supplied by the operator — there is no risk of an incorrectly stated entry price. Verify the SharesPurchased event on the adapter to confirm the execution price matches position.entryPrice.