> ## Documentation Index
> Fetch the complete documentation index at: https://docs.robin.markets/llms.txt
> Use this file to discover all available pages before exploring further.

# Withdrawing (unstaking)

> Burn vault shares to get your Polymarket tokens and organic yield back, via batchWithdraw — works the same for both wallet kinds.

A single `batchWithdraw` call burns your vault shares and returns the underlying Polymarket outcome tokens plus the organic yield those shares accrued. It works identically for both Polymarket wallet kinds.

## `batchWithdraw`

```solidity theme={null}
function batchWithdraw(
    bytes32[] conditionIds,
    uint256[] yesShares,
    uint256[] noShares,
    address yieldRecipient,
    uint256 nonZeroLength,
    uint256 referralCode,
    bool wrapYieldToPolyUsd
) external;
```

The vault burns the supplied shares and returns the corresponding outcome tokens (loss-adjusted) plus the pending organic USDC.e yield in one transaction.

| Param                | Type        | Notes                                                                                                                                       |
| -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `conditionIds`       | `bytes32[]` | Markets to withdraw from. Must be sorted strictly ascending with no duplicates.                                                             |
| `yesShares`          | `uint256[]` | YES shares to burn per market (6-decimal integers). Aligned to `conditionIds`.                                                              |
| `noShares`           | `uint256[]` | NO shares to burn per market. Aligned to `conditionIds`.                                                                                    |
| `yieldRecipient`     | `address`   | Recipient of the organic yield. Pass `address(0)` to default to `msg.sender`.                                                               |
| `nonZeroLength`      | `uint256`   | Count of non-zero entries across `yesShares` + `noShares`.                                                                                  |
| `referralCode`       | `uint256`   | `0` if none.                                                                                                                                |
| `wrapYieldToPolyUsd` | `bool`      | `true` wraps the USDC.e yield to PolyUSD via Polymarket's `CollateralOnramp`; falls back to USDC.e if the wrap fails. `false` keeps USDC.e. |

<Warning>
  `conditionIds` must be sorted strictly ascending with no duplicates, and
  `yesShares` / `noShares` must use the same permutation. This is the same
  ordering rule as [deposits](/developers/deposits). A wrong order reverts.
</Warning>

A side may be zero (withdraw only YES or only NO), but each row must burn at least one share. The `Side` enum is `YES=0, NO=1`.

## Getting share balances

Read the shares you can burn — and what they are currently worth in outcome tokens — from `RobinLens.batchGetUserSharesAndAssets`. The `yesAssets` / `noAssets` are loss-adjusted token amounts, so they reflect any impermanent loss already booked against the position.

```solidity theme={null}
function batchGetUserSharesAndAssets(address user, bytes32[] conditionIds)
    external
    view
    returns (
        uint256[] yesShares,
        uint256[] noShares,
        uint256[] yesAssets,
        uint256[] noAssets
    );
```

<Tip>
  Prefer HTTP? The Integration API `GET /v1/positions?wallet=…` returns the same
  per-market shares (plus live yield and APY) as 6-decimal integer strings, with
  no on-chain call. Use the resolved staking wallet, not the EOA.
</Tip>

All amounts are 6-decimal fixed-point integers (`UNDERLYING_DECIMALS=6`). See [Reading on-chain state](/developers/reading-onchain-state) for the full `RobinLens` surface.

## TWAP first

<Note>
  The vault rejects a withdrawal for a market whose TWAP is not fresh, because
  the TWAP determines how yield is split between the YES and NO sides. Refresh
  the relevant markets and, when needed, prepend
  `RobinTwapOracle.submitTwap(...)` to the same batch as `batchWithdraw`. See
  [Keeping TWAP fresh](/developers/twap).
</Note>

## Bonus payout is separate

<Note>
  The on-chain `batchWithdraw` returns only the **organic yield** (paid via the
  vault's `lossIndex` + `yieldPerShare` accounting). The yield guarantee,
  matching bonus, and Robin Points are an off-chain programme: Robin computes
  them at withdrawal and sends them in a **separate** USDC transaction from its
  operator wallet shortly after. Your withdraw transaction will not contain that
  bonus — do not expect it in the `Withdrawn` event or the returned `yield`.
</Note>

The emitted `Withdrawn(...)` event carries a `protocolFee` — Robin may take a protocol fee on the organic yield only, never on principal.

## Transport

`batchWithdraw` is identical for both wallet kinds; only how you submit it differs. Resolve the wallet once and submit through its transport.

<Steps>
  <Step title="Resolve the wallet">
    Determine whether the user's Polymarket account is a `DepositWallet` or a
    legacy Gnosis Safe proxy, and key all reads and writes on that resolved
    address. See [Wallets](/developers/wallets).
  </Step>

  <Step title="Build the batch">
    Sort by `conditionId`, then assemble the call array — optionally
    `submitTwap` first, then `batchWithdraw`.
  </Step>

  <Step title="Submit through the wallet's transport">
    **Safe proxy** → `Safe.execTransaction`. **DepositWallet** → the Polymarket
    relayer. Unlike deposits, there is no pull/push distinction for withdrawals
    — the vault already holds the shares.
  </Step>
</Steps>

The runnable `withdraw.ts` in the integration example repo wires all of this together — wallet resolution, TWAP refresh, the multi-market batch, and transport dispatch.

## Next steps

<CardGroup cols={2}>
  <Card title="Reading on-chain state" icon="magnifying-glass" href="/developers/reading-onchain-state">
    Read shares, assets, and pending yield from `RobinLens`.
  </Card>

  <Card title="Keeping TWAP fresh" icon="clock" href="/developers/twap">
    Refresh a market's TWAP before withdrawing.
  </Card>
</CardGroup>
