# Migrating from Drift

> Canonical: https://docs.velocity.exchange/developers/migrate-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` |

> **Info:**
>
> 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](/developers/velocity-sdk/setup.md) 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_builder` instruction, a `RevenueShare` escrow account, and `ReferrerStatus.BuilderReferral = 4`. See [Builder Codes](/developers/velocity-sdk/builder-codes.md).
- **Tiered admin keys**: the single `State.admin` is split into `cold_admin`, `warm_admin`, `pause_admin`, and a set of narrowly scoped hot keys. See [Account Model](/developers/concepts/account-model.md#state-account).
- **Continuous funding dead zone**: a per-market funding clamp threshold and ramp slope, `fundingClampThreshold` and `fundingRampSlope`.
- **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](/developers/migrate-from-drift/agent-guide.md#5-behavioral-divergences-stop-and-report), 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 `generatedAt` response 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_native` silently skips a write, returning `Ok` with 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_DENOMINATOR` dropped 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_tier` where 0 means no floor. Separately, `getMarketFees` now subtracts the referee discount, and `calculateFeeForQuoteAmount` became `calculatePerpTakerFee`, which rounds predicted fees up rather than down. Re-model taker fees with no stake benefit.
- **`MarketStatus` discriminants shifted.** Four now-removed pause variants sat between `Active` and `ReduceOnly` on Drift, so `ReduceOnly`, `Settlement`, and `Delisted` were 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_orders` and `place_scale_orders` accumulate 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 with `InsufficientCollateral`. Size batches against initial margin.
- **Deposits and transfers enforce per-market admission.** Same-market `transfer_deposit`, its delegate variant, and direct `deposit()` now apply the full admission logic: active status, `max_token_deposits`, the reduce-only cap, and the per-market `Deposit` pause 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](/developers/vault-managers.md) (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](/developers/data-api/glossary.md) 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` → `VelocityClient`
- `DRIFT_PROGRAM_ID` → `VELOCITY_PROGRAM_ID`
- `DriftEnv` → `VelocityEnv`
- Account subscribers: `webSocketDriftClientAccountSubscriber(V2)` → `webSocketVelocityClientAccountSubscriber(V2)`, `pollingDriftClientAccountSubscriber` → `pollingVelocityClientAccountSubscriber`, `grpcDriftClientAccountSubscriber(V2)` → `grpcVelocityClientAccountSubscriber(V2)`
- Config field `USDC_MINT_ADDRESS` → `QUOTE_MINT_ADDRESS`
- `Order.oraclePriceOffset` / `OrderParams.oraclePriceOffset` widened from `number` to `BN`: wrap raw numbers in `new BN(...)`
- Removed root exports include `PythSolanaReceiver` and `WormholeCoreBridgeSolana`: 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](/developers/migrate-from-drift/agent-guide.md).

## 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.
