Deposits & Withdrawals
How it works
A deposit lands in the user account's spot balances, and every balance in one subaccount backs every position in that same subaccount. That is what cross-margin means here: deposits collateralize perp positions, and an account can borrow against them to take on leverage.
Balances carry interest in both directions. A deposit earns from borrowers; a borrow accrues a charge. Each balance is stored at the token mint's own decimals, so 1e6 for the quote asset and 1e9 for SOL, and is signed: positive is a deposit, negative is a borrow. Total collateral is the sum of deposits after asset weighting, minus borrows and unrealized perp losses.
Withdrawals need free collateral. Collateral backing an open position is not available to withdraw, and a withdrawal cannot take the account below its margin requirement. Margin is not the only gate, though.
A withdrawal also fails if the exchange or the market has withdrawals paused, or if the spot market's daily withdraw circuit breaker has tripped. That breaker caps how far a market's deposits can fall below their 24-hour TWAP; the cap is a per-market setting, so read it off the spot market account. Treat all three as separate error cases: free collateral alone does not predict success.
Spot markets on Velocity are collateral and borrow-lend only, with no order-book trading (see Orders). Deposits, withdrawals, and internal transfers are unaffected by that change. The SDK derives the token accounts and does the precision conversion.
SDK Usage
Deposits and withdrawals move tokens between the wallet's token accounts and the Velocity subaccount's spot position. Both take an amount in the market's own precision and the wallet's associated token account for that mint, so every flow starts with the same two calls.
Converting amounts and deriving the token account
convertToSpotPrecision scales a human-readable amount by the market's token decimals. It is per market, not a fixed constant: see Precision and Types.
// Spot market 0 is the quote asset: dUSDT on devnet, USDT on mainnet-beta.
const marketIndex = 0;
const amount = velocityClient.convertToSpotPrecision(marketIndex, 100); // 100 tokensGet the wallet's associated token account for a given spot market mint.
const marketIndex = 0;
const ata = await velocityClient.getAssociatedTokenAccount(marketIndex);
console.log(ata.toBase58());Deposit
Deposit tokens from the wallet ATA into the Velocity subaccount's spot balance.
const marketIndex = 0;
const amount = velocityClient.convertToSpotPrecision(marketIndex, 100);
const associatedTokenAccount = await velocityClient.getAssociatedTokenAccount(marketIndex);
await velocityClient.deposit(amount, marketIndex, associatedTokenAccount);Withdraw
Withdraw tokens from the subaccount's Velocity spot balance back to the wallet ATA (subject to free collateral checks).
const marketIndex = 0;
const amount = velocityClient.convertToSpotPrecision(marketIndex, 100);
const associatedTokenAccount = await velocityClient.getAssociatedTokenAccount(marketIndex);
await velocityClient.withdraw(amount, marketIndex, associatedTokenAccount);Spot rates (borrow and lend)
Both rates read off the spot market account and return an annualized rate as a BN in SPOT_MARKET_RATE_PRECISION (1e6), so 109500 is 10.95% annualized. calculateDepositRate is what depositors receive; calculateBorrowRate is what borrowers pay. The deposit rate is the borrow rate net of the insurance-fund and protocol fee carveouts, scaled down by utilization, since only the borrowed share of deposits earns anything.
Both also take an optional delta, a hypothetical change in token amount, so a deposit or borrow can be priced against the rate before it is sent.
import { SPOT_MARKET_RATE_PRECISION, calculateDepositRate, convertToNumber } from "@velocity-exchange/sdk";
const spotMarket = velocityClient.getSpotMarketAccount(0);
const rate = calculateDepositRate(spotMarket);
// 0.1095 means 10.95% annualized
console.log(convertToNumber(rate, SPOT_MARKET_RATE_PRECISION));import { SPOT_MARKET_RATE_PRECISION, calculateBorrowRate, convertToNumber } from "@velocity-exchange/sdk";
const spotMarket = velocityClient.getSpotMarketAccount(0);
const rate = calculateBorrowRate(spotMarket);
// 0.1420 means 14.20% annualized
console.log(convertToNumber(rate, SPOT_MARKET_RATE_PRECISION));