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
function _xycConcentrateGrowLiquidity2D(Context memory ctx, bytes calldata args) internal pure
Behavior
- Parses
sqrtPriceMinandsqrtPriceMax - Determines which of
balanceIn/balanceOutcorresponds totokenLtvstokenGt - Computes liquidity
Lfrom real balances and price bounds: β = bLt × sqrtPriceMin / 1e18 + bGt × 1e18 / sqrtPriceMax disc = β² + 4 × (sqrtPriceMax − sqrtPriceMin) × bLt × bGt / sqrtPriceMax L = (β + √disc) × sqrtPriceMax / (2 × (sqrtPriceMax − sqrtPriceMin)) - Computes virtual reserves by adding virtual offsets to real balances:
- If
tokenInistokenLt:virtualBalanceIn = balanceIn + ⌈L / sqrtPriceMax⌉virtualBalanceOut = balanceOut + L × sqrtPriceMin / 1e18
- If
tokenInistokenGt:virtualBalanceIn = balanceIn + ⌈L × sqrtPriceMin / 1e18⌉virtualBalanceOut = balanceOut + L / sqrtPriceMax
- 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
balanceInandbalanceOutset 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)
Related
- XYCSwap: unbounded constant-product AMM
- Balances: provides
balanceIn/balanceOutfrom storage - Fee: apply fee before this instruction to reduce the effective
amountIn