Overview
The RektHubFactory is the central hub of the RektHub protocol. It’s your single entry point for creating creator tokens, trading, and managing the entire token lifecycle. Think of it as the conductor of an orchestra, coordinating token creation, routing trades, and managing graduations across the creator economy.
For Integrators: Always use the Factory as your primary interface. It
ensures consistency, proper fee distribution, and seamless cross-contract
interactions.
Purpose & Architecture
What It Does
Token Creation : Deploys new creator tokens with bonding curves
Trade Routing : Routes buy/sell orders to the correct bonding curve
Fee Management : Collects platform fees
Graduation Control : Manages token migration to DEX (owner-only)
Address Discovery : Maps tokens to their bonding curves
Why It Matters
The Factory pattern provides:
Gas Efficiency : Uses minimal proxies (EIP-1167) to clone implementations
Isolation : Each token gets its own bonding curve with isolated state
Upgradeability : New features can be added without affecting existing tokens (not an upgradeable contract though)
Single Source of Truth : All critical operations go through one audited contract
Key Functions
Token Creation
createToken
Token name (e.g., “Creator Coin”)
Token symbol (e.g., “CRTR”)
URI pointing to token metadata JSON
Returns:
tokenAddress: Address of the deployed token
curveAddress: Address of the bonding curve
Events Emitted:
Example:
function createToken (
string calldata name ,
string calldata symbol ,
string calldata tokenURI
) external payable returns ( address tokenAddress , address curveAddress );
const tx = await factory . createToken ( 'Creator Coin' , 'CRTR' , 'ipfs://Qm...' , {
value: creationFee ,
});
const receipt = await tx . wait ();
const event = receipt . logs
. map (( log ) => factory . interface . parseLog ( log ))
. find (( e ) => e ?. name === 'TokenCreated' );
console . log ( 'Token address:' , event . args . tokenAddress );
console . log ( 'Curve address:' , event . args . curveAddress );
Metadata Best Practices: Host your tokenURI on IPFS or Arweave for
permanence. Include name, description, image, and social links. See Token
Contract for JSON format.
createTokenDeterministic
Create a token with a vanity address using CREATE2.
CREATE2 salt (pre-mined for vanity address)
Returns:
tokenAddress: Deterministic token address
curveAddress: Deterministic curve address
Events Emitted:
Example:
const salt = ethers . id ( 'my-vanity-salt' );
const [ predictedToken , predictedCurve ] = await factory . predictAddresses ( salt );
console . log ( 'Will create token at:' , predictedToken );
const code = await provider . getCode ( predictedToken );
if ( code !== '0x' ) {
throw new Error ( 'Address already occupied!' );
}
const tx = await factory . createTokenDeterministic (
'Vanity Token' ,
'VNTY' ,
'ipfs://Qm...' ,
salt ,
{ value: creationFee }
);
Address Collision: Always check if the predicted address is available
before calling createTokenDeterministic. The transaction will revert if the
address is occupied.
predictAddresses
Preview the addresses that will be created with a given salt.
Returns:
predictedToken: Token address that will be created
predictedCurve: Curve address that will be created
Example:
const salt = ethers . id ( 'test-salt' );
const [ tokenAddr , curveAddr ] = await factory . predictAddresses ( salt );
console . log ( 'Future token address:' , tokenAddr );
console . log ( 'Future curve address:' , curveAddr );
Trading Functions
buy
Purchase creator tokens from any deployed curve.
Address of the token to buy
Minimum tokens expected (slippage protection)
Returns:
tokensReceived: Actual amount of tokens received
Events Emitted:
Example:
const curveAddress = await factory . getCurve ( tokenAddress );
const curve = new ethers . Contract ( curveAddress , CURVE_ABI , provider );
const amountToSpend = ethers . parseEther ( '0.1' );
const [ expectedTokens , totalFee ] = await curve . getBuyPrice ( amountToSpend );
const minTokensOut = ( expectedTokens * 95 n ) / 100 n ;
const tx = await factory . buy ( tokenAddress , minTokensOut , {
value: amountToSpend ,
});
const receipt = await tx . wait ();
Always get a quote before buying. Prices move based on bonding curve math,
protect users with minTokensOut.
sell
Sell creator tokens back to the bonding curve.
Address of the token to sell
Minimum native tokens expected (slippage protection)
Returns:
nativeReceived: Amount of native tokens received
Events Emitted:
Example:
const curveAddress = await factory . getCurve ( tokenAddress );
const token = new ethers . Contract ( tokenAddress , TOKEN_ABI , signer );
const amountToSell = ethers . parseEther ( '1000' );
await token . approve ( curveAddress , amountToSell );
const curve = new ethers . Contract ( curveAddress , CURVE_ABI , provider );
const [ expectedNative , totalFee ] = await curve . getSellPrice ( amountToSell );
const minNativeOut = ( expectedNative * 95 n ) / 100 n ;
const tx = await factory . sell ( tokenAddress , amountToSell , minNativeOut );
await tx . wait ();
sellPercentage
Sell a percentage of your token balance, perfect for “Sell 25%” buttons.
Address of the token to sell
Percentage in basis points (5000 = 50%, 10000 = 100%)
Minimum native tokens expected
Returns:
nativeReceived: Amount of native tokens received
Events Emitted:
Example:
const curveAddress = await factory . getCurve ( tokenAddress );
await token . approve ( curveAddress , ethers . MaxUint256 );
const tx = await factory . sellPercentage ( tokenAddress , 5000 , minNativeOut );
Basis Points: 100 basis points = 1%. So 2500 = 25%, 5000 = 50%, 10000 =
100%.
Admin Functions
migrate
Graduate a bonded token to DEX. Owner-only function.
Address of the token to migrate
Address of the DEX migrator contract
Returns:
poolAddress: Address of the created liquidity pool
platformName: Name of the DEX platform
Events Emitted:
Requirements:
Token must be bonded (all 850M tradeable tokens sold)
Token must not already be graduated
Caller must be contract owner
Migrator must implement IDEXMigrator interface
Example:
const UNISWAP_MIGRATOR = '0x...' ;
const tx = await factory . migrate ( tokenAddress , UNISWAP_MIGRATOR );
const receipt = await tx . wait ();
const event = receipt . logs
. map (( log ) => factory . interface . parseLog ( log ))
. find (( e ) => e ?. name === 'TokenMigrated' );
console . log ( 'LP Pool created:' , event . args . poolAddress );
console . log ( 'Platform:' , event . args . platformName );
console . log ( 'Liquidity added:' , ethers . formatEther ( event . args . nativeLiquidity ));
For Creators: You cannot manually trigger migration. Graduation is handled
by RektHub’s automated systems after your token bonds and you select your
preferred DEX.
withdrawFees
Withdraw accumulated platform fees. Owner-only function.
Example:
const balance = await provider . getBalance ( factory . address );
console . log ( 'Withdrawable fees:' , ethers . formatEther ( balance ));
const tx = await factory . withdrawFees ();
await tx . wait ();
View Functions
getCurve
Get the bonding curve address for a token.
Returns:
address: Bonding curve address
Example:
const curveAddress = await factory . getCurve ( tokenAddress );
console . log ( 'Curve for token:' , curveAddress );
const curve = new ethers . Contract ( curveAddress , CURVE_ABI , provider );
getCreationFee
Get the current token creation fee.
Returns:
uint256: Creation fee in native tokens
Example:
const fee = await factory . getCreationFee ();
console . log ( 'Creation fee:' , ethers . formatEther ( fee ), 'ETH' );
Events
TokenCreated
Emitted when a new token is deployed.
event TokenCreated (
address indexed tokenAddress ,
address indexed curveAddress ,
address indexed creator ,
string name ,
string symbol ,
string uri ,
uint256 realNativeReserves ,
uint256 realTokenReserves ,
uint256 virtualNativeReserves ,
uint256 virtualTokenReserves ,
uint256 creationFee
);
Use Cases:
Track new token launches
Build trending token feeds
Creator analytics dashboards
TokenPurchased
Emitted when tokens are bought through the factory.
event TokenPurchased (
address indexed token ,
address indexed curve ,
address indexed buyer ,
uint256 nativeIn ,
uint256 tokensOut ,
uint256 totalFee ,
uint256 creatorFee ,
uint256 platformFee ,
uint256 newRealNativeReserves ,
uint256 newRealTokenReserves ,
uint256 newVirtualNativeReserves ,
uint256 newVirtualTokenReserves
);
Use Cases:
Real-time trade feeds
Price charts and volume tracking
Creator earnings dashboards
TokenSold
Emitted when tokens are sold through the factory.
event TokenSold (
address indexed token ,
address indexed curve ,
address indexed seller ,
uint256 tokensIn ,
uint256 nativeOut ,
uint256 totalFee ,
uint256 creatorFee ,
uint256 platformFee ,
uint256 newRealNativeReserves ,
uint256 newRealTokenReserves ,
uint256 newVirtualNativeReserves ,
uint256 newVirtualTokenReserves
);
TokenMigrated
Emitted when a token graduates to DEX.
event TokenMigrated (
address indexed tokenAddress ,
address indexed curveAddress ,
address indexed poolAddress ,
string platformName ,
uint256 nativeLiquidity ,
uint256 tokenLiquidity ,
uint256 migrationFee ,
uint256 creatorFee ,
uint256 platformFee
);
FeesWithdrawn
Emitted when platform fees are withdrawn.
event FeesWithdrawn (
address indexed recipient ,
uint256 amount
);
Integration Tips
Always Use Factory for Consistency
// ✅ Good: Use factory
await factory . buy ( tokenAddress , minTokensOut , { value: amount });
// ❌ Avoid: Directly calling curve (unless you have a reason)
await curve . buy ( buyer , minTokensOut , { value: amount });
Handle Events Efficiently
const tokenFilter = factory . filters . TokenPurchased ( tokenAddress );
factory . on ( tokenFilter , ( token , curve , buyer , nativeIn , tokensOut ) => {
updateUI ({ buyer , nativeIn , tokensOut });
});
factory . on ( 'TokenPurchased' , handlePurchase );
factory . on ( 'TokenSold' , handleSale );
Multi-Chain Setup
const factories = {
1 : new ethers . Contract ( ETHEREUM_FACTORY , ABI , ethProvider ),
8453 : new ethers . Contract ( BASE_FACTORY , ABI , baseProvider ),
42161 : new ethers . Contract ( ARB_FACTORY , ABI , arbProvider ),
};
async function buyOnChain ( chainId , tokenAddress , amount ) {
const factory = factories [ chainId ];
return factory . buy ( tokenAddress , minOut , { value: amount });
}
Next Steps
Bonding Curve Contract Learn about the trading engine
Token Contract Understand creator token standards
Buying Guide Deep dive into buying patterns
Events Reference Complete events documentation