跳转到主要内容
本页代码示例使用 bondingCurve 合约实例进行报价计算。其地址可通过 MemeFactory.bondingCurve() 获取。详见合约概览

买入代币

发送 KAS 到 MemeFactory.buy() 以获得代币。
function buy(address token, uint256 minTokensOut) external payable;
参数说明
token代币合约地址
minTokensOut最少接收代币数量(滑点保护)
msg.value花费的 KAS 数量(wei)
const kasAmount = ethers.parseEther("100"); // 100 KAS

// 1. 先获取报价
const tokensOut = await bondingCurve.calculateBuyReturnWithParams(
  kasAmount, tokenReserves, kasReserves, vToken, vKas
);

// 2. 应用滑点(例如 20%)
const minTokensOut = tokensOut * 80n / 100n;

// 3. 执行买入
const tx = await factory.buy(tokenAddress, minTokensOut, {
  value: kasAmount,
});
await tx.wait();

Buy 事件

event Buy(
    address indexed token,
    address indexed buyer,
    uint256 kasAmount,
    uint256 tokenAmount,
    uint256 fee
);

卖出代币

通过 MemeFactory.sell() 卖出代币换回 KAS。
function sell(address token, uint256 tokenAmount, uint256 minKasOut) external;
参数说明
token代币合约地址
tokenAmount卖出的代币数量(wei)
minKasOut最少接收 KAS 数量(滑点保护)
卖出前,必须先 approve MemeFactory 合约花费你的代币。
const tokenAmount = ethers.parseEther("1000000"); // 100 万代币

// 1. 授权 MemeFactory 花费代币
const tokenContract = new ethers.Contract(tokenAddress, [
  "function approve(address spender, uint256 amount) returns (bool)",
], signer);
const approveTx = await tokenContract.approve(FACTORY_ADDRESS, tokenAmount);
await approveTx.wait();

// 2. 获取报价
const kasOut = await bondingCurve.calculateSellReturnWithParams(
  tokenAmount, tokenReserves, kasReserves, vToken, vKas
);

// 3. 应用滑点(例如 20%)
const minKasOut = kasOut * 80n / 100n;

// 4. 执行卖出
const tx = await factory.sell(tokenAddress, tokenAmount, minKasOut);
await tx.wait();

Sell 事件

event Sell(
    address indexed token,
    address indexed seller,
    uint256 tokenAmount,
    uint256 kasAmount,
    uint256 fee
);

滑点保护

始终设置 minTokensOut(买入)或 minKasOut(卖出)以防止报价和执行之间的价格变化。
滑点乘数适用场景
5%quote * 95 / 100低波动性
20%quote * 80 / 100常规(推荐)
50%quote * 50 / 100高波动性 / 大额订单
KasFun 网站默认使用 20% 滑点。程序化交易时,请根据代币的波动性和你的订单相对于池储备的大小进行调整。

完整交易流程

import { ethers } from "ethers";

const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

const FACTORY = "0x5F65Df9DCf7d764CA9d319Baf89611d289546A81";

const factory = new ethers.Contract(FACTORY, [
  "function buy(address token, uint256 minTokensOut) payable",
  "function sell(address token, uint256 tokenAmount, uint256 minKasOut)",
  "function getTokenInfo(address token) view returns (tuple(uint256 tokenId, address creator, address pool, uint256 tokenReserves, uint256 kasReserves, uint256 createdAt, bool fulfilled, bool graduated, string metadataUri, uint256 paramVersion))",
  "function getTokenParamVersion(address token) view returns (tuple(uint256 graduationThreshold, uint256 virtualToken, uint256 virtualKas, uint160 sqrtPriceX96Token0, uint160 sqrtPriceX96Token1, bool active))",
  "function bondingCurve() view returns (address)",
], signer);

// 获取 BondingCurve 地址
const bcAddress = await factory.bondingCurve();
const bc = new ethers.Contract(bcAddress, [
  "function calculateBuyReturnWithParams(uint256,uint256,uint256,uint256,uint256) pure returns (uint256)",
  "function calculateSellReturnWithParams(uint256,uint256,uint256,uint256,uint256) pure returns (uint256)",
], provider);

const TOKEN = "0x..."; // 你的代币地址

// 读取当前状态
const info = await factory.getTokenInfo(TOKEN);
const params = await factory.getTokenParamVersion(TOKEN);

// --- 买入 ---
const kasIn = ethers.parseEther("100");
const buyReturn = await bc.calculateBuyReturnWithParams(
  kasIn,
  info.tokenReserves,
  info.kasReserves,
  params.virtualToken,
  params.virtualKas
);
const minTokens = buyReturn * 80n / 100n; // 20% 滑点
const buyTx = await factory.buy(TOKEN, minTokens, { value: kasIn });
await buyTx.wait();

// --- 卖出 ---
const tokensIn = ethers.parseEther("500000");
const sellReturn = await bc.calculateSellReturnWithParams(
  tokensIn,
  info.tokenReserves,
  info.kasReserves,
  params.virtualToken,
  params.virtualKas
);
const minKas = sellReturn * 80n / 100n; // 20% 滑点

// 先授权
const token = new ethers.Contract(TOKEN, [
  "function approve(address,uint256) returns (bool)",
], signer);
await (await token.approve(FACTORY, tokensIn)).wait();

const sellTx = await factory.sell(TOKEN, tokensIn, minKas);
await sellTx.wait();
Bonding Curve 交易仅在代币未毕业时可用(info.fulfilled === false)。一旦 fulfilled,buy/sell 将会 revert。