Skip to main content
Staking deposits Polymarket conditional tokens (YES/NO outcome tokens) into RobinStakingVault, which pairs and merges them to USDC, deposits that USDC into a yield strategy, and mints you ERC-1155 shares (one share token per market per side). There are two ways to deposit, and which one you use depends on the kind of Polymarket account you hold. Tokens live in the user’s resolved Polymarket account (a DepositWallet or a legacy Gnosis Safe proxy), not their EOA. Resolve the wallet once and key every read and write on it — see Wallets. DepositWallets submit through the Polymarket relayer, which blocks approve, so they are restricted to the push path; Safe proxies submit through Safe.execTransaction and can use either.

Sorting rule

In every batch call, conditionIds must be sorted strictly ascending with no duplicates, or the call reverts with UnsortedConditionIds. All other batch arrays (questionIds, yesAmounts, noAmounts, and the push ids/values) must use that same permutation so each index lines up with its market.

Pull deposit (Safe proxy only)

The pull path is three calls wrapped in a single Safe.execTransaction batch: grant the vault approval on ConditionalTokens, let it pull and process your tokens via batchDeposit, then revoke the approval in the same transaction so no standing allowance is left behind.
1

Approve the vault

ConditionalTokens.setApprovalForAll(vault, true).
2

Deposit

RobinStakingVault.batchDeposit(...) — the vault pulls the outcome tokens, pairs and merges them, deposits to yield startegies, and mints shares.
3

Deposit

RobinStakingVault.batchDeposit(...) — the vault pulls the outcome tokens, pairs and merges them, deposits to the yield strategy, and mints shares.
4

Revoke

ConditionalTokens.setApprovalForAll(vault, false).
DepositWallets cannot use the pull path — the Polymarket relayer blocks approve calls to the CTF. Use the push path below instead.
The batchDeposit signature:
See deposit.ts in the robin-markets-integration example repo for the full Safe batch, including the TWAP prepend.

Push deposit (both wallet kinds)

The push path is a single ConditionalTokens.safeBatchTransferFrom(wallet, vault, ids, values, data) into the vault. The vault’s onERC1155BatchReceived hook decodes data and runs the entire deposit pipeline atomically — no approval, no standing allowance, one vault-side call. This is the only path a DepositWallet can use, and it works for Safe proxies too. The data argument carries exactly the same payload as batchDeposit:

Building ids and values

ids and values are dense and sorted. Iterate markets in ascending conditionId; for each market, push the YES side first (if yesAmount > 0), then the NO side (if noAmount > 0), skipping zero sides. ids.length must equal nonZeroLength.
  • ids are the on-chain ERC-1155 token ids — the YES/NO positionIds. Polymarket’s /positions data API returns the held side as asset and the unheld side as oppositeAsset.
  • The vault rebuilds its own (ids, values) from its cached positionIds and reverts PushDepositMismatch if yours do not match, or UnsolicitedTransfer if the transfer is not from the CTF or data fails to decode.
See deposit-push.ts in the example repo for the end-to-end flow, including wallet resolution and relayer submission.

TWAP first

Each market’s TWAP must be fresh before the vault accepts a deposit for it — the TWAP determines how yield is split between the YES and NO sides. Prepend a RobinTwapOracle.submitTwap(...) call to your batch (or skip it if Robin already submitted on-chain). See TWAP for the refresh flow.

Capacity

The vault has a finite, two-tier deposit capacity (it’s global, not per-market), and an over-capacity batchDeposit reverts. Preview a batch before submitting — over HTTP with GET /api/v1/capacity, or on-chain with RobinLens.checkBatchDepositCapacity, which checks both tiers:
Tier 1 reverts CapacityExceeded, tier 2 reverts SupplyOverflow. See Capacity for the tiers, the API, and reading the raw headroom.

Errors

Next steps

Withdrawing

Burn shares to redeem outcome tokens plus organic yield.

TWAP refresh

Keep a market’s TWAP fresh before depositing.

Wallets

Resolve the user’s Polymarket account and pick the transport.