← Docs / API-CreateToken.25-03-2026.md ⬇ Download

Create Token Guide

Overview

This guide walks you through the complete flow of creating a new token on the Bullshot Protocol — from reading fee parameters to calling createToken on-chain.


Flow Summary

Step Action Description
1 Read fee params Fetch creationFeeAmount, buyFeePercent, FEE_DENOMINATOR from BullshotFactory
2 Calculate msg.value initAmountIn + buyFee + creationFee
3 Call createToken Deploy a new BCToken + BondingCurve pair
4 Listen for Created event Get the new token and bonding curve addresses
5 (Optional) Buy more tokens Call bondingCurve.buy() with additional BNB

Step 1 — Read Fee Parameters

const factory = new ethers.Contract(FACTORY_ADDRESS, BullshotFactoryABI, provider);

const creationFeeAmount = await factory.creationFeeAmount(); // 150000000000000 wei = 0.00015 BNB
const buyFeePercent     = await factory.buyFeePercent();     // 10 = 1%
const FEE_DENOMINATOR   = 1000;

Current live values:


Step 2 — Calculate msg.value

Without initial buy

const initAmountIn = ethers.constants.Zero;
const msgValue = creationFeeAmount; // just the creation fee

With initial buy (e.g. 0.5 BNB)

const initAmountIn = ethers.utils.parseEther("0.5");
const buyFee = initAmountIn.mul(buyFeePercent).div(FEE_DENOMINATOR);
const msgValue = initAmountIn.add(buyFee).add(creationFeeAmount);

Formula:

msg.value = initAmountIn
          + (initAmountIn × buyFeePercent / FEE_DENOMINATOR)
          + creationFeeAmount

Step 3 — Call createToken

function createToken(
    string memory name,
    string memory ticker,
    uint256 initAmountIn
) external payable
const signer = provider.getSigner();
const factory = new ethers.Contract(FACTORY_ADDRESS, BullshotFactoryABI, signer);

const tx = await factory.createToken(
    "Bullshot",   // token name
    "BULL",       // ticker symbol
    initAmountIn, // BNB to spend on initial buy (0 = skip)
    { value: msgValue }
);

const receipt = await tx.wait();

Step 4 — Get token and bonding curve addresses from the Created event

// Parse the Created event from the receipt
const iface = new ethers.utils.Interface(BullshotFactoryABI);

let bondingCurveAddress, tokenAddress;
for (const log of receipt.logs) {
    try {
        const parsed = iface.parseLog(log);
        if (parsed.name === "Created") {
            bondingCurveAddress = parsed.args.bondingCurve;
            tokenAddress        = parsed.args.token;
            console.log("BondingCurve:", bondingCurveAddress);
            console.log("Token:", tokenAddress);
        }
    } catch (_) {}
}

Step 5 — (Optional) Buy Additional Tokens

After token creation, the bonding curve is live and ready for trading.

const bondingCurve = new ethers.Contract(bondingCurveAddress, BondingCurveABI, signer);

const additionalBuy = ethers.utils.parseEther("0.1"); // 0.1 BNB
const additionalFee = additionalBuy.mul(buyFeePercent).div(FEE_DENOMINATOR);
const buyMsgValue   = additionalBuy.add(additionalFee);

// Pre-calculate expected output
const [expectedOut] = await bondingCurve.calcBuyExactIn(additionalBuy);
const minOut = expectedOut.mul(95).div(100); // 5% slippage

const deadline = Math.floor(Date.now() / 1000) + 60;

const buyTx = await bondingCurve.buy(
    additionalBuy,
    minOut,
    signerAddress,
    deadline,
    { value: buyMsgValue }
);
await buyTx.wait();

Parameter Reference

createToken Parameters

Parameter Type Description Example
name string Full token name "Bullshot"
ticker string Token symbol / ticker "BULL"
initAmountIn uint256 BNB to spend on initial buy (excluding fee). Pass 0 to skip ethers.utils.parseEther("0.5")
msg.value uint256 Must equal initAmountIn + buyFee + creationFeeAmount Calculated above

Fixed Protocol Parameters (Set by owner, cannot be changed by creator)

Parameter Description
totalSupply Always 1,000,000,000 tokens (18 decimals)
tokenReserve 800M tokens available for sale on bonding curve
lpTokens 200M tokens reserved for PancakeSwap LP at launch
launchThreshold ~24 BNB collected triggers DEX migration
virtualEthReserve (initial) 6 BNB (sets starting price)

Complete Example (JavaScript / ethers.js v5)

const { ethers } = require("ethers");
const BullshotFactoryABI = require("./BullshotFactory.abi.json");
const BondingCurveABI    = require("./BondingCurve.abi.json");

const FACTORY_ADDRESS = "0x..."; // deployed BullshotFactory address
const RPC_URL = "https://bsc-dataseed.binance.org/";

async function createToken(privateKey, name, ticker, initBnbAmount) {
    const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
    const signer   = new ethers.Wallet(privateKey, provider);
    const factory  = new ethers.Contract(FACTORY_ADDRESS, BullshotFactoryABI, signer);

    // Read fee params
    const creationFeeAmount = await factory.creationFeeAmount();
    const buyFeePercent     = await factory.buyFeePercent();
    const FEE_DENOMINATOR   = 1000;

    // Calculate msg.value
    const initAmountIn = ethers.utils.parseEther(initBnbAmount.toString());
    const buyFee       = initAmountIn.mul(buyFeePercent).div(FEE_DENOMINATOR);
    const msgValue     = initAmountIn.add(buyFee).add(creationFeeAmount);

    console.log(`Creating token "${name}" (${ticker})`);
    console.log(`Initial buy: ${initBnbAmount} BNB`);
    console.log(`Total msg.value: ${ethers.utils.formatEther(msgValue)} BNB`);

    // Send transaction
    const tx      = await factory.createToken(name, ticker, initAmountIn, { value: msgValue });
    const receipt = await tx.wait();

    // Parse Created event
    const iface = new ethers.utils.Interface(BullshotFactoryABI);
    for (const log of receipt.logs) {
        try {
            const parsed = iface.parseLog(log);
            if (parsed.name === "Created") {
                console.log("\nToken created successfully!");
                console.log("BondingCurve:", parsed.args.bondingCurve);
                console.log("Token:", parsed.args.token);
                console.log("Creator:", parsed.args.creator);
                return {
                    bondingCurve: parsed.args.bondingCurve,
                    token: parsed.args.token
                };
            }
        } catch (_) {}
    }
}

// Example: Create "Bullshot" token with 0.5 BNB initial buy
createToken(process.env.PRIVATE_KEY, "Bullshot", "BULL", 0.5);

Notes

  1. Wrong value error: If msg.value doesn't match the formula exactly, the transaction reverts with "Wrong value". Always read fee params on-chain before sending.
  2. Gas: Token creation involves deploying two ERC1167 proxies and optionally executing a buy. Estimate gas before sending.
  3. Pair address: The pair field in the Created event is always address(0). The actual PancakeSwap pair is created lazily on the first post-creation buy.
  4. Name and ticker: These are free-form strings. No validation is performed on-chain. Choose wisely.
  5. Immediate buy: Setting initAmountIn > 0 performs an initial buy in the same transaction as token creation — the creator gets the first tokens at the lowest price.