Skip to main content
This guide deposits an eligible token, such as WETH (wrap native ETH first), on-chain as perp collateral. The token isn’t converted to USDG. For how token collateral and the automatic USDG loan work, see Multi-Asset Collateral. For runnable Python covering the deposit and everything after it, see Use Multi-Asset Collateral.
This moves real funds on mainnet. Send a small test deposit first and confirm it is credited (see Step 5) before you send more.
What this guide covers. Depositing WETH (wrap native ETH first) or a Stock Token to the BridgeVault on mainnet or testnet. The steps are the same for both; only native ETH needs wrapping first. Check that the vault accepts a token (step 3) before depositing it. There is no on-chain USDG deposit path documented for mainnet: deposit USDG through the app. On testnet, to deposit USDG on-chain, see Fund a testnet account.

Deposit contract addresses can change

Arcus deposit contract addresses can change. Read them from the docs and the API before every deposit. Never hard-code an address, and never reuse one you saved earlier or copied from somewhere else. A deposit sent to an old or wrong address may not be credited to your account.
  • Deposit contract (BridgeVault): the verifyingContract for your environment in the per-environment chainId / verifyingContract table on POST /v1/withdraw.
  • Token contract: contractId for the asset on GET /v1/spotAssets. This is the token you send, not the deposit contract.
  • Chain ID: the chainId in the same POST /v1/withdraw table, also listed under Environments. Check that your wallet or RPC is on that chain.

Before you start

  • The token on Robinhood Chain, plus a little native ETH for gas. Buy tokens on Arcus spot.
  • A subaccount to deposit into (accountIndex). You don’t need an API key or an order first.

Step 1: Read the current addresses

Read the BridgeVault address, chain ID and token contractId as described in Deposit contract addresses can change. Do this for every deposit.

Step 2: Hold the exact token

Use the token at contractId on GET /v1/spotAssets. Any other token for the same asset isn’t credited. For ETH that is WETH on Robinhood Chain. Native ETH isn’t accepted, so wrap it first by calling deposit() on the WETH contract.

Step 3: Check the vault accepts the token

Call the BridgeVault’s depositConfig(token) view. It returns (allowed, minAmount):
  • allowed must be true. An asset can appear on GET /v1/spotAssets before the vault accepts it.
  • Your amount must be at least minAmount, in the token’s smallest unit. Minimums are set per token and can change, so read it before each deposit.

Step 4: Approve and deposit

  1. Approve the BridgeVault to pull the amount from your wallet (approve(BridgeVault, amount) on the token). Token deposits go to the BridgeVault directly, not through a USDG deposit proxy.
  2. Call initiateDeposit(owner, accountIndex, token, amount) on the BridgeVault. owner must be the wallet that sends the transaction, and amount is in the token’s smallest unit (read the token’s decimals()). Keep the returned inboxIndex; it is also emitted in the DepositInitiated event, and you need it to reclaim a deposit that is never credited.
Size the amount in whole multiples of the asset’s stepSize so you can withdraw the full credited size later. Step 2 of Use Multi-Asset Collateral has the code.

Step 5: Confirm the credit

Arcus credits the token after the transaction is picked up from the chain.
  • Poll GET /v1/accountTransferUpdates (or the accountTransferUpdates channel) for the DEPOSIT row. It carries spotAssetId and the size in token units as amount, and ends APPLIED once the token is credited, or with a REJECTED_* status if Arcus refused it.
  • Read GET /v1/account. The token shows in spotPositions, your USDG balance is unchanged, and borrowHeadroom rises by about the token’s value × ltvInitial. There is no separate “enable as collateral” step.
  • A credited deposit to a subaccount you have never used activates it: GET /v1/account for that accountIndex goes from 404 to 200. A rejected deposit doesn’t.
Step 3 of Use Multi-Asset Collateral has the polling code and an example response.

If a deposit fails

A token deposit has two steps. You send it on-chain, and then Arcus credits it to your account. Either step can fail:

Reclaiming a deposit

A token that isn’t credited stays held by the BridgeVault, not lost. To reclaim it, first read BridgeVault.pendingDepositByIndex(index). It returns the pending deposit’s record:
  • amount: non-zero while the deposit is still reclaimable; 0 once it has been credited or refunded.
  • expiresAt: cancelDeposit succeeds only after this time. A rejected deposit is expired early, so its expiresAt has already passed.
  • cancelRecipient: the address that receives the refund, and the only address that can call cancelDeposit for a deposit made with initiateDeposit. For a token you deposited with initiateDeposit on the BridgeVault, it is your wallet.
Then call cancelDeposit(index) on the BridgeVault from that wallet. The tokens go back to the wallet, and pendingDepositByIndex(index) returns an amount of 0. Calling cancelDeposit again reverts with PendingDepositNotFound. A deposit routed through a deposit proxy is cancelled through that proxy instead. Which index to use:
  • Rejected deposit (a REJECTED_* row): rootchainQueueIndex from the rejected row. It is the same number as the deposit’s inboxIndex. You can reclaim it right away.
  • Never-credited deposit (no row): the inboxIndex from step 4. Reclaim it once expiresAt has passed.

Next steps