Deploy a Token
Step-by-step guide to deploying a token + bonding curve pair through the Factory contract using ethers.js.
Prerequisites
- A wallet with ETH/BNB for the deployment fee (0.0006 ETH on Base, 0.0012 BNB on BSC)
- An Ethereum provider (MetaMask, ethers.js JsonRpcProvider, etc.)
- Access to a recent block's hash for vanity salt mining
Step 1: Mine a Vanity Salt
The salt must commit to a recent blockhash and produce a token address starting with 0x24. Here's the process:
const { ethers } = require("ethers");
// Get the current block number as anchor
const anchorBlock = await provider.getBlockNumber();
const block = await provider.getBlock(anchorBlock);
const blockHash = block.hash;
// Extract first 8 bytes of blockhash
const hashPrefix = blockHash.slice(0, 18); // "0x" + 16 hex chars = 8 bytes
// Pack anchor block (8 bytes, big-endian)
const anchorBytes = ethers.utils.hexZeroPad(
ethers.utils.hexlify(anchorBlock), 8
);
// Mine nonce until CREATE2 address starts with 0x24
const factoryAddr = "0x8A96..."; // Factory address
const tokenMaster = "0xf07a..."; // Token master address
const initCodeHash = ethers.utils.keccak256(
/* minimal proxy initcode for token_master */
);
let nonce = 0;
while (true) {
const nonceHex = ethers.utils.hexZeroPad(
ethers.utils.hexlify(nonce), 16
);
const salt = anchorBytes + hashPrefix.slice(2) + nonceHex.slice(2);
const addr = ethers.utils.getCreate2Address(
factoryAddr, salt, initCodeHash
);
if (addr.startsWith("0x24")) {
console.log("Found salt:", salt);
break;
}
nonce++;
}
Step 2: Call deploy_pair
const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, signer);
const tx = await factory.deploy_pair(
"My Token", // name
"MTK", // symbol
salt, // bytes32 vanity salt
ethers.constants.HashZero, // packed_socials (optional)
{ value: ethers.utils.parseEther("0.0006") }
);
const receipt = await tx.wait();
// Parse the PairDeployed event
const event = receipt.events.find(e => e.event === "PairDeployed");
const tokenAddress = event.args.token;
const curveAddress = event.args.curve;
console.log("Token:", tokenAddress); // Will start with 0x24
console.log("Curve:", curveAddress);
Timing is Critical
Your transaction must be included within the INCLUSION_WINDOW (10 blocks / 20s on Base, 44 blocks / ~132s on BSC) after the anchor block. Mine the salt and submit the transaction quickly.