The BondingCurve contract address can be obtained from MemeFactory.bondingCurve(). See Contract Overview for details.
KasFun uses a constant-product bonding curve (similar to Uniswap V2), enhanced with virtual reserves:
(tokenReserves + virtualToken) * (kasReserves + virtualKas) = k
The virtual reserves set the initial price and curve shape without requiring seed liquidity.
Getting Curve Parameters
Before calculating prices, fetch the token’s current state and curve parameters:
// 1. Current reserves
const info = await factory.getTokenInfo(tokenAddress);
const { tokenReserves, kasReserves } = info;
// 2. Virtual parameters
const params = await factory.getTokenParamVersion(tokenAddress);
const { virtualToken, virtualKas, graduationThreshold } = params;
Price Calculation Functions
The BondingCurve contract provides three pure calculation functions:
Calculate Buy Return
How many tokens will I get for a given KAS amount?
function calculateBuyReturnWithParams(
uint256 kasIn,
uint256 tokenReserves,
uint256 kasReserves,
uint256 vToken,
uint256 vKas
) pure returns (uint256 tokensOut)
const kasIn = ethers.parseEther("100"); // 100 KAS
const tokensOut = await bondingCurve.calculateBuyReturnWithParams(
kasIn,
info.tokenReserves,
info.kasReserves,
params.virtualToken,
params.virtualKas
);
console.log("Tokens out:", ethers.formatEther(tokensOut));
Calculate Sell Return
How much KAS will I get for selling a given amount of tokens?
function calculateSellReturnWithParams(
uint256 tokensIn,
uint256 tokenReserves,
uint256 kasReserves,
uint256 vToken,
uint256 vKas
) pure returns (uint256 kasOut)
const tokensIn = ethers.parseEther("1000000"); // 1M tokens
const kasOut = await bondingCurve.calculateSellReturnWithParams(
tokensIn,
info.tokenReserves,
info.kasReserves,
params.virtualToken,
params.virtualKas
);
console.log("KAS out:", ethers.formatEther(kasOut));
Calculate Buy Cost
How much KAS do I need to spend to get a specific amount of tokens?
function calculateBuyCostWithParams(
uint256 tokensOut,
uint256 tokenReserves,
uint256 kasReserves,
uint256 vToken,
uint256 vKas
) pure returns (uint256 kasIn)
const desiredTokens = ethers.parseEther("1000000"); // I want 1M tokens
const kasNeeded = await bondingCurve.calculateBuyCostWithParams(
desiredTokens,
info.tokenReserves,
info.kasReserves,
params.virtualToken,
params.virtualKas
);
console.log("KAS needed:", ethers.formatEther(kasNeeded));
Current Price
Get the current token price (KAS per token):
// Via MemeFactory (convenience)
const price = await factory.getCurrentPrice(tokenAddress);
// Via BondingCurve (from reserves)
const price = await bondingCurve.getCurrentPrice(
info.tokenReserves,
info.kasReserves
);
console.log("Price:", ethers.formatEther(price), "KAS per token");
Price Impact
For large trades, the price impact can be significant. Calculate it by comparing the effective price with the current price:
const kasIn = ethers.parseEther("1000"); // 1000 KAS
const tokensOut = await bondingCurve.calculateBuyReturnWithParams(
kasIn, tokenReserves, kasReserves, vToken, vKas
);
const effectivePrice = kasIn * BigInt(1e18) / tokensOut; // KAS per token
const currentPrice = await factory.getCurrentPrice(tokenAddress);
const priceImpact = Number(effectivePrice - currentPrice) / Number(currentPrice) * 100;
console.log(`Price impact: ${priceImpact.toFixed(2)}%`);
When kasIn is very small relative to kasReserves, the price impact approaches zero and the effective price approaches the spot price.
Graduation Threshold
Each token has a graduationThreshold in its curve parameters. When kasReserves >= graduationThreshold, the token graduates:
const params = await factory.getTokenParamVersion(tokenAddress);
const info = await factory.getTokenInfo(tokenAddress);
const remaining = params.graduationThreshold - info.kasReserves;
console.log("KAS until graduation:", ethers.formatEther(remaining));