XYCConcentrate

The XYCConcentrate instruction implements a concentrated liquidity AMM swap in SwapVM, the Aqua swap engine. It computes virtual reserves from real balances and a price range (sqrtPriceMin, sqrtPriceMax), then performs a constant-product swap within those virtual reserves. Bounding the price range concentrates a maker's real balances so they provide deeper liquidity inside that range than an unbounded constant-product curve would.

XYCConcentrate is part of the AquaOpcodes instruction set on the AquaSwapVMRouter (the deployed SwapVM router), alongside Controls, XYCSwap, Decay, Fee, PeggedSwap, and Extruction.

Source: src/instructions/XYCConcentrate.sol


Args encoding

Field Offset Size Description
sqrtPriceMin 0 32 bytes (uint256) sqrt(P_min) in 1e18 fixed-point, where P = tokenGt / tokenLt
sqrtPriceMax 32 32 bytes (uint256) sqrt(P_max) in 1e18 fixed-point

Total: 64 bytes. Build with XYCConcentrateArgsBuilder.build2D(uint256 sqrtPriceMin, uint256 sqrtPriceMax). Requires 0 < sqrtPriceMin < sqrtPriceMax.

Token ordering: tokenLt is the token with the lower address; tokenGt is the token with the higher address. Price P is always expressed as tokenGt / tokenLt.


Instructions

_xycConcentrateGrowLiquidity2D

Solidity
1
function _xycConcentrateGrowLiquidity2D(Context memory ctx, bytes calldata args) internal pure

Behavior

  1. Parses sqrtPriceMin and sqrtPriceMax
  2. Determines which of balanceIn/balanceOut corresponds to tokenLt vs tokenGt
  3. Computes liquidity L from real balances and price bounds: β = bLt × sqrtPriceMin / 1e18 + bGt × 1e18 / sqrtPriceMax disc = β² + 4 × (sqrtPriceMax − sqrtPriceMin) × bLt × bGt / sqrtPriceMax L = (β + √disc) × sqrtPriceMax / (2 × (sqrtPriceMax − sqrtPriceMin))
  4. Computes virtual reserves by adding virtual offsets to real balances:
  • If tokenIn is tokenLt:
    • virtualBalanceIn = balanceIn + ⌈L / sqrtPriceMax⌉
    • virtualBalanceOut = balanceOut + L × sqrtPriceMin / 1e18
  • If tokenIn is tokenGt:
    • virtualBalanceIn = balanceIn + ⌈L × sqrtPriceMin / 1e18⌉
    • virtualBalanceOut = balanceOut + L / sqrtPriceMax
  1. Applies constant-product swap formula on virtual reserves:
  • exactIn: amountOut = amountIn × virtualBalanceOut / (virtualBalanceIn + amountIn) (floor)
  • exactOut: amountIn = ⌈amountOut × virtualBalanceIn / (virtualBalanceOut − amountOut)⌉ (ceil)

ctx.swap.balanceIn and ctx.swap.balanceOut are not mutated; only amountIn and amountOut are written. Fee reinvestment is automatic: as real balances grow from each swap, L increases on the next swap.

Errors

Error Condition
ConcentrateRecomputeDetected(amountIn, amountOut) amountOut != 0 (exactIn) or amountIn != 0 (exactOut)

Constraints

  • Requires balanceIn and balanceOut set by a preceding _dynamicBalancesXD (so real reserves update each swap)
  • Suffix 2D: operates on both tokens; pure (no state read/write in the instruction itself)

  • XYCSwap: unbounded constant-product AMM
  • Balances: provides balanceIn/balanceOut from storage
  • Fee: apply fee before this instruction to reduce the effective amountIn

Did you find what you need?