Cdpm calculation skill
npx -y skills add RandyPen/cdpm --skill cdpm-calculation-skillAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
CDPM calculation utilities using Cetus DLMM SDK plus the Scallop and Kai SAV lending math used by scallop_supply / scallop_redeem / kai_supply / kai_redeem. Provides liquidity calculation, bin price math, position management, fee calculations, and yield-fee accounting for both lending integrations. Use when performing mathematical operations for CDPM positions.
SKILL.md
8.7 KB, ~2.3k tokens by cl100k_base, as published. Nobody here has run it
CDPM Calculation Guide
Overview
This skill provides calculation utilities for CDPM (Cetus DLMM Position Manager) using the Cetus DLMM SDK, plus off-chain twins of both lending integrations' upstream math — Scallop (scallop_*) and Kai SAV (kai_*). All Cetus calculations should use the SDK for accuracy and to handle edge cases properly; the Scallop and Kai formulas mirror the upstream protocol::mint / protocol::redeem and kai_vault::deposit / kai_vault::withdraw math that cdpm composes into single-call entries. The two integrations share pm.lending: Bag, the same fee_house.fee_rate knob, and the same principal-amortization shape — only the predictors differ (Scallop reads balance_sheet, Kai reads total_available_balance + total_yt_supply).
Installation
npm install @cetusprotocol/dlmm-sdk
SDK Imports
import { BinUtils, FeeUtils } from '@cetusprotocol/dlmm-sdk/utils'
Topics
Core Calculations
- Liquidity Calculation — Constant-sum formula,
getLiquidity,calculateOutByShare. - Strategy Distributions —
Spot/Curve/BidAskweights (MAX=2000,MIN=200), single-sided fallback,StrategyUtils.toAmountsBothSideByStrategy/autoFillCoinByStrategy. - Bin Price Calculations — Bin ↔ price conversions, Q64x64 price.
- Position Management — Position count, split bins into positions.
- Fee Calculations — Variable / protocol / composition fee.
- Position Query — Query PositionManager assets, fees, rewards.
Lending Math (Scallop & Kai SAV)
- Scallop Lending Math —
predictScallopMint/predictScallopRedeem, principal amortization, yield-fee deduction, redemption sizing (inverse formulas + worked example), live supply APY via@scallop-io/sui-scallop-sdk, Scallop-vs-Kai picker. - Kai SAV Lending Math —
predictKaiDeposit/predictKaiWithdrawfor<T, YT>vaults; live APY via@kunalabs-io/kai. - Cross-Protocol PTB (cdpm + Scallop + Kai) — Mysten-rooted shared-
Transactionpattern, approach comparison table, atomic Scallop ↔ Kai rebalance, dust-prediction patterns when composing redeem → add-liquidity.
Advanced Topics
- Price Conversion - Compare CDPM prices with external exchanges
Reference
- Token Constants - Common token addresses
- SDK Constants - SDK configuration constants
- Error Reference - Common errors and solutions
Complete Examples
Example 1: Create Position Calculation
import { BinUtils } from '@cetusprotocol/dlmm-sdk/utils'
async function calculatePosition(
poolInfo: { bin_step: number; active_bin_id: number },
tokenADecimals: number,
tokenBDecimals: number,
depositA: string,
depositB: string,
slippagePercent: number
) {
const { bin_step, active_bin_id } = poolInfo
// 1. Get current price
const currentPrice = BinUtils.getPriceFromBinId(
active_bin_id,
bin_step,
tokenADecimals,
tokenBDecimals
)
// 2. Calculate price range with slippage
const minPrice = (parseFloat(currentPrice) * (1 - slippagePercent / 100)).toString()
const maxPrice = (parseFloat(currentPrice) * (1 + slippagePercent / 100)).toString()
// 3. Get bin IDs
const lowerBinId = BinUtils.getBinIdFromPrice(
minPrice, bin_step, true, tokenADecimals, tokenBDecimals
)
const upperBinId = BinUtils.getBinIdFromPrice(
maxPrice, bin_step, false, tokenADecimals, tokenBDecimals
)
// 4. Calculate position count
const positionCount = BinUtils.getPositionCount(lowerBinId, upperBinId)
// 5. Distribute liquidity
const binCount = upperBinId - lowerBinId + 1
const amountAPerBin = (BigInt(depositA) / BigInt(binCount)).toString()
const amountBPerBin = (BigInt(depositB) / BigInt(binCount)).toString()
// 6. Calculate total liquidity
const activeQPrice = BinUtils.getQPriceFromId(active_bin_id, bin_step)
const totalLiquidity = BinUtils.getLiquidity(depositA, depositB, activeQPrice)
return {
lowerBinId,
upperBinId,
positionCount,
totalLiquidity,
bins: Array.from({ length: binCount }, (_, i) => ({
binId: lowerBinId + i,
amountA: amountAPerBin,
amountB: amountBPerBin
}))
}
}
Example 2: Remove Liquidity Calculation
function calculateRemoval(
positionBins: Array<{
binId: number
amountA: string
amountB: string
liquidity: string
}>,
percentage: number // 0-100
): Array<{ binId: number; amountA: string; amountB: string }> {
const results = []
for (const bin of positionBins) {
const removeLiquidity = (BigInt(bin.liquidity) * BigInt(percentage) / 100n).toString()
const { amount_a, amount_b } = BinUtils.calculateOutByShare(
{ amount_a: bin.amountA, amount_b: bin.amountB, liquidity: bin.liquidity },
removeLiquidity
)
results.push({
binId: bin.binId,
amountA: amount_a,
amountB: amount_b
})
}
return results
}
Example 3: Rebalancing Calculation
async function calculateRebalance(
currentBins: Array<{ binId: number; liquidity: string }>,
targetActiveBinId: number,
rangeWidth: number,
binStep: number
) {
const lowerBinId = targetActiveBinId - rangeWidth
const upperBinId = targetActiveBinId + rangeWidth
// 1. Calculate total liquidity
let totalLiquidity = 0n
for (const bin of currentBins) {
totalLiquidity += BigInt(bin.liquidity)
}
// 2. Calculate new distribution
const targetBinCount = rangeWidth * 2 + 1
const liquidityPerBin = (totalLiquidity / BigInt(targetBinCount)).toString()
// 3. Get amounts needed for each bin
const targetBins = []
for (let i = 0; i < targetBinCount; i++) {
const binId = lowerBinId + i
const qPrice = BinUtils.getQPriceFromId(binId, binStep)
// For equal distribution, amounts depend on price
// amount_a = liquidity / (2 * price), amount_b = liquidity / 2
const amountA = (BigInt(liquidityPerBin) / (2n * BigInt(qPrice) >> 64n)).toString()
const amountB = (BigInt(liquidityPerBin) / 2n).toString()
targetBins.push({ binId, amountA, amountB, liquidity: liquidityPerBin })
}
// 4. Calculate positions needed
const positionCount = BinUtils.getPositionCount(lowerBinId, upperBinId)
return { targetBins, positionCount }
}
Best Practices
1. Always Use SDK Utils
// Good - Use SDK
import { BinUtils } from '@cetusprotocol/dlmm-sdk/utils'
const liquidity = BinUtils.getLiquidity(amountA, amountB, qPrice)
// Bad - Manual calculation
const liquidity = (BigInt(price) * BigInt(amountA)) + (BigInt(amountB) << 64n)
2. Pass Amounts as Strings
// Good - String format
const liquidity = BinUtils.getLiquidity('1000000', '1200000', qPrice)
// Bad - Number format (precision loss)
const liquidity = BinUtils.getLiquidity(1000000, 1200000, qPrice)
3. Cache QPrice
// Good - Cache QPrice
const qPriceCache = new Map()
function getCachedQPrice(binId: number, binStep: number) {
const key = `${binId}-${binStep}`
if (!qPriceCache.has(key)) {
qPriceCache.set(key, BinUtils.getQPriceFromId(binId, binStep))
}
return qPriceCache.get(key)
}
4. Validate Inputs
function validateBinRange(lowerBinId: number, upperBinId: number) {
if (lowerBinId >= upperBinId) {
throw new Error('Invalid range: lower must be less than upper')
}
if (upperBinId - lowerBinId > 1000) {
throw new Error('Range too large: max 1000 bins')
}
}
5. Handle Errors
try {
const binId = BinUtils.getBinIdFromPrice(price, binStep, true, decimalsA, decimalsB)
} catch (error) {
console.error('Failed to calculate bin ID:', error)
// Fallback or retry logic
}
Related Skills
cdpm-user-sdk- User operations guidecdpm-agent-sdk- Agent automation strategiescdpm-protocol-sdk- Protocol integration guidecetus-dlmm-sdk-skill- Full Cetus DLMM SDK documentation
What ships with it: 13 files
142.8 KB alongside SKILL.md
reference/
- bin-price-calculations.md1.2 KB
- cross-protocol-ptb.md20.0 KB
- error-reference.md5.4 KB
- fee-calculations.md2.4 KB
- kai-lending-math.md33.0 KB
- liquidity-calculation.md1.5 KB
- position-management.md1.5 KB
- position-query.md14.6 KB
- price-conversion.md5.9 KB
- scallop-lending-math.md35.0 KB
- sdk-constants.md361 B
- strategy-distributions.md21.5 KB
- token-constants.md497 B