← Docs / API-Contract-BullshotFactory.md ⬇ Download

BullshotFactory Contract API Documentation

Overview

BullshotFactory is the main entry point of the Bullshot Protocol. It deploys BCToken and BondingCurve contracts using ERC1167 minimal proxy cloning (gas-efficient), tracks all created tokens, and emits global Buy/Sell events forwarded from individual bonding curves.

Key Features:


Constants

Name Type Value Description
FEE_DENOMINATOR uint16 1000 Denominator for fee calculations (per-mille)

State Variables

Fee Configuration

Name Type Visibility Current Value Description
buyFeePercent uint8 public 10 (= 1%) Fee charged on buys. Expressed in per-mille. Added on top of amountIn
sellFeePercent uint8 public 10 (= 1%) Fee charged on sells. Deducted from amountOut
launchFeePercent uint8 public set by owner Fee taken from the ETH pool balance at the moment of DEX launch
creationFeeAmount uint256 public 150000000000000 wei (0.00015 BNB) Fixed BNB fee required to create a new token
feeRecipient address payable public set by owner Address receiving all protocol fees

Infrastructure

Name Type Visibility Description
uniswapV2Router address public PancakeSwap V2 Router address
uniswapV2Factory address public PancakeSwap V2 Factory address
isBondingCurveAddress mapping(address => bool) public Maps BondingCurve address → true if deployed by this factory
tokens BCToken[] public Array of all BCToken contracts ever created

Events

Created

Emitted when a new token and bonding curve pair are deployed.

event Created(
    address indexed bondingCurve,
    address indexed token,
    address indexed pair,
    address creator
);

Parameters:


Buy

Emitted when any user buys on any bonding curve managed by this factory.

event Buy(
    address indexed bc,
    address indexed token,
    address indexed buyer,
    uint amountIn,
    uint amountOut
);

Parameters:


Sell

Emitted when any user sells on any bonding curve managed by this factory.

event Sell(
    address indexed bc,
    address indexed token,
    address indexed seller,
    uint amountIn,
    uint amountOut
);

Parameters:


Public Functions

createToken

function createToken(
    string memory name,
    string memory ticker,
    uint256 initAmountIn
) external payable

Deploys a new BCToken and BondingCurve pair, then optionally performs an initial buy on behalf of the creator.

Parameters:

msg.value formula:

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

Example (no initial buy, 0.01 BNB creation fee):

const creationFee = await factory.creationFeeAmount();
await factory.createToken("Bullshot", "BULL", 0, { value: creationFee });

Example (0.5 BNB initial buy, 0.01 BNB creation fee, 1% buy fee):

const initAmountIn = ethers.utils.parseEther("0.5");
const buyFeePercent = await factory.buyFeePercent(); // e.g. 10
const FEE_DENOMINATOR = 1000;
const creationFee = await factory.creationFeeAmount();
const buyFee = initAmountIn.mul(buyFeePercent).div(FEE_DENOMINATOR);
const value = initAmountIn.add(buyFee).add(creationFee);
await factory.createToken("Bullshot", "BULL", initAmountIn, { value });

Effects:

  1. Transfers creationFeeAmount BNB to feeRecipient
  2. Clones a new BondingCurve and a new BCToken using ERC1167
  3. Registers the bonding curve in isBondingCurveAddress
  4. Pushes the token to the tokens array
  5. Initializes both contracts
  6. Emits Created
  7. If initAmountIn > 0, calls bondingCurve.buy(...) with the remaining value

getTokensLength

function getTokensLength() external view returns (uint256)

Returns the total number of tokens ever created through this factory.


getTokensList

function getTokensList(
    uint256 startIndex,
    uint256 count
) external view returns (BCToken[] memory)

Returns a paginated slice of the tokens array.

Parameters:

Returns: Array of BCToken addresses (may be shorter than count if end of array is reached)

Example:

// Get first 20 tokens
const tokens = await factory.getTokensList(0, 20);

// Get next 20 tokens
const tokens2 = await factory.getTokensList(20, 20);

setFee

function setFee(
    uint256 creationFeeAmount_,
    uint8 buyFeePercent_,
    uint8 sellFeePercent_,
    uint8 launchFeePercent_,
    address payable feeRecipient_
) public onlyOwner

Updates all protocol fee parameters. Only callable by the contract owner.

Parameters:


Example Usage

Listen for New Token Creations

factory.on("Created", (bondingCurve, token, pair, creator, event) => {
    console.log("New token created!");
    console.log("Token:", token);
    console.log("BondingCurve:", bondingCurve);
    console.log("Creator:", creator);
});

Listen for All Trades

factory.on("Buy", (bc, token, buyer, amountIn, amountOut) => {
    console.log(`Buy on ${token}: ${ethers.utils.formatEther(amountIn)} BNB → ${ethers.utils.formatEther(amountOut)} tokens`);
});

factory.on("Sell", (bc, token, seller, amountIn, amountOut) => {
    console.log(`Sell on ${token}: ${ethers.utils.formatEther(amountIn)} tokens → ${ethers.utils.formatEther(amountOut)} BNB`);
});

Check if Address is a Bullshot Bonding Curve

const isBondingCurve = await factory.isBondingCurveAddress("0x...");
if (isBondingCurve) {
    console.log("This address is a Bullshot BondingCurve");
}

Important Notes

  1. Fee Denominator: All fee percentages use FEE_DENOMINATOR = 1000. So buyFeePercent = 10 means 1%.
  2. Creation Fee: creationFeeAmount is in wei and transferred to feeRecipient before the bonding curve is initialized.
  3. Clone Pattern: Both BondingCurve and BCToken are deployed as ERC1167 minimal proxies pointing to master implementations — this makes token creation extremely gas-efficient.
  4. Pair Address at Creation: The pair field in the Created event is always address(0). The actual PancakeSwap pair is created lazily on the first buy call.
  5. Only BondingCurves Can Emit: emitBuyEvent and emitSellEvent can only be called by registered bonding curve addresses (isBondingCurveAddress[msg.sender] == true).