Migrating from Drift
Velocity Protocol is a fork of Drift Protocol v2, taken at Drift SDK v2.163.0-beta.0. It is not an upgrade of Drift in place. It is an entirely new onchain program deployment with a new program ID, a reduced feature set, and its own renamed SDK. The Drift program is paused, and no onchain state carries over: user accounts must be re-initialized and balances start fresh on Velocity.
Because the program ID changed, every PDA address is different from Drift: even for the accounts whose seeds are byte-for-byte unchanged (user, user_stats, perp_market, spot_market, spot_market_vault, insurance_fund_vault). One trading seed was also renamed: the State PDA seed went from drift_state to velocity_state. Never reuse a Drift-derived address on Velocity.
At a glance
| Drift | Velocity | |
|---|---|---|
| Program ID | dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH | vELoC1audYbSYVRXn1vPaV8Axoa9oU6BYmNGZZBDZ1P |
| npm package | @drift-labs/sdk (2.163.0-beta.0) | @velocity-exchange/sdk (0.20.0) |
| Client class | DriftClient | VelocityClient (no back-compat alias) |
| Anchor | @coral-xyz/anchor@0.29.0 | @anchor-lang/core@1.0.1 (aliased as @coral-xyz/anchor) |
| IDL file | drift.json | velocity.json |
| Mainnet quote asset | USDC | USDT |
| Data API host | data.api.drift.trade | data.velocity.exchange |
This page covers the TypeScript SDK at @velocity-exchange/sdk 0.20.0. Rust (velocity-rs) and raw-ABI integrators need the full layout-and-ABI reference as well, which lives in the velocity-v1 monorepo. That repository is not public; ask the team for the document.
Quote asset is now USDT
This is the single most money-relevant change. On Drift, spot market 0 (the cross-margin quote and collateral asset) is USDC. On Velocity mainnet-beta it is USDT.
| Network | Quote mint |
|---|---|
| Drift mainnet (USDC) | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| Velocity mainnet-beta (USDT) | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
| Velocity devnet (dUSDT placeholder) | GqmEqYsy8EyvofDpmtFxK8zhYrgWgNokAtYoduQdL7v6 |
Both are 6-decimal SPL tokens, so notional amounts look identical and nothing type-checks differently. A desk that funds accounts with USDC, as it did on Drift, is depositing the wrong token: deposits, withdrawals, ATA derivation, collateral, and settlement all reference the USDT mint.
Switch every quote-mint hardcode and associated token account to USDT on mainnet, and to dUSDT on devnet. Never assume QUOTE_MINT_ADDRESS == USDC. The reliable fix is to stop hardcoding the mint at all and read getConfig().QUOTE_MINT_ADDRESS; see Setup for the config accessor.
Removed features
Several Drift subsystems were dropped. Their SDK exports are gone (no back-compat), and their onchain error variants are preserved only as deprecated, code-stable stubs.
| Feature | What changed |
|---|---|
| Spot DLOB trading | place_spot_order, place_and_take_spot_order, place_and_make_spot_order, fill_spot_order are removed. Spot markets still exist (for collateral and borrow-lend) but placing orders on a spot book is not possible. Attempting it returns SpotDlobTradingDisabled (6350). |
| External spot fulfillment | Serum, Phoenix, and OpenBook fulfillment are gone. The serum/*, phoenix/*, openbook/* subscribers and fulfillment-config maps, and the SERUM_V3 / PHOENIX / OPENBOOK env config fields, are removed. |
| Fuel | The math/fuel module and the FuelSeasonRecord / FuelSweepRecord event types are removed. |
| vAMM LP (BAMM) shares | LP provisioning on the vAMM is gone: PerpPosition.lp_shares and the LPRecord / LPAction types are removed. |
| Protected maker mode | The four protected-maker instructions, the ProtectedMakerModeConfig account type, and VelocityClient.updateUserProtectedMakerOrders are removed. |
| High leverage mode | The five HLM instructions and their config-account subscribers are removed. The onchain MarginMode enum and the User.marginMode field are gone. (The TS MarginMode class still exists in the SDK, reduced to DEFAULT only, so imports don't break.) |
| Prediction markets | initialize_prediction_market is removed; ContractType.PREDICTION is now DEPRECATED_PREDICTION. |
| Legacy Pyth pull/push | The legacy Pyth pull/push instructions are removed, along with oracles/pythPullClient and util/pythOracleUtils. Pyth Lazer is the supported Pyth path. The PythSolanaReceiver and WormholeCoreBridgeSolana root exports are also gone. |
| Switchboard oracles | oracles/switchboardClient and oracles/switchboardOnDemandClient are removed; the OracleSource Switchboard variants are renamed DEPRECATED_SWITCHBOARD / DEPRECATED_SWITCHBOARD_ON_DEMAND (discriminants preserved). |
| Gov-token stake fee discounts | Staking a gov token for a fee discount is gone: updateUserGovTokenInsuranceStake, GOV_SPOT_MARKET_INDEX, and the delegate variant are removed. Perp fee tier is now based on 30-day volume, floored by an admin-set promo tier (see below). |
| IF rebalance / protocol-IF shares | Protocol-owned insurance-fund shares and IF rebalancing are removed (the admin IF-withdraw, protocol-IF-share transfer, IF-swap, and IF-rebalance-config instructions). |
| Legacy referrer-reward fee path | UserStats.fees.total_referrer_reward, UserStats.fees.current_epoch_referrer_reward, and UserStats.next_epoch_ts are deleted; FeeStructure.referrer_reward_epoch_upper_bound is now padding. The SDK's referrerInfo? param is dropped from placeAndMakePerpOrder, placeAndMakeSignedMsgPerpOrder, and fillPerpOrder. |
New on Velocity
Velocity also adds subsystems Drift never had. In brief:
- Velocity liquidity pool module: a liquidity-pool and vAMM-hedge component, configured per market through
PerpMarketAccount.hedgeConfig. - Isolated perp positions: per-position isolated collateral. The instructions are feature-gated out of mainnet builds pending audit; the state layout is present in every build.
- Builder codes: the
change_approved_builderinstruction, aRevenueShareescrow account, andReferrerStatus.BuilderReferral = 4. See Builder Codes. - Tiered admin keys: the single
State.adminis split intocold_admin,warm_admin,pause_admin, and a set of narrowly scoped hot keys. See Account Model. - Continuous funding dead zone: a per-market funding clamp threshold and ramp slope,
fundingClampThresholdandfundingRampSlope. - Per-market funding-bias spread widening: an opt-in vAMM spread widen on the funding-paying side, off by default.
- Fast-fill auctions: the DLOB server can force fast, marketable auctions. See the behavior changes below.
- Protocol fee redesign: fees are re-routed through a three-way AMM, insurance fund, and protocol split rather than changing the taker rate itself.
Behavior changes to review
These are semantic changes a compiler cannot catch: a port that builds cleanly can still mispredict onchain behavior. What follows is the shortlist, ordered by impact for a market maker. Every item is enumerated in full, with the exact condition and the check to run, in Section 5 of the agent guide, which is the reference version of this list.
- Quote asset is USDT on mainnet. See above. Funding an account with the wrong token is the highest-severity failure mode on this page.
- Fast-fill auctions. At DLOB server API version 3 and above, every market is fast-fill: the auction starts inside the touch and lasts 2000ms of wall clock. Auctions become marketable almost immediately, so a maker quoting off stale prices gets run over. Derive the window from the live slot duration rather than hardcoding 5 slots, and use the
generatedAtresponse field for staleness checks. - Trigger orders are priced at their post-trigger price. The Rust DLOB library used by fillers and keeper bots now rewrites a resting trigger order's book price to its computed post-trigger auction price, clamped to the limit price for
TriggerLimit, instead of tagging it with the raw trigger price. Stop assuming a resting trigger order's book price equals its trigger price. - AMM JIT is dropped from match fills under a hard gate. With a pause, a drawdown, MM-oracle volatility, or an invalid oracle in force, a DLOB match fills DLOB-only and fills can be capped to the resting maker's size. Do not assume AMM JIT backstops a match.
- MM-oracle native writes are throttled and clamped.
update_mm_oracle_nativesilently skips a write, returningOkwith no error, on a non-positive price, a non-increasing sequence id, a non-advancing slot, or a source slot more than 800ms from the landing slot. An oversized price step is the exception: it is clamped to the 1% per-write cap and written, so a large move converges over several writes rather than freezing the oracle. Throttle crank writes to at least 800ms apart and expect no error signal when one is dropped. - The funding floor rose from 7.3% to 10.95% annualized.
FUNDING_RATE_OFFSET_DENOMINATORdropped from 5000 to 3333, making the always-applied floor and ceiling roughly 1.5x higher. The SDK mirror is in sync, so re-pull it and re-model funding carry on any perp inventory. - Fee costs changed for referred and previously staked accounts. The gov-token stake discount is gone; the perp fee tier now comes from 30-day volume, floored by the admin-set
State.promo_fee_tierwhere 0 means no floor. Separately,getMarketFeesnow subtracts the referee discount, andcalculateFeeForQuoteAmountbecamecalculatePerpTakerFee, which rounds predicted fees up rather than down. Re-model taker fees with no stake benefit. MarketStatusdiscriminants shifted. Four now-removed pause variants sat betweenActiveandReduceOnlyon Drift, soReduceOnly,Settlement, andDelistedwere 6, 7, and 8. They are 2, 3, and 4 here. IDL-based decoding is fine; any custom raw-byte decoder silently misclassifies market state until it is rebuilt.- Bulk order margin is tighter.
place_ordersandplace_scale_ordersaccumulate risk across the batch and check initial margin once per touched risk scope, instead of gating only the last order at maintenance margin. Batches that previously slipped a risk-increasing order past a weak gate now revert withInsufficientCollateral. Size batches against initial margin. - Deposits and transfers enforce per-market admission. Same-market
transfer_deposit, its delegate variant, and directdeposit()now apply the full admission logic: active status,max_token_deposits, the reduce-only cap, and the per-marketDepositpause bit independently of the global pause. Calls that used to succeed against a capped, non-active, or reduce-only market now revert. Pre-check spot market status and caps.
Data API: Drift-only columns
The Data API's Trades/Market Trades tables drop the spotFulfillmentMethodFee column (external spot fulfillment is removed), and the Funding Rates table drops periodRevenue and baseAssetAmountWithUnsettledLp (vAMM LP shares are removed). One entire table has no Velocity equivalent:
LP (BAL), Drift-only, no Velocity equivalent. Drift's vAMM LP shares (PerpPosition.lpShares and the addLiquidity/settleLiquidity actions below) were removed entirely on Velocity. There is no per-user LP-share mechanism to emit these events. Liquidity provision against a market now happens through the separate Velocity liquidity pool module (a hedge-pool architecture configured per-market via PerpMarketAccount.hedgeConfig), which has its own accounting and does not map onto this table.
| Column | Unit | Description |
|---|---|---|
| action | addLiquidity / settleLiquidity | |
| nShares | int | Number of perpetual contract shares traded. |
| deltaBaseAssetAmount | int | Change in base asset position due to the trade. |
| deltaQuoteAssetAmount | int | Change in quote asset position due to the trade. |
| pnl | int | Profit or loss from the trade. |
See the Data API glossary for the full current column reference.
SDK surface
The headline renames a TypeScript integrator hits first: there are no back-compat aliases, so these surface as build errors:
DriftClient→VelocityClientDRIFT_PROGRAM_ID→VELOCITY_PROGRAM_IDDriftEnv→VelocityEnv- Account subscribers:
webSocketDriftClientAccountSubscriber(V2)→webSocketVelocityClientAccountSubscriber(V2),pollingDriftClientAccountSubscriber→pollingVelocityClientAccountSubscriber,grpcDriftClientAccountSubscriber(V2)→grpcVelocityClientAccountSubscriber(V2) - Config field
USDC_MINT_ADDRESS→QUOTE_MINT_ADDRESS Order.oraclePriceOffset/OrderParams.oraclePriceOffsetwidened fromnumbertoBN: wrap raw numbers innew BN(...)- Removed root exports include
PythSolanaReceiverandWormholeCoreBridgeSolana: importing either from the package root now breaks
Note also that the IDL account names are PascalCase (e.g. PerpMarket, SpotMarket, User). Pass those exact names to the account coder.
For the exhaustive symbol tables and a step-by-step procedure an AI coding agent can execute, see the AI Agent Migration Guide.
Scope & currency
This page reflects @velocity-exchange/sdk 0.20.0 and covers the TypeScript SDK. The canonical layout-and-ABI reference, which Rust (velocity-rs) and raw-ABI integrators need, is docs/DRIFT-TO-VELOCITY.md in the velocity-v1 monorepo. That repository is not public and will not be until the post-fork audit report is final, so ask the team for the document rather than looking for a clone URL.