Skip to content

Take your money out without us

The vault holds your cash on chain. It pays that cash only to the wallet linked to your account. You can ask it for the cash yourself, with two transactions and no help from us. Use this guide if our exchange or our site is unavailable and you want your money out. If Privy is down, you need a key you exported earlier.

The exit takes about an hour. Most of that time is a wait that the vault enforces. You can do it whether or not the exchange is running.

  • The key of your linked wallet. If you signed up with a wallet, you have it already. If you signed up with an email, your wallet is a Privy wallet. Export its key from the app: Settings, then Wallet, then Export wallet key. If our site is down but Privy works, use Privy Home. Sign in with the same email, find your wallet, and export its key. Privy’s guide has the steps. If Privy is down, you need a key you exported earlier.
  • A little Base Sepolia ETH in that wallet, to pay for gas. Each transaction costs under 0.000001 ETH, so one faucet claim of 0.0001 ETH covers both. The Coinbase Developer Platform faucet (portal.cdp.coinbase.com/products/faucet) gives 0.0001 Base Sepolia ETH a claim, free with a CDP account.
  • The vault address: 0x11B14DFeb20Cf4F3960799d84fe8147b686097C3, on Base Sepolia (chain ID 84532).
  • Your account id. In the app, open Settings. The id is the Account number. The app shows your cash as Cash in the vault. Note it before you need it. If you cannot open the app, see Find your account id without the app.

Do not share your wallet key. Anyone who has it can take your funds.

Check three values before you send anything. The vault’s page on Blockscout shows them on the Read/Write contract tab: https://base-sepolia.blockscout.com/address/0x11B14DFeb20Cf4F3960799d84fe8147b686097C3

Function Argument What it returns
walletOf Your account id. The wallet linked to your account. It must be the wallet you hold the key for.
cashOf Your account id. Your cash in the vault, in USDC base units.
exitDelaySeconds None. The wait before you can complete a withdrawal, in seconds. It is 3600 on testnet.

One wallet can be linked to several ids. Check cashOf for each id that returns yours.

The vault pays only cash. Your positions in markets are not cash. See Positions.

USDC has 6 decimals. Every amount in a vault call is a whole number of base units, with no decimal point. 1 USDC is 1000000. To withdraw 25 USDC, send 25000000.

  1. Open the vault’s Read/Write contract tab, showing its write methods: https://base-sepolia.blockscout.com/address/0x11B14DFeb20Cf4F3960799d84fe8147b686097C3
  2. Import your wallet key into a wallet such as MetaMask. If Base Sepolia is not in its network list, add it: RPC URL https://sepolia.base.org, chain ID 84532, currency ETH.
  3. Select Connect your wallet on the page, and choose that wallet.
  4. Open requestTimedWithdrawal. Enter your account id and the amount in base units. Select Write, and confirm in your wallet.
  5. Open the transaction. In its logs, find TimedWithdrawalRequested. Its availableAtSeconds is the Unix time at which you can complete the withdrawal.
  6. Wait until that time. It is the time of your request plus the exit delay.
  7. Open completeTimedWithdrawal. Enter your account id. Select Write, and confirm in your wallet.

The vault sends the USDC to your wallet in the same transaction.

You need Foundry’s cast. Set the three values first. Read your key without printing it:

Terminal window
export RPC_URL=https://sepolia.base.org
export VAULT=0x11B14DFeb20Cf4F3960799d84fe8147b686097C3
export ACCOUNT_ID=2
read -rs PRIVATE_KEY && export PRIVATE_KEY

Read the delay and your cash:

Terminal window
cast call $VAULT "exitDelaySeconds()(uint256)" --rpc-url $RPC_URL
cast call $VAULT "cashOf(uint64)(uint256)" $ACCOUNT_ID --rpc-url $RPC_URL

Request the withdrawal. This example asks for 25 USDC:

Terminal window
cast send $VAULT "requestTimedWithdrawal(uint64,uint256)" $ACCOUNT_ID 25000000 \
--private-key "$PRIVATE_KEY" --rpc-url $RPC_URL

Wait for the exit delay. Then complete it:

Terminal window
cast send $VAULT "completeTimedWithdrawal(uint64)" $ACCOUNT_ID \
--private-key "$PRIVATE_KEY" --rpc-url $RPC_URL
  • requestTimedWithdrawal(accountId, amount) records the request. The amount is the most you want. The vault checks that you are the linked wallet.
  • completeTimedWithdrawal(accountId) pays the wallet that calls it. It pays the amount you asked for, or all your cash if you have less by then.
  • Only one request can be pending for an account at a time.
  • A fill dated 60 seconds or more after the request is skipped if it would take your cash below the amount you asked for. The vault reserves that cash until you complete or cancel.
  • The exit does not need the exchange. A pause by the vault’s admin does not stop it.

A failed call reverts with one of these errors.

Error Cause What to do
TimedWithdrawalNotReady The delay has not passed. The error carries the Unix time you can complete at. Wait until that time, then send the call again.
NotTheLinkedWallet The calling wallet is not the one linked to the account id. Check walletOf. Use that wallet’s key and your own account id.
TimedWithdrawalPending The account already has a pending request. Complete it, or cancel it. See below.
NoTimedWithdrawal The account has no pending request. Send requestTimedWithdrawal first.
ZeroAmount The amount is 0. Send an amount above 0.

If your cash is below the requested amount when you complete, the vault pays all your cash. It does not revert. You can request again for any cash that arrives later, such as a position that you redeem after the request.

To stop a pending withdrawal, call cancelTimedWithdrawal(accountId) from the linked wallet. Then you can send a new request with a different amount. The vault reserves no cash after you cancel.

Terminal window
cast send $VAULT "cancelTimedWithdrawal(uint64)" $ACCOUNT_ID \
--private-key "$PRIVATE_KEY" --rpc-url $RPC_URL

When the exchange pays a withdrawal that the vault cannot push to your wallet, the vault keeps the amount for the wallet. This is not part of the timed exit. Read unpaidTo with your wallet address. If it is above 0, call claimUnpaid() from that wallet. It takes no arguments and pays the whole amount.

Terminal window
cast call $VAULT "unpaidTo(address)(uint256)" <your wallet> --rpc-url $RPC_URL
cast send $VAULT "claimUnpaid()" --private-key "$PRIVATE_KEY" --rpc-url $RPC_URL

If you have nothing to claim, the call reverts with NothingToClaim.

The vault pays cash only. A position in a market that has not paid out is not cash. Two calls turn a position into cash, and anyone can send both:

  1. Resolve the market, if it has no outcome yet: resolveMarket(marketId).
  2. Redeem your position: redeem(marketId, [accountId]). It pays the position into your cash. A winning lot pays 10,000 base units. A lot in a void market pays 5,000. See A void market.

If a market has no outcome, redeem reverts with MarketNotResolved. Resolve it first. Then request your withdrawal.

A market resolves once the exchange has posted its fills, or from 6 hours after its end if the exchange is down. If the vault lacks its start or end price, anyone can resolve it as void from 24 hours after its end. resolveMarket can revert with ResolutionNotOpen, PricesMissing or VoidNotOpen. Each means a time has not come yet. Try again later.

In cast, pass the account ids as a list:

Terminal window
cast send $VAULT "resolveMarket(uint64)" <market id> \
--private-key "$PRIVATE_KEY" --rpc-url $RPC_URL
cast send $VAULT "redeem(uint64,uint64[])" <market id> "[$ACCOUNT_ID]" \
--private-key "$PRIVATE_KEY" --rpc-url $RPC_URL

To find your markets, read the vault’s FillApplied events. Look for your account id as takerAccountId or makerAccountId. The market id is the indexed marketId. positionOf(accountId, marketId) shows the position. A positive number is Up lots and a negative number is Down lots.

The vault records which wallet each account id is linked to, and walletOf(accountId) returns it. Account ids count up from 1. Check each id until you find the one that returns your wallet:

Terminal window
for id in $(seq 1 50); do
echo "$id $(cast call $VAULT 'walletOf(uint64)(address)' $id --rpc-url $RPC_URL)"
done

An id that no wallet is linked to returns 0x0000000000000000000000000000000000000000. Raise the range if your wallet is not in the first 50.