npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@exponent-labs/market-three-math

v0.1.8

Published

Mathematical simulation package for Exponent CLMM (Concentrated Liquidity Market Maker) markets.

Readme

@exponent-labs/market-three-math

Mathematical simulation package for Exponent CLMM (Concentrated Liquidity Market Maker) markets.

Overview

This package provides TypeScript implementations of the CLMM mathematical functions from the Exponent protocol. It enables client-side simulation of:

  • Swap operations: Simulate PT ↔ SY trades with accurate pricing and fee calculations
  • Liquidity deposits: Calculate required token amounts for concentrated liquidity positions
  • Price calculations: Convert between effective prices, implied rates, and tick indices

The implementations are direct ports from the Rust on-chain program code in solana/programs/exponent_clmm.

Installation

yarn add @exponent-labs/market-three-math

Usage

Simulating a Swap

import { MarketThreeState, SwapDirection, simulateSwap } from "@exponent-labs/market-three-math"

// Prepare market state
const marketState: MarketThreeState = {
  financials: {
    expirationTs: Date.now() / 1000 + 86400, // 1 day from now
    ptBalance: 1000000,
    syBalance: 1000000,
    liquidityBalance: 1000000,
  },
  configurationOptions: {
    lnFeeRateRoot: 0.001,
    rateScalarRoot: 5.0,
    treasuryFeeBps: 2000, // 20%
    lastLnImpliedRate: 0.05,
    epsilonClamp: 0.000001,
    minLpTickAmount: 1000,
    maxLpSupply: 10000000000,
    tickSpace: 100,
    priceDecimals: 4,
  },
  ticks: {
    currentTick: 500,
    currentSpotPrice: 0.05,
    feeGrowthIndexGlobalPt: 0,
    feeGrowthIndexGlobalSy: 0,
    ticks: [
      // ... tick data
    ],
    market: "marketAddress",
  },
  currentSyExchangeRate: 1.0,
}

// Simulate buying PT with SY
const swapResult = simulateSwap(marketState, {
  direction: SwapDirection.SyToPt,
  amountIn: 100000, // 100k SY
  syExchangeRate: 1.0,
  isCurrentFlashSwap: false,
  priceSpotLimit: 0.06, // Maximum price willing to pay
})

console.log("PT received:", swapResult.amountOut)
console.log("Fees paid:", swapResult.lpFeeChargedOutToken + swapResult.protocolFeeChargedOutToken)
console.log("Final price:", swapResult.finalSpotPrice)

Simulating Liquidity Deposit

import { estimateBalancedDeposit, simulateAddLiquidity } from "@exponent-labs/market-three-math"

// Estimate balanced amounts for a target liquidity
const { ptNeeded, syNeeded } = estimateBalancedDeposit(
  marketState,
  100000, // Target liquidity
  4.5, // Lower tick APY (%)
  5.5, // Upper tick APY (%)
)

// Simulate the actual deposit
const depositResult = simulateAddLiquidity(marketState, {
  lowerTick: 45000, // 4.5% in basis points
  upperTick: 55000, // 5.5% in basis points
  maxSy: syNeeded,
  maxPt: ptNeeded,
  syExchangeRate: 1.0,
})

console.log("Liquidity added:", depositResult.deltaL)
console.log("PT spent:", depositResult.ptSpent)
console.log("SY spent:", depositResult.sySpent)

Working with Effective Prices

import { EffSnap, normalizedTimeRemaining } from "@exponent-labs/market-three-math"

const secondsRemaining = 86400 // 1 day
const syExchangeRate = 1.0

const snap = new EffSnap(normalizedTimeRemaining(secondsRemaining), syExchangeRate)

// Convert ln implied rate to effective price
const lnImpliedRate = 0.05 // 5%
const effectivePrice = snap.getEffectivePrice(lnImpliedRate)

// Convert back from effective price to implied rate
const recoveredRate = snap.impliedRateFromEffectivePrice(effectivePrice)

Key Concepts

Effective Price Model

The CLMM uses an effective price model where:

C = e^(-τ * u) / r

Where:

  • C = effective price (PT per SY)
  • τ = time factor (normalized time to expiry)
  • u = ln implied rate (spot price)
  • r = SY exchange rate

Tick-Based Liquidity

Liquidity is concentrated in tick ranges, similar to Uniswap v3:

  • Each tick represents a specific implied rate
  • Liquidity is active only when the current price is within the tick range
  • Ticks store principal PT and SY for accurate accounting

Fee Structure

Fees are calculated as:

  • LP fee: Retained by liquidity providers
  • Protocol fee: Sent to treasury (typically 20% of total fee)
  • Total fee rate increases as expiration approaches

API Reference

Types

  • MarketThreeState: Complete market state required for simulations
  • SwapArgs: Arguments for swap simulation
  • SwapOutcome: Results of a swap simulation
  • AddLiquidityArgs: Arguments for liquidity deposit simulation
  • AddLiquidityOutcome: Results of liquidity deposit simulation
  • Tick: Individual tick data structure
  • Ticks: Complete ticks array with metadata

Functions

Swap Functions

  • simulateSwap(marketState, args): Simulate a swap operation
  • getSwapQuote(marketState, amountIn, direction): Quick quote for a swap

Liquidity Functions

  • simulateAddLiquidity(marketState, args): Simulate liquidity deposit
  • estimateBalancedDeposit(marketState, targetLiquidity, lowerTickApy, upperTickApy): Estimate balanced PT/SY amounts
  • computeLiquidityTargetAndTokenNeeds(...): Low-level liquidity calculation

Utility Functions

  • EffSnap: Effective price snapshot class
  • calculateFeeRate(lnFeeRateRoot, secondsRemaining): Calculate current fee rate
  • normalizedTimeRemaining(secondsRemaining): Normalize time to [0,1]
  • getLnImpliedRate(tickKey): Convert tick key to implied rate
  • convertApyToApyBp(apyPercent) / convertApyBpToApy(apyBp): APY conversion utilities

Relationship to On-Chain Code

This package is a direct port of the Rust implementations from:

  • solana/programs/exponent_clmm/src/state/market_three/helpers/swap.rs
  • solana/programs/exponent_clmm/src/state/market_three/helpers/add_liquidity.rs
  • solana/programs/exponent_clmm/src/utils/math.rs

The TypeScript implementations maintain mathematical equivalence with the on-chain code to ensure accurate simulations.

License

AGPL-3.0