Skip to content

[feat]: release 0.2.0#101

Merged
dannxbt merged 22 commits intomainfrom
feat/release_0.2.0
Mar 13, 2026
Merged

[feat]: release 0.2.0#101
dannxbt merged 22 commits intomainfrom
feat/release_0.2.0

Conversation

@dannxbt
Copy link
Copy Markdown
Collaborator

@dannxbt dannxbt commented Mar 2, 2026

Features

Added

  • Added new CollectFeeMode.Compounding mode — a constant-product (x * y = k) liquidity mode where a configurable percentage of trading fees are compounded back into pool liquidity (as token B), with the remaining fees available for claiming. Pools with compounding mode do not use price ranges.
  • Added LiquidityHandler interface and two implementations: CompoundingLiquidityHandler and ConcentratedLiquidityHandler, with a getLiquidityHandler factory function that dispatches based on collectFeeMode.
  • Added compoundingFeeBps field to PoolFeesParams for configuring the compounding fee split.
  • Added collectFeeMode parameter to getLiquidityDelta, getDepositQuote, getWithdrawQuote, and preparePoolCreationParams.
  • Added tokenAAmount, tokenBAmount, and liquidity parameters to getDepositQuote and getWithdrawQuote for compounding liquidity calculations.

Changed

  • Rewrote swapQuote.ts to use LiquidityHandler abstraction, supporting both concentrated and compounding liquidity modes.
  • Fee structure: tradingFee split into claimingFee + compoundingFee in SwapResult2, FeeOnAmountResult, and SplitFees types.
  • Renamed PoolVersion enum to LayoutVersion.
  • PoolFeesParams.padding changed from number[] to number.
  • splitFees and getFeeOnAmount no longer accept hasPartner parameter.
  • getQuote totalFee now computed as claimingFee + compoundingFee + protocolFee + referralFee.
  • getQuote2 return type: tradingFee and partnerFee replaced with claimingFee and compoundingFee.
  • collectFeeMode comment updated: 0: BothToken, 1: OnlyB, 2: Compounding.
  • Liquidity delta and amount functions (getLiquidityDeltaFromAmountA, getLiquidityDeltaFromAmountB, getAmountAFromLiquidityDelta, getAmountBFromLiquidityDelta) now accept collectFeeMode and dispatch to the appropriate handler.

Removed

  • Removed claimPartnerFee endpoint and ClaimPartnerFeeParams type.
  • Removed partnerFee from fee result types (FeeOnAmountResult, SplitFees, SwapResult2).
  • Removed hasPartner helper function.
  • Removed FEE_PADDING constant.

Examples

CollectFeeMode: Compounding
https://devnet.meteora.ag/dammv2/7WnkQ484JTBWbKafc3nKvYrq1jVVaM13mBq9xNWx7EAB

SwapMode: ExactIn
Buy Sell

SwapMode: PartialFill
Buy Sell

SwapMode: ExactOut
Buy Sell

Published (Beta)

@meteora-ag/cp-amm-sdk@1.3.6-rc.2

@dannxbt
Copy link
Copy Markdown
Collaborator Author

dannxbt commented Mar 7, 2026

/bot review

@dannxbt dannxbt requested a review from bangyro March 7, 2026 17:33
@metoeraag-bot
Copy link
Copy Markdown

metoeraag-bot Bot commented Mar 7, 2026

Bot Agent progress: /bot review

Progress:

  • Repo checks (3 ok, 0 failed)
  • Context build
  • Codex review (1 pass + first look)
  • Buddy review (agreed after 2/10)
  • Post review

Copy link
Copy Markdown

@metoeraag-bot metoeraag-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Compounding-mode support is close, but two correctness issues remain: exact-out compounding quotes need a reserve-bound guard to prevent zero/negative-denominator math when the requested output reaches or exceeds reserves, and applySwapResult computes compounding-pool post-swap reserves/nextSqrtPrice incorrectly in the feesOnInput path by using the post-fee input amount instead of the full amount received by the vault.

Inline comments

See inline comments on the diff.

Claude (API) review

Rounds: 2 (min=1, max=10).
First look: Codex + Claude (API).
Agreement: yes (no new findings/questions).

Debate transcript

First look comparison

Codex (first look):

Summary:
Compounding-mode support looks close, but the new liquidity-handler swap API still exposes invalid price data for compounding pools and the exact-out helpers need a reserve-bound guard to avoid unsafe math.

Inline comment highlights:

  • src/math/liquidity/compoundingLiquidity.ts:109: These compounding swap helpers return nextSqrtPrice as 0 (same pattern in the other exact/partial in/out helpers). Since LiquidityHandler.calculate* exposes nextSqrtPrice as part of its contract, any direct consumer of the new handl
  • src/math/liquidity/compoundingLiquidity.ts:208: Please guard amountOut.gte(tokenBAmount) here (and the symmetric amountOut.gte(tokenAAmount) case in calculateBtoAFromAmountOutForCompoundingLiquidity). With the current tokenXAmount.sub(amountOut) denominator, an exact-out quote th

Claude (API) (first look):

Summary:
Large release PR adding CompoundingLiquidity mode, LiquidityHandler abstraction, fee restructuring (tradingFee→claimingFee+compoundingFee), and removing partner fee functionality. The code is well-structured with clean abstractions. Key concerns: a potential division-by-zero in compounding liquidity calculations when pool reserves equal the output amount, and the applySwapResult function mutating the result object's nextSqrtPrice after construction which could be confusing.

Inline comment highlights:

  • src/math/liquidity/compoundingLiquidity.ts:211: Bug: Division by zero when amountOut >= tokenBAmount. If amountOut equals tokenBAmount, tokenBAmount.sub(amountOut) is zero, causing mulDiv to divide by zero. Similarly, if amountOut > tokenBAmount, the denominator goes nega
  • src/math/liquidity/compoundingLiquidity.ts:238: Bug: Division by zero when amountOut >= tokenAAmount. Same issue as calculateAtoBFromAmountOutForCompoundingLiquidity — if amountOut equals or exceeds tokenAAmount, tokenAAmount.sub(amountOut) is zero or negative, causing a di
  • src/math/liquidity/compoundingLiquidity.ts:317: Potential underflow: sqrtPrice.subn(1) will underflow if sqrtPrice is zero (BN). While unlikely in practice (zero sqrt price means zero-priced token B), consider adding a guard or documenting that sqrtPrice must be > 0.
  • src/math/swapQuote.ts:47: Nit/clarity: applySwapResult is called after constructing the SwapResult2 object, and then it overwrites result.nextSqrtPrice. This pattern of constructing a result, then mutating it, is a bit surprising. For non-compounding pools it'
  • src/math/swapQuote.ts:64: In applySwapResult for compounding mode, result.excludedFeeInputAmount is used to compute newTokenAAmount/newTokenBAmount, but for the feesOnInput case this is the amount after fee deduction. The includedFeeInputAmount (origin
  • src/math/liquidity/compoundingLiquidity.ts:13: Minor: Typo in function name — getInitialCompoundingPoolComInformation should likely be getInitialCompoundingPoolInformation (extra Com).
  • src/math/feeMath.ts:84: With strictNullChecks disabled in tsconfig, this isn't a compile error, but the switch cases don't have a guaranteed assignment for feesOnInput/feesOnTokenA before the return. If a new TradeDirection value were added without updat
  • src/math/liquidity/liquidityHandler.ts:119: The _nextSqrtPrice parameter is completely ignored in CompoundingLiquidityHandler.getNextSqrtPrice. This is intentional per the comment on the concentrated handler (line 222-223), but the compounding handler has no such comment. Conside

Comparison notes:

Review synthesis

  • No major disagreement on the main blocker: both reviews flag the compounding exact-out path as unsafe when amountOut >= reserve (A as a missing reserve-bound guard; B as a division-by-zero/negative-denominator bug).
  • Different primary emphasis: A focuses on API correctness for compounding pools, especially nextSqrtPrice being exposed as 0 via LiquidityHandler. B focuses more on swap-result handling, especially applySwapResult mutating nextSqrtPrice and possible fee-accounting confusion.
  • Scope differs: A stays tightly focused on 2 likely blockers. B raises additional secondary issues (possible sqrtPrice.subn(1) underflow, ignored parameter/comment mismatch, switch exhaustiveness, typo/nits).

Most important follow-up action:
Fix and regression-test the compounding exact-out quote flow end-to-end: enforce amountOut < reserve guards in both directions and verify compounding swap results return a valid, non-zero nextSqrtPrice.

Round 1

Codex (primary):

Summary:
Compounding-mode support looks close, but the new liquidity-handler swap API still exposes invalid price data for compounding pools and the exact-out helpers need a reserve-bound guard to avoid unsafe math.

Inline comment highlights:

  • src/math/liquidity/compoundingLiquidity.ts:109: These compounding swap helpers return nextSqrtPrice as 0 (same pattern in the other exact/partial in/out helpers). Since LiquidityHandler.calculate* exposes nextSqrtPrice as part of its contract, any direct consumer of the new handl
  • src/math/liquidity/compoundingLiquidity.ts:208: Please guard amountOut.gte(tokenBAmount) here (and the symmetric amountOut.gte(tokenAAmount) case in calculateBtoAFromAmountOutForCompoundingLiquidity). With the current tokenXAmount.sub(amountOut) denominator, an exact-out quote th

Claude (API):

Critique of Primary Review

The primary review correctly identifies the two highest-impact issues but has one significant gap and one false positive:

False Positive: nextSqrtPrice: 0 exposure

The primary review's main concern about nextSqrtPrice being exposed as 0 from compounding swap helpers is overstated. The applySwapResult function in swapQuote.ts always overwrites nextSqrtPrice for compounding pools by recomputing from post-swap reserves. The 0 is an internal placeholder, not a leaked API value. All three swap paths (ExactIn, PartialFill, ExactOut) call applySwapResult before returning.

Missed Issue: Reserve calculation uses wrong input amount

Neither the primary review nor the first-look review clearly identified that applySwapResult uses result.excludedFeeInputAmount to compute new reserves, but for the feesOnInput case, the vault actually receives includedFeeInputAmount. This produces an incorrect nextSqrtPrice for compounding pools in the OnlyB/Compounding fee modes (BtoA direction). This is a real bug affecting compounding pool price tracking.

Reserve accounting questions

The applySwapResult function adds compoundingFee back to tokenB reserves but doesn't clearly account for where claimingFee, protocolFee, and referralFee come from relative to the vault. The primary review didn't examine this accounting at all.

Agreement on exact-out guard

The primary review's call for amountOut.gte(reserve) guards on the exact-out paths is correct and important. The division-by-zero / negative-denominator bug is real and should be blocked before release.

Codex (response):

  • New findings applied: 1/2
  • False positives addressed: 1/1
  • Open questions kept for author: 2/2

Round 2

Codex (primary):

Summary:
Compounding-mode support looks close, but there are still two correctness issues to address: exact-out compounding quotes need a reserve-bound guard to avoid zero/negative-denominator math, and applySwapResult miscomputes post-swap reserves/nextSqrtPrice for compounding pools when fees are charged on input by using the post-fee input amount instead of the full amount received by the vault.

Inline comment highlights:

  • src/math/liquidity/compoundingLiquidity.ts:208: Please guard amountOut.gte(tokenBAmount) here (and the symmetric amountOut.gte(tokenAAmount) case in calculateBtoAFromAmountOutForCompoundingLiquidity). With the current tokenXAmount.sub(amountOut) denominator, an exact-out quote th
  • src/math/swapQuote.ts:64: In the feesOnInput branch, the reserve-increase side should use result.includedFeeInputAmount, not result.excludedFeeInputAmount. The vault receives the full input amount before fees are split internally, so using the post-fee input u

Claude (API):

Critique of Primary Review (Round 2)

The primary review now correctly identifies the two remaining blockers:

  1. Reserve-bound guard for exact-out compounding (compoundingLiquidity.ts:208 and the symmetric case) — correctly flagged.
  2. applySwapResult uses excludedFeeInputAmount instead of includedFeeInputAmount for feesOnInput compounding pools (swapQuote.ts:64) — correctly flagged.

The false positive about nextSqrtPrice: 0 was addressed and retracted. The two open questions about claimingFee reserve accounting and protocolFee/referralFee subtraction were kept for the author, which is appropriate.

No additional high-signal findings remain that the primary review missed. The review coverage is adequate for this PR.

Codex (response):

Agreement reached. No further changes.

Synthesis

Review synthesis

  • No major disagreement on the main blocker: both reviews flag the compounding exact-out path as unsafe when amountOut >= reserve (A as a missing reserve-bound guard; B as a division-by-zero/negative-denominator bug).
  • Different primary emphasis: A focuses on API correctness for compounding pools, especially nextSqrtPrice being exposed as 0 via LiquidityHandler. B focuses more on swap-result handling, especially applySwapResult mutating nextSqrtPrice and possible fee-accounting confusion.
  • Scope differs: A stays tightly focused on 2 likely blockers. B raises additional secondary issues (possible sqrtPrice.subn(1) underflow, ignored parameter/comment mismatch, switch exhaustiveness, typo/nits).

Most important follow-up action:
Fix and regression-test the compounding exact-out quote flow end-to-end: enforce amountOut < reserve guards in both directions and verify compounding swap results return a valid, non-zero nextSqrtPrice.

Repo checks

Repo Checks

  • pnpm install --frozen-lockfile: ok
Lockfile is up to date, resolution step is skipped
Progress: resolved 1, reused 0, downloaded 0, added 0
Packages: +186
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 186, reused 75, downloaded 0, added 0
Progress: resolved 186, reused 167, downloaded 19, added 185
Progress: resolved 186, reused 167, downloaded 19, added 186, done

dependencies:
+ @coral-xyz/anchor 0.31.1
+ @solana/spl-token 0.4.14
+ @solana/web3.js 1.98.4
+ @types/bn.js 5.2.0
+ bn.js 5.2.2
+ chain 0.4.2
+ decimal.js 10.6.0
+ invariant 2.2.4

devDependencies:
+ @types/invariant 2.2.37
+ prettier 3.7.4
+ solana-bankrun 0.4.0
+ ts-node 10.9.2
+ tsup 8.5.1
+ tsx 4.21.0
+ typescript 5.9.3
+ vitest 4.0.16

╭ Warning ─────────────────────────────────────────────────────────────────────╮
│                                                                              │
│   Ignored build scripts: bigint-buffer, bufferutil, esbuild,                 │
│   utf-8-validate.                                                            │
│   Run "pnpm approve-builds" to pick which dependencies should be allowed     │
│   to run scripts.                                                            │
│                                                                              │
╰──────────────────────────────────────────────────────────────────────────────╯

Done in 2.8s using pnpm v10.15.0

! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-10.15.0.tgz
  • pnpm run lint: ok
> @meteora-ag/cp-amm-sdk@1.3.7 lint /data/workdir/MeteoraAg/damm-v2-sdk
> prettier */*.js "*/**/*{.js,.ts}" --check

Checking formatting...
All matched files use Prettier code style!
  • pnpm run check-types: ok
> @meteora-ag/cp-amm-sdk@1.3.7 check-types /data/workdir/MeteoraAg/damm-v2-sdk
> tsc --noEmit

Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/swapQuote.ts
0xSoju2 pushed a commit to 0xSoju2/damm-v2-sdk that referenced this pull request Mar 7, 2026
…tecture

Following PR MeteoraAg#101's architectural patterns:

**New: src/math/liquidity/ module**
- compoundingLiquidity.ts — all constant-product math isolated here
  (calculateAtoBFromAmountIn, getLiquidityDeltaFromAmountA, etc.)
- concentratedLiquidity.ts — all CLMM math extracted from quote.ts
- liquidityHandler.ts — LiquidityHandler interface + CompoundingLiquidityHandler
  + ConcentratedLiquidityHandler classes + getLiquidityHandler() factory
  + dispatcher functions (getAmountAFromLiquidityDelta, getLiquidityDeltaFromAmountA, etc.)
- index.ts — clean exports

**Renamed: quote.ts → swapQuote.ts (rewritten)**
- Uses getLiquidityHandler(poolState) for polymorphic dispatch
- Added applySwapResult() — recalculates post-swap sqrt price for Compounding pools
  including compoundingFee reinvestment into reserves
- Uses poolState.feeVersion (not .version)
- No if/else Compounding branches — clean handler dispatch throughout

**Updated: shared functions now dispatch by collectFeeMode**
- getLiquidityDeltaFromAmountA/B — threads collectFeeMode
- getAmountAFromLiquidityDelta/B — threads collectFeeMode, tokenAmount, liquidity
- preparePoolCreationParams — accepts collectFeeMode, dispatches correctly
- preparePoolCreationSingleSide — accepts collectFeeMode
- getLiquidityDelta — accepts collectFeeMode
- getDepositQuote — uses handler.getAmountsForModifyLiquidity
- getWithdrawQuote — uses handler.getAmountsForModifyLiquidity

**Updated: types.ts**
- PoolFeesParams.padding: number[] → number, added compoundingFeeBps
- SwapResult2: removed tradingFee, replaced with claimingFee + compoundingFee
- GetDepositQuoteParams/GetWithdrawQuoteParams: added required collectFeeMode,
  tokenAAmount, tokenBAmount, liquidity fields
- LiquidityDeltaParams/PreparePoolCreationParams/PreparePoolCreationSingleSide:
  added collectFeeMode
- Added LiquidityHandler interface, SwapAmountFromInput/Output, InitialPoolInformation
- PoolVersion deprecated, LayoutVersion added (alias for PoolLayoutVersion)

**Removed: operator instructions**
- fixPoolLayoutVersion() removed — operator-only, not client SDK scope

**constants.ts**
- Added DEAD_LIQUIDITY = 100 * 2^64
Comment thread src/math/feeMath.ts Outdated
Comment thread src/math/feeMath.ts Outdated
Comment thread src/helpers/validation.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts Outdated
Comment thread src/types.ts Outdated
Comment thread src/constants.ts Outdated
@dannxbt
Copy link
Copy Markdown
Collaborator Author

dannxbt commented Mar 10, 2026

/bot review

@metoeraag-bot
Copy link
Copy Markdown

metoeraag-bot Bot commented Mar 10, 2026

Bot Agent progress: /bot review

Progress:

  • Repo checks (3 ok, 0 failed)
  • Context build
  • Codex review (1 pass + first look)
  • Buddy review (agreed after 2/10)
  • Post review

Comment thread src/helpers/validation.ts
Comment thread src/helpers/validation.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Copy link
Copy Markdown

@metoeraag-bot metoeraag-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Mostly solid, but five correctness issues remain: the compounding swap helpers still expose a placeholder nextSqrtPrice, the compounding liquidity-delta helpers still rely on ambiguous optional-parameter truthiness, numeric-enum validation still uses overly permissive in checks, negative token amounts can still pass preflight validation, and split percentages still still lack a lower-bound check.

Inline comments

See inline comments on the diff.

Claude (API) review

Rounds: 2 (min=1, max=10).
First look: Codex + Claude (Claude first-look failed; fell back to Codex).
Agreement: yes (no new findings/questions).

Debate transcript

First look comparison

Codex (first look):

Summary:
Mostly solid, but I found one compounding quote bug and a couple of missing lower-bound checks in the new client-side validators.

Inline comment highlights:

  • src/math/liquidity/compoundingLiquidity.ts:109: These compounding swap helpers hard-code nextSqrtPrice to 0. Since this module is exported publicly and SwapAmountFromInput/SwapAmountFromOutput includes that field, any caller consuming it directly will observe an impossible post-swa
  • src/helpers/validation.ts:597: This only rejects the case where both token amounts are non-positive. A negative tokenAAmount with a positive tokenBAmount still passes validation, even though these fields are serialized as unsigned amounts. Please reject negative amou
  • src/helpers/validation.ts:699: validateSplitPositionParams only enforces an upper bound. Negative percentages currently pass this validator and will fail later during serialization/on-chain validation, which defeats the point of the new preflight checks. Please add a `

Codex (first look fallback):

Summary:
Compounding support looks broadly aligned with the release notes, but there are a few runtime holes where the new validation/quote paths can still return misleading results or fail much later than intended.

Inline comment highlights:

  • src/helpers/validation.ts:393: Using in on a numeric TypeScript enum is too permissive here because the compiled enum includes reverse-mapped string keys. Values like "Compounding" or "0" will pass this check at runtime, so JS consumers can bypass the validation an
  • src/helpers/validation.ts:699: This only rejects percentages above 100. Negative values still pass validation, so a JS caller can send -1 here and get a much less obvious encoder/runtime failure later. Please add a lower-bound check (pct < 0) here so splitPosition
  • src/math/liquidity/compoundingLiquidity.ts:109: These compounding swap helpers are exported, but they always return nextSqrtPrice: new BN(0) (same placeholder pattern repeats in the other compounding swap methods below). Any direct consumer of these helpers will get a bogus post-swap p
  • src/math/liquidity/liquidityHandler.ts:327: For compounding mode, this branch silently falls back to the pool-creation formula whenever either reserve or liquidity is missing. That means an incomplete argument list changes the math instead of failing fast, which can produce a plausib

Comparison notes:

Review synthesis

Top differences in emphasis

  1. No major disagreement on the biggest bugs: both reviews independently flag the bogus compounding quote output (nextSqrtPrice = 0) and the missing lower-bound check for split percentages.
  2. Review A focuses more on input lower bounds: it uniquely calls out negative token amounts slipping through validation for unsigned fields.
  3. Review B focuses more on JS/runtime robustness: it uniquely flags the permissive enum check (in on numeric enums) and the compounding-path fallback that should fail fast instead of silently switching formulas.

Most important follow-up action

  • Fix the exported compounding swap helpers to return a real nextSqrtPrice (or fail explicitly) and add regression tests for direct consumers. This is the highest-impact issue because it can produce misleading quote data, not just delayed validation failures.

Round 1

Codex (primary):

Summary:
Mostly solid, but I found one compounding quote bug and a couple of missing lower-bound checks in the new client-side validators.

Inline comment highlights:

  • src/math/liquidity/compoundingLiquidity.ts:109: These compounding swap helpers hard-code nextSqrtPrice to 0. Since this module is exported publicly and SwapAmountFromInput/SwapAmountFromOutput includes that field, any caller consuming it directly will observe an impossible post-swa
  • src/helpers/validation.ts:597: This only rejects the case where both token amounts are non-positive. A negative tokenAAmount with a positive tokenBAmount still passes validation, even though these fields are serialized as unsigned amounts. Please reject negative amou
  • src/helpers/validation.ts:699: validateSplitPositionParams only enforces an upper bound. Negative percentages currently pass this validator and will fail later during serialization/on-chain validation, which defeats the point of the new preflight checks. Please add a `

Claude (API):

Assessment of Primary Review

The primary review correctly identified the three most impactful issues:

  1. Compounding swap nextSqrtPrice: 0 placeholder — valid concern, though the code does have a separate getNextSqrtPrice() override in the handler that computes the real value from reserves. The risk depends on whether downstream code uses the per-swap-step value before the handler override runs.
  2. Negative token amounts passing validation — solid catch at line 597.
  3. Missing lower-bound check on split percentages — solid catch at line 699.

What the primary review missed

  1. Enum in check is too permissive (line 393, 404) — This is a well-known JS/TS footgun with numeric enums that the primary review didn't flag. It weakens the new validation layer for JS consumers.

  2. Silent fallback in compounding liquidity delta functions (liquidityHandler.ts lines 327, 368, 403, 448) — The optional-parameter truthiness pattern conflates "caller forgot to pass reserves" with "pool creation mode". This is a design-level issue that the primary review missed entirely.

What the primary review got right

All three findings are legitimate. The nextSqrtPrice: 0 issue is the most impactful for direct consumers of the exported functions, though the handler abstraction partially mitigates it for the main quote paths.

Codex (response):

  • New findings applied: 3/3
  • Open questions kept for author: 1/1

Round 2

Codex (primary):

Summary:
Mostly solid, but I still see five correctness issues: the compounding swap helpers expose a placeholder nextSqrtPrice, the compounding liquidity-delta helpers rely on ambiguous optional-parameter truthiness, numeric-enum validation uses overly permissive in checks, negative token amounts can still pass preflight validation, and split percentages still have no lower-bound check.

Inline comment highlights:

  • src/math/liquidity/compoundingLiquidity.ts:109: This helper returns nextSqrtPrice as 0. Because SwapAmountFromInput/SwapAmountFromOutput exposes that field and this module is exported publicly, any direct caller—or any generic quote/price-impact logic that reads nextSqrtPrice bef
  • src/math/liquidity/liquidityHandler.ts:327: Using optional BN truthiness to choose between the pool-creation formula and the compounding formula is unsafe. If the caller forgets to pass the existing-pool reserves, this silently falls back to the creation path instead of rejecting t
  • src/helpers/validation.ts:393: in on a compiled numeric enum is too permissive at runtime: reverse-mapped keys like "0" or "Compounding" also return true. That means JS callers can pass string representations and bypass the intended validation. Please replace this
  • src/helpers/validation.ts:597: Negative token amounts slip through because this only rejects the case where both amounts are non-positive. These fields are serialized as unsigned amounts, so please add individual < 0 checks before the existing "at least one amount > 0"
  • src/helpers/validation.ts:699: validateSplitPositionParams only enforces an upper bound. Negative percentages currently pass this validator and will fail later during serialization/on-chain validation, which defeats the point of the new preflight checks. Please add a `

Claude (API):

Assessment

The primary review's five findings are all legitimate and well-targeted. All three new findings from the prior critique round were accepted (3/3), and the open question about nextSqrtPrice consumption was kept for the author (1/1).

After reviewing the full diff again against the primary review and prior critique:

  1. Enum in check (line 393, 404) — already accepted, correctly identified.
  2. Optional BN truthiness (line 327 etc.) — already accepted, correctly identified.
  3. Negative token amounts (line 597) — already accepted, correctly identified.
  4. nextSqrtPrice: 0 placeholder (compoundingLiquidity.ts:109) — already flagged by primary review.
  5. Split percentage lower bound (line 699) — already flagged by primary review.

I don't see additional issues that weren't already covered by the combined primary + prior critique findings, and I don't see false positives in the primary review's current set of findings. The coverage is comprehensive for the scope of this PR.

Codex (response):

Agreement reached. No further changes.

Synthesis

Review synthesis

Top differences in emphasis

  1. No major disagreement on the biggest bugs: both reviews independently flag the bogus compounding quote output (nextSqrtPrice = 0) and the missing lower-bound check for split percentages.
  2. Review A focuses more on input lower bounds: it uniquely calls out negative token amounts slipping through validation for unsigned fields.
  3. Review B focuses more on JS/runtime robustness: it uniquely flags the permissive enum check (in on numeric enums) and the compounding-path fallback that should fail fast instead of silently switching formulas.

Most important follow-up action

  • Fix the exported compounding swap helpers to return a real nextSqrtPrice (or fail explicitly) and add regression tests for direct consumers. This is the highest-impact issue because it can produce misleading quote data, not just delayed validation failures.
Repo checks

Repo Checks

  • LLM checks planner: added package install step before running JS commands.

  • pnpm install --frozen-lockfile: ok

Lockfile is up to date, resolution step is skipped
Already up to date

╭ Warning ─────────────────────────────────────────────────────────────────────╮
│                                                                              │
│   Ignored build scripts: bigint-buffer, bufferutil, esbuild,                 │
│   utf-8-validate.                                                            │
│   Run "pnpm approve-builds" to pick which dependencies should be allowed     │
│   to run scripts.                                                            │
│                                                                              │
╰──────────────────────────────────────────────────────────────────────────────╯

Done in 1.1s using pnpm v10.15.0

! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-10.15.0.tgz
  • pnpm run lint: ok
> @meteora-ag/cp-amm-sdk@1.3.7 lint /data/workdir/MeteoraAg/damm-v2-sdk
> prettier */*.js "*/**/*{.js,.ts}" --check

Checking formatting...
All matched files use Prettier code style!
  • pnpm run check-types: ok
> @meteora-ag/cp-amm-sdk@1.3.7 check-types /data/workdir/MeteoraAg/damm-v2-sdk
> tsc --noEmit

Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/liquidityHandler.ts
Comment thread src/helpers/validation.ts Outdated
Comment thread src/helpers/validation.ts
Comment thread src/helpers/validation.ts Outdated
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/compoundingLiquidity.ts
Comment thread src/math/liquidity/liquidityHandler.ts
Comment thread src/math/liquidity/concentratedLiquidity.ts
Comment thread src/math/poolFees/baseFee/baseFeesHandler.ts
Comment thread src/math/poolFees/baseFee/baseFeesHandler.ts
Comment thread src/math/feeMath.ts
Comment thread src/math/feeMath.ts
Comment thread src/math/swapQuote.ts
Comment thread src/math/swapQuote.ts
@dannxbt dannxbt merged commit 8852aa0 into main Mar 13, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants