RobinTwapOracle holds a time-weighted average YES price for every market. The vault reads it to split organic yield between the YES and NO sides, and refuses a deposit or withdrawal when the market’s TWAP is stale. Before you call batchDeposit, the push-deposit safeBatchTransferFrom, or batchWithdraw, fetch a signed update from Robin and prepend submitTwap to the same batch when one is needed.
Why TWAP
A market’s outcome tokens (YES and NO) earn yield as one pooled USDC position, but each side accrues at a different rate. The oracle’s time-weighted YES price is the split point. It determines how much of the pool’s yield belongs to YES holders versus NO holders. The vault enforces freshness per market. If the stored TWAP is stale, a deposit or withdrawal for that market reverts until a fresh value is submitted. You never compute this price yourself: Robin’s backend computes it from Polymarket trade data and returns it signed.The TWAP payload is signed by a Robin operator key. This signer is migrating to an Oasis ROFL TEE, but the HTTP request and response shapes documented here stay the same — no integration changes are required.
Fetch a signed update
Request the update from the Integration API atPOST /api/v1/twap — open CORS, no auth, rate-limited per IP like the rest of /api/v1. Pass the conditionIds (up to 25, unique) for every market in your upcoming batch.
submitTwap entirely.
TwapData-shaped market entries plus a signature. Prepend submitTwap({ markets, signature }) to your batch (see Submit it).
All amounts and prices are 6-decimal integer strings.
twapPriceYes is scaled by PRICE_SCALE (1e6), so 1000000 is 100%.Submit it
When you get Mode B, prepend a singleRobinTwapOracle.submitTwap call to your deposit or withdrawal batch — the oracle refresh and the vault action then land atomically in the same Safe or relayer transaction.
Short-circuit
You can skipsubmitTwap even in Mode B when no market actually needs an update.
fetchTwap helper folds all of this into one call: it returns null for Mode A and for the short-circuit case, and otherwise returns { markets, signature } with every field already coerced to bigint. Your batch builder then conditionally prepends submitTwap only when the helper returns non-null. See fetchTwap in src/shared.ts of the robin-markets-integration example repo, used by both deposit flows and the withdrawal flow.
Next steps
Deposits
Build the pull or push deposit batch that the TWAP update goes in front of.
Withdrawals
Burn shares and claim organic yield, with the same fresh-TWAP requirement.