# v10 migration

> **Notice:** These documents are currently in progress. For any questions or clarifications, please contact the team.

Current version: <https://www.npmjs.com/package/@gainsnetwork/sdk/v/1.0.0-rc12>

### v10 Changes - Overview

* New funding fees (skew-based, only on v10 positions)
* New borrowing fees v2 (alongside existing v1)
* New P\&L withdrawal feature (withdraw profits without closing)
* New counter trade type (fee discounts for improving skew)
* New skew price impact
* New market max skew limits
* Fees no longer impact position size (exact position sizes)
* Modified borrowing fees v1 (uses dynamic OI)
* Modified partial update requirements (use effective leverage)
* Modified liquidation, pnl, fees calculations
* Pre and post v10 OI stored separately
* Pre-v10 trades cannot partial add
* New accounting: TradeFeesData and UiRealizedPnlData
* New Trade fields: positionSizeToken and isCounterTrade

### Developer Notes - Overview

* SDK has been updated to support v10 more effectively than previous versions
  * Backend transforms and converters are available (fetching is still separate)
    * Transform trading variables: `transformGlobalTradingVariables`
    * Transform global trades: `transformGlobalTrades`
    * All functions expect backend types
  * Additional feature support
    * Holding fees
    * Action fees
    * Price impact
    * PnL
    * Liquidations
    * Counter trade validation
    * Effective leverage
    * Market holding rates
    * Market leverage requirements
    * Market open interest
    * Market price
  * New context builders
    * More declarative development pattern
    * SDK functions mirror contract functions. But they don't fetch data, instead rely on all data provided
    * Provide large trading variables object and context builder will prepare struct for specific functions with all expected data

### Integration Guide

NOTE: For `tradingVariables` and any trade struct (`trade`, `tradeInfo`, etc), consume from backends first: [Backend](/developer/integrators/backend.md#v10-update)

#### 1. New Funding Fees

Funding fees are skew-based fees that balance long/short exposure.

**Trade-Specific Funding Fees:**

```typescript
import { buildFundingContext } from "@gainsnetwork/sdk/trade/fees/fundingFees/builder";
import {
  getTradeFundingFeesCollateral,
  getAvgFundingRatePerSecondP,
} from "@gainsnetwork/sdk/trade/fees/fundingFees";

// Build funding context
const fundingContext = buildFundingContext(
  tradingVariables,
  collateralIndex,
  pairIndex,
  currentTimestamp
);

// Calculate funding fees for a trade
const fundingFees = getTradeFundingFeesCollateral(
  trade,
  currentTimestamp,
  fundingContext
);

// Get current funding rate
const { avgFundingRatePerSecondP, currentFundingRatePerSecondP } =
  getAvgFundingRatePerSecondP(fundingContext, currentTimestamp);
```

**Display helpers:**

```typescript
import {
  convertRatePerSecondToAPR,
  formatHoldingFeeRate,
} from "@gainsnetwork/sdk/markets/holdingFees";
import { fundingRateToAPR } from "@gainsnetwork/sdk/trade/fees/fundingFees/converter";

// Convert to annual percentage rate
const apr = convertRatePerSecondToAPR(ratePerSecond);
const fundingAPR = fundingRateToAPR(fundingRatePerSecond);

// Format for display (e.g., "0.25%")
const formatted = formatHoldingFeeRate(rate);
```

#### 2. New Borrowing Fees v2

Borrowing fees v2 work alongside funding fees with a simplified rate-based model.

**Context Builder & Calculation:**

```typescript
import { buildBorrowingV2Context } from "@gainsnetworks/sdk/trade/fees/borrowingV2/builder";
import { getTradeBorrowingFeesCollateral } from "@gainsnetworks/sdk/trade/fees/borrowingV2";

// Build borrowing v2 context
const borrowingV2Context = buildBorrowingV2Context(
  tradingVariables,
  collateralIndex,
  pairIndex,
  currentTimestamp
);

// Calculate borrowing fees for a trade
const borrowingFees = getTradeBorrowingFeesCollateral(
  trade,
  currentTimestamp,
  oraclePrice,
  borrowingV2Context
);
```

**Display helpers:**

```typescript
import { borrowingRateToAPR } from "@gainsnetworks/sdk/trade/fees/borrowingV2/converter";

// Convert borrowing rate to APR for display
const borrowingAPR = borrowingRateToAPR(borrowingRatePerSecond);
```

#### 3. P\&L Withdrawal Feature

Users can withdraw profits without closing their position. This maintains leverage while extracting gains.

**Contract Interaction:**

```typescript
// Direct contract call (no SDK wrapper currently)
const tx = await gnsMultiCollatDiamond.withdrawPositivePnl(
  tradeIndex,
  amountCollateral // in collateral precision (e.g., 6 decimals for USDC)
);
```

**Important behavior:** If `amountCollateral` exceeds available positive PnL, the contract will automatically withdraw only the maximum available amount (no revert).

**To withdraw all available PnL:**

```typescript
const MAX_UINT120 = BigNumber.from(2).pow(120).sub(1);
const tx = await gnsMultiCollatDiamond.withdrawPositivePnl(
  tradeIndex,
  MAX_UINT120 // Will be capped to available PnL
);
```

**Integration requirements:**

* Calculate withdrawable P\&L: `tradeValue - initialCollateral` (when positive)
* Show withdrawable amount in UI when position is in profit
* Listen for `TradePositivePnlWithdrawn` event to update UI
* Update position display after withdrawal:
  * `collateralAmount` increases
  * `positionSizeToken` remains unchanged
  * Track `pnlWithdrawnCollateral` for total withdrawn

#### 4. Counter Trade Type

Counter trades improve market balance and receive fee discounts.

**Creating a Counter Trade:**

```typescript
// When opening a trade, set the isCounterTrade flag
const tradeStruct = {
  // ... other trade parameters ...
  isCounterTrade: true, // Request counter trade discount
};

// Open trade with counter trade flag
const tx = await gnsMultiCollatDiamond.openTrade(
  tradeStruct,
  slippagePercent,
  referrer
);
```

**Note:** The contract will validate if the trade actually qualifies as a counter trade. If not, it will be rejected. If the trade size is larger than the max skew limit, it will be reduced in size but still opened.

**Pre-validation:**

```typescript
import { validateCounterTrade } from "@gainsnetworks/sdk/trade/counterTrade/validateCounterTrade";

// Check if trade qualifies as counter trade before submitting
const validation = validateCounterTrade(
  isLong,
  positionSizeCollateral,
  leverage,
  pairIndex,
  tradingVariables
);
```

**Detection (for existing trades):**

```typescript
// Check Trade struct field
const isCounterTrade = trade.isCounterTrade; // boolean field in v10 trades
```

#### 5. Skew Price Impact

Price impact based on market skew (imbalance between long/short OI).

**NOTE:** The SDK offers wrapper utilities for open and close price impact which can be used to calculate all price impact data. More in SDK convenience functions.

**Context Builder & Calculation:**

```typescript
import { buildSkewPriceImpactContext } from "@gainsnetwork/sdk/trade/priceImpact/skew/builder";
import { getTradeSkewPriceImpact } from "@gainsnetwork/sdk/trade/priceImpact/skew";

// Build context
const skewContext = buildSkewPriceImpactContext(
  tradingVariables,
  collateralIndex,
  pairIndex
);

// Calculate skew price impact
const skewImpact = getTradeSkewPriceImpact(
  isLong,
  oraclePrice,
  positionSizeToken,
  skewContext
);
```

**Helper functions:**

```typescript
import {
  getNetSkewToken,
  getNetSkewCollateral,
} from "@gainsnetwork/sdk/trade/priceImpact/skew";

// Get current market skew
const skewToken = getNetSkewToken(pairOiData);
const skewCollateral = getNetSkewCollateral(pairOiData, oraclePrice);
```

#### 6. Market Max Skew Limits

Markets have maximum allowed skew to prevent excessive imbalance.

**Check skew using computeOiValues:**

```typescript
import { computeOiValues } from "@gainsnetworks/sdk/markets/oi/converter";

// Compute current OI values including skew
const { skewToken } = computeOiValues(
  pairOi,
  oraclePrice / collateralPriceUsd // Convert to token price in collateral
);

// Get max skew from trading variables
const maxSkewCollateral =
  tradingVariables.pairs[pairIndex]?.params?.maxSkewCollateral;

// Convert skewToken to collateral for comparison
const skewCollateral = Math.abs(skewToken) * (oraclePrice / collateralPriceUsd);
const skewExceeded = skewCollateral > maxSkewCollateral;
```

**Note:** For counter trade validation and position sizing, use `validateCounterTrade` (see section 5).

#### 7. Effective Leverage in Partial Updates

Partial position updates now validate against effective leverage (accounts for unrealized P\&L).

**Calculation:**

```typescript
import { getEffectiveLeverage } from "@gainsnetworks/sdk/trade/effectiveLeverage";

// Calculate effective leverage
const effectiveLeverage = getEffectiveLeverage(
  trade.leverage,
  trade.collateralAmount,
  pnlCollateral
);
```

**Validation Requirements:**

**For Position Increases (Partial Add):**

* Effective leverage must not exceed `pairMaxLeverage`
* Counter trades must not exceed `pairCounterTradeMaxLeverage`
* Adjusted initial leverage must be between 0.1x and max uint24 (\~16,777x)
* Pre-v10 trades cannot partial add

**For Position Decreases (Partial Close):**

* No effective leverage maximum check
* Only validates adjusted initial leverage (≥ 0.1x)

**For Leverage Increases:**

* Same as position increases - effective leverage validated

**For Leverage Decreases (Add Collateral):**

* Same as position decreases - no effective leverage check

```typescript
// Example validation
const maxLeverage = isCounterTrade
  ? tradingVariables.pairs[pairIndex].maxLeverageCounterTrade
  : tradingVariables.pairs[pairIndex].maxLeverage;

const isValid = effectiveLeverage <= maxLeverage;
const MIN_LEVERAGE = 0.1; // 0.1x minimum
```

#### 8. Modified Borrowing Fees v1

Borrowing fees v1 now use dynamic OI (position size adjusted by current price vs entry price).

**Context Builder & Calculation:**

```typescript
import { buildBorrowingV1Context } from "@gainsnetworks/sdk/trade/fees/borrowing/builder";
import { getBorrowingFee } from "@gainsnetworks/sdk/trade/fees/borrowing";

// Build borrowing v1 context
const borrowingV1Context = buildBorrowingV1Context(
  tradingVariables,
  collateralIndex,
  currentBlock
);

// Calculate borrowing fee for a trade
const borrowingFee = getBorrowingFee(
  positionSizeCollateral,
  pairIndex,
  isLong,
  initialAccFees,
  currentPairPrice,
  borrowingV1Context
);
```

**Utility functions:**

```typescript
import { borrowingFeeUtils } from "@gainsnetworks/sdk/trade/fees/borrowing";

// Get pending accumulated fees for a pair
const pendingFees = borrowingFeeUtils.getPairPendingAccFees(
  pairs,
  pairGroups,
  groups,
  initialAccFees,
  pairIndex,
  currentBlock,
  feePerBlockCaps
);

// Check if within max group OI
const withinLimit = borrowingFeeUtils.withinMaxGroupOi(
  pairs,
  pairGroups,
  groups,
  positionSizeCollateral,
  pairIndex,
  isLong
);
```

#### 9. Modified Liquidation Calculations

Liquidation now accounts for pending fees and realized P\&L.

**Context Builder & Calculation:**

```typescript
import { buildLiquidationPriceContext } from "@gainsnetwork/sdk/trade/liquidation/builder";
import { getLiquidationPrice } from "@gainsnetwork/sdk/trade/liquidation";

// Build comprehensive context
const liquidationContext = buildLiquidationPriceContext(
  tradingVariables,
  tradeContainer,
  {
    currentBlock,
    currentTimestamp,
    currentPairPrice,
    spreadP,
    traderFeeMultiplier,
    userPriceImpact,
  }
);

// Calculate liquidation price
const liqPrice = getLiquidationPrice(trade, liquidationContext);
```

**Additional functions:**

```typescript
import { getLiquidationPriceAfterPositionUpdate } from "@gainsnetwork/sdk/trade/liquidation";

// Calculate after position update
const newLiqPrice = getLiquidationPriceAfterPositionUpdate(
  existingTrade,
  existingLiquidationContext,
  newCollateralAmount,
  newLeverage
);
```

#### 10. Modified PnL Calculations

Comprehensive PnL includes all v10 components: funding fees, borrowing fees, and realized P\&L.

**Context Builder & Calculation:**

```typescript
import { buildComprehensivePnlContext } from "@gainsnetwork/sdk/trade/pnl/builder";
import { getComprehensivePnl } from "@gainsnetwork/sdk/trade/pnl";

// Build context
const pnlContext = buildComprehensivePnlContext(
  tradingVariables,
  tradeContainer,
  {
    currentBlock,
    currentTimestamp,
    traderFeeMultiplier,
  }
);

// Calculate comprehensive PnL
const pnl = getComprehensivePnl(
  trade,
  marketPrice,
  executionPrice, // price after spreads/impacts
  tradeInfo,
  pnlContext
);
```

**Helper functions:**

```typescript
import { getPnlPercent, getTradeValue } from "@gainsnetwork/sdk/trade/pnl";

// Calculate PnL percentage
const pnlPercent = getPnlPercent(openPrice, currentPrice, isLong, leverage);

// Get trade value (collateral + PnL)
const tradeValue = getTradeValue(collateralAmount, pnlCollateral, 0); // pass 0 for raw trade value calculation
```

#### 11. New Trade Fields

v10 trades have additional fields that must be parsed and stored.

**New fields in Trade struct:**

```typescript
interface Trade {
  // ... existing fields ...
  positionSizeToken: bigint; // Position size in token units (1e18 precision)
  isCounterTrade: boolean; // Whether trade qualified for counter trade discount
}
```

#### 12. V10 OI Tracking

OI is tracked separately for pre-v10 and post-v10 trades.

**OI Functions:**

```typescript
import {
  getPairTotalOisCollateral,
  getPairTotalOisDynamicCollateral,
  getPairV10OiTokenSkewCollateral,
  getPairV10OiDynamicSkewCollateral,
} from "@gainsnetworks/sdk/markets/oi";

// Get total OI (pre-v10 only)
const staticOI = getPairTotalOisCollateral(pairOi);

// Get dynamic OI (pre-v10 + v10 adjusted by price)
const dynamicOI = getPairTotalOisDynamicCollateral(pairOi, oraclePrice);

// Get v10 skew in collateral
const skewCollateral = getPairV10OiTokenSkewCollateral(pairOi, oraclePrice);

// Get v10 dynamic skew
const dynamicSkew = getPairV10OiDynamicSkewCollateral(pairOi, oraclePrice);
```

**Comprehensive OI Values:**

```typescript
import { computeOiValues } from "@gainsnetwork/sdk/markets/oi/converter";

// Get all computed OI values at once
const oiValues = computeOiValues(
  pairOi,
  oraclePrice / collateralPriceUsd // Convert to token price in collateral
);
```

**Important notes:**

* Funding fees only apply to v10 OI
* Skew calculations use v10 OI only
* Max OI checks use combined OI (pre-v10 + v10)
* Counter trade validation uses v10 skew

### Market Price Concept

Market price is a v10 feature that applies to markets with funding fees and skew price impact. It represents the oracle price adjusted for current market skew.

**Calculate Market Price:**

```typescript
import { getCurrentMarketPrice } from "@gainsnetworks/sdk/markets/price/marketPrice";
import { buildMarketPriceContext } from "@gainsnetworks/sdk/markets/price/builder";

// Build context for market price calculation
const marketPriceContext = buildMarketPriceContext(tradingVariables, pairIndex);

// Calculate market price from oracle price
const { marketPrice, skewImpactP } = getCurrentMarketPrice(
  pairIndex,
  oraclePrice,
  marketPriceContext
);
```

### SDK Wrapper Functions

The SDK provides high-level wrapper functions that combine multiple calculations for common operations.

#### Price Impact

**Opening a Trade:**

```typescript
import { getTradeOpeningPriceImpact } from "@gainsnetwork/sdk/trade/priceImpact/open";
import { buildTradeOpeningPriceImpactContext } from "@gainsnetwork/sdk/trade/priceImpact/open/builder";

// Build context with all required data
const openContext = buildTradeOpeningPriceImpactContext(
  tradingVariables,
  collateralIndex,
  pairIndex,
  currentBlock
);

// Calculate total price impact and execution price
const openImpact = getTradeOpeningPriceImpact(
  oraclePrice, // Always pass oracle price
  isLong,
  positionSizeCollateral,
  leverage,
  openContext
);
```

**Understanding Price Impact Results:**

```typescript
// The function returns multiple price impact values:
const {
  priceAfterImpact, // Final execution price
  totalPriceImpactP, // Total impact from oracle price
  totalPriceImpactPFromMarketPrice, // Total impact from market price
  baseSkewPriceImpactP, // Market skew before trade
  tradeSkewPriceImpactP, // Additional skew from this trade
  totalSkewPriceImpactP, // Total skew impact (base + trade)
} = openImpact;

// For UI display:
// If showing market price: use totalPriceImpactPFromMarketPrice
// If showing oracle price: use totalPriceImpactP
```

**Closing a Trade:**

```typescript
import { getTradeClosingPriceImpact } from "@gainsnetwork/sdk/trade/priceImpact/close";
import { buildTradeClosingPriceImpactContext } from "@gainsnetwork/sdk/trade/priceImpact/close/builder";

// Build context
const closeContext = buildTradeClosingPriceImpactContext(
  tradingVariables,
  tradeContainer,
  currentBlock
);

// Calculate price impact for closing
const closeImpact = getTradeClosingPriceImpact(
  trade,
  oraclePrice, // Always pass oracle price
  closeContext
);

// Similar to opening, returns multiple impact values
const {
  priceAfterImpact,
  tradeValueCollateral,
  totalPriceImpactP, // From oracle price
  totalPriceImpactPFromMarketPrice, // From market price
  // ... other impact components
} = closeImpact;
```

#### Action Fees (Trading Fees)

**Calculate Total Trading Fees:**

```typescript
import { getTotalTradeFeesCollateral } from "@gainsnetwork/sdk/trade/fees/trading";
import { buildTradingFeesContext } from "@gainsnetwork/sdk/trade/fees/trading/builder";

// Build context
const feesContext = buildTradingFeesContext(
  tradingVariables,
  collateralIndex,
  pairIndex
);

// Calculate total fees
const totalFees = getTotalTradeFeesCollateral(
  positionSizeCollateral,
  isCounterTrade,
  tradeTier,
  feesContext
);
```

**Get Detailed Fee Breakdown:**

```typescript
import { getTradeFeesCollateral } from "@gainsnetwork/sdk/trade/fees/trading";

// Get breakdown of all fee components
const feeBreakdown = getTradeFeesCollateral(
  positionSizeCollateral,
  pairOpenFeeP,
  tradeTierMultiplier,
  referralFeeP,
  pairTriggerOrderFeeP,
  pairOtcFeeP,
  collateralPrecision
);
// Returns: referralFees, govFees, triggerFees, gnsOtcFees, gTokenFees
```

**Calculate Pending Holding Fees:**

```typescript
import { getTradePendingHoldingFeesCollateral } from "@gainsnetwork/sdk/trade/fees/trading";

// Calculate all accumulated holding fees
const holdingFees = getTradePendingHoldingFeesCollateral(
  trade,
  currentBlock,
  currentTimestamp,
  oraclePrice,
  collateralPrecision,
  holdingFeesContext // combines funding + borrowing contexts
);
```

### Summary

The SDK provides all necessary functions to integrate v10 features. Key patterns:

1. **Use Context Builders**: Most complex calculations require a context object built from trading variables
2. **Transform Backend Data**: Use `transformGlobalTradingVariables` and `transformGlobalTrades` before passing to SDK functions
3. **Handle Pre-v10 Trades**: Check `trade.contractsVersion` to determine if a trade uses v10 features
4. **Display Market Rates**: Use functions in "Current Market Rates" section for market-wide statistics


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.gains.trade/developer/integrators/guides/v10-migration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
