DEXs & Providing Liquidity

Yield API supports concentrated and non-concentrated liquidity pools via two new yield types and extended state metadata.

1. Yield Types

YieldType valueDescriptionTypical protocols
concentrated-liquidity-poolConcentrated AMM positions with price ranges and fee tiers. Liquidity is provided within a range.PancakeSwap V3
liquidity-pool“Classic” / v2-style liquidity pools with a single LP token and no price ranges.Curve

These values appear in the metadata.type field of YieldDto returned by:

  • GET /v1/yields
  • GET /v1/yields/{id}

2. Interaction Model

Both pool types use the standard enter / exit action model under /v1/actions, with yield-specific arguments exposed via:

  • args.enter
  • args.exit

in YieldDto.


2.1 Concentrated Liquidity Pools (PancakeSwap V3)

  • Yield type: concentrated-liquidity-pool

Enter arguments

FieldTypeRequiredDescription
amountstringYesTotal notional amount the user wants to supply (in inputToken units).
inputTokenstringNoOptional token address / symbol to deposit. Defaults to the first token in inputTokens.
modestringYesPositioning mode. Currently only "balanced" is supported (50/50 value split base/quote).
rangeobjectNoOptional price range object. If omitted, the position is opened with the full range.

range object

FieldTypeRequiredDescription
lowerPricestringYesLower price bound.
upperPricestringYesUpper price bound.

Exit arguments

FieldTypeRequiredDescription
percentagenumberYesPercentage of the position to exit (0–100). 100 exits the full position.

The API returns the usual ActionDto / TransactionDto envelope with constructed unsigned transactions for the pool’s network.


2.2 Non-Concentrated Liquidity Pools (Curve & other v2 pools)

  • Yield type: liquidity-pool
  • Classic multi-asset pools that mint a single LP token.

Enter arguments

FieldTypeRequiredDescription
amountsstring[]YesArray of deposit amounts — one entry per input token in inputTokens.

Example

{
  "amounts": ["100", "100"] // For a 2-token pool: [DAI, USDC]
}

Exit arguments

FieldTypeRequiredDescription
amountstringYesLP token amount to withdraw / redeem from pool.

3. New State Fields on GET /v1/yields/{id}

The yields endpoint now exposes a state object with pool-specific metadata. This is read-only and intended for UI display and additional calculations (e.g. APR, TVL, fee stats).

GET /v1/yields/{id}

{
  "id": "...",
  "type": "concentrated-liquidity-pool",
  "metadata": { /* ... */ },
  "state": {
    "concentratedLiquidityPoolState": { /* ... */ },
    "pricePerShareState": null
  }
}

Depending on the yield type, either concentratedLiquidityPoolState or pricePerShareState will be populated.

3.1. Concentrated Liquidity Pools

state.concentratedLiquidityPoolState:

FieldTypeDescription
baseAprstringBase APR for a full-range position in this pool (trading fees only).
pricestringCurrent pool price (base/quote).
tickSpacingnumberTick spacing for this fee tier.
minTicknumberMinimum allowed tick for the pool.
maxTicknumberMaximum allowed tick for the pool.
volume24hUsdstring or null24-hour trading volume in USD (if available).
fee24hUsdstring or null24-hour fees earned by LPs in USD (if available).
tvlUsdstring or nullCurrent TVL of the pool in USD (nullable if unavailable).
feeTierstringFee tier for the pool (e.g. "0.01", "0.05").
baseTokenTokenDtoBase token metadata (symbol, address, decimals, network, etc.).
quoteTokenTokenDtoQuote token metadata.

Important: For concentrated liquidity, the API returns Base APR only (APR for a full-range position). If you want to display Range APR (APR for the user’s chosen price range), it has to be computed on the client side following the range selection.

Range APR calculation (client-side)

// From pool state
const baseApr = Number(state.concentratedLiquidityPoolState.baseApr);
const currentPrice = Number(state.concentratedLiquidityPoolState.price);

// Derive minPrice / maxPrice from minTick, maxTick and tickSpacing using the PancakeSwap / Uniswap v3 tick formula
const minPrice = /* derived from minTick */;
const maxPrice = /* derived from maxTick */;

// Full-range width
const fullRangeWidth = (maxPrice - minPrice) / currentPrice;

// User-selected range
const lowerPrice = /* user lower bound */;
const upperPrice = /* user upper bound */;
const userRangeWidth = (upperPrice - lowerPrice) / currentPrice;

// Range APR
const rangeMultiplier = fullRangeWidth / userRangeWidth;
const rangeApr = baseApr * rangeMultiplier;

Where:

Narrower range → smaller userRangeWidth → larger rangeMultiplier → higher rangeApr.

Wider rangerangeApr approaches baseApr.

Out of range (current price outside [lowerPrice, upperPrice]) → APR effectively 0%, since the position is not earning fees.

3.2. Non-Concentrated Liquidity Pools

For classic Curve-style LPs, the state.pricePerShareState field exposes the LP share price and quote token:

state.pricePerShareState:

FieldTypeDescription
pricestringCurrent price of one LP share, denominated in quoteToken.
shareTokenTokenDtoLP token metadata (symbol, address, decimals, network).
quoteTokenTokenDtoQuote token used for pricing (typically a stablecoin like USDC / DAI).

This lets integrators:

  • Convert LP balances into a USD / stable equivalent.
  • Show portfolio value and PnL for Curve / v2 LP positions.