Skip to main content
Three contracts (Solidity 0.8.30, OpenZeppelin-based) run the entire protocol. Integrators only need the HoodLaunchpad address — everything else is discoverable from it.

HoodLaunchpad

The singleton that combines the token factory, every bonding curve, the fee ledger, and the Uniswap v3 migrator.

Launching

function createToken(
    string calldata name,
    string calldata symbol,
    string calldata metadataURI,
    uint256 minTokensOut
) external payable returns (address token);
Deploys a HoodToken and opens its curve. Any attached ETH executes an optional dev buy at the public starting price; minTokensOut protects it against front-running. Emits TokenCreated.

Trading

function buy(address token, uint256 minTokensOut, uint256 deadline)
    external payable returns (uint256 tokensOut);

function buyExactTokens(address token, uint256 tokensOut, uint256 deadline)
    external payable;  // refunds excess ETH

function sell(address token, uint256 tokenAmount, uint256 minEthOut, uint256 deadline)
    external returns (uint256 ethOut);  // requires prior approve

function sellWithPermit(
    address token, uint256 tokenAmount, uint256 minEthOut, uint256 deadline,
    uint8 v, bytes32 r, bytes32 s
) external returns (uint256 ethOut);   // single-tx sell via EIP-2612
A buy that exceeds the remaining curve supply fills to exactly the end, refunds the excess ETH, and sets graduated = true. Emits Trade on every fill and Graduated on the final one.

Views & quotes

function quoteBuy(address token, uint256 grossEthIn)
    external view returns (uint256 tokensOut, uint256 fee, uint256 ethUsed);
function quoteBuyExact(address token, uint256 tokensOut)
    external view returns (uint256 ethNeeded, uint256 fee);
function quoteSell(address token, uint256 tokenAmount)
    external view returns (uint256 ethOut, uint256 fee);

function currentPrice(address token) external view returns (uint256);      // wei per 1e18 tokens
function curveProgressBps(address token) external view returns (uint256);  // 0–10000
function getTokens(uint256 offset, uint256 limit) external view returns (address[] memory);
function getCurveStates(address[] calldata tokens) external view returns (CurveState[] memory);
function curves(address token) external view returns (CurveState memory);
CurveState fields: virtualEth, virtualToken, realTokensLeft, realEth, creator, graduated, migrated.

Migration

function migrate(address token) external returns (address pool, uint256 tokenId);
Permissionless and parameter-free. Wraps the raised ETH, mints a full-range Uniswap v3 position (1% fee tier) at the final curve price, and locks the position NFT in the FeeLocker. Includes a bounded corrective swap to neutralize hostile pool pre-initialization. Leftover tokens burn to 0xdEaD; leftover WETH accrues to protocol fees. Emits Migrated.

Fees

function claimCreatorFees(address token) external;   // anyone may call; pays the fee recipient
function claimProtocolFees() external;               // anyone may call; pays the treasury
function setFeeRecipient(address token, address newRecipient) external; // current recipient only

function creatorFeesOwed(address token) external view returns (uint256);
function protocolFeesOwed() external view returns (uint256);
function feeRecipientOf(address token) external view returns (address);
function protocolFeeBps() external view returns (uint256);  // currently 70
function creatorFeeBps() external view returns (uint256);   // currently 30

Owner surface (complete list)

function setFees(uint256 protocolBps, uint256 creatorBps) external;  // total hard-capped at 500 bps
function setTreasury(address newTreasury) external;
function setLocker(address locker) external;                         // one-time
There is deliberately no withdraw, pause, upgrade, or seize function.

Events

event TokenCreated(address indexed token, address indexed creator, string name, string symbol, string metadataURI);
event Trade(address indexed token, address indexed trader, bool isBuy, uint256 ethGross, uint256 tokenAmount, uint256 fee, uint256 virtualEth, uint256 virtualToken);
event Graduated(address indexed token, uint256 ethRaised);
event Migrated(address indexed token, address pool, uint256 tokenId, uint256 ethAmount, uint256 tokenAmount);

Custom errors

CurveClosed, CurveStillOpen, AlreadyMigrated, Expired, SlippageExceeded, UnknownToken, ZeroAmount, ZeroAddress, FeeTooHigh, NotFeeRecipient, LockerNotSet

HoodToken

The per-launch ERC-20, deployed by createToken:
  • OpenZeppelin ERC20 + ERC20Permit (EIP-2612), 18 decimals
  • Fixed supply of 1,000,000,000 × 1e18, minted once to the launchpad
  • metadataURI() — immutable token metadata pointer (e.g. ipfs://…)
  • No owner, mint, burn-by-admin, pause, blacklist, or fee-on-transfer

FeeLocker

The immutable, ownerless vault for graduated liquidity:
function positionOf(address token) external view returns (uint256 tokenId); // 0 = not migrated
function collectFees(address token) external;  // harvests pool fees, splits 50/50 creator/treasury
The locker has no function that can transfer a position out — locked liquidity is permanent by construction. The 50/50 creator/treasury split is set in the constructor and immutable.

Curve constants

uint256 constant TOTAL_SUPPLY    = 1_000_000_000e18;
uint256 constant VIRTUAL_TOKEN_0 = 1_073_000_000e18;
uint256 constant SALE_SUPPLY     =   793_100_000e18;
uint256 constant POOL_SUPPLY     = TOTAL_SUPPLY - SALE_SUPPLY; // 206_900_000e18
// virtualEth0: immutable constructor parameter (1.6 ETH at launch)
uint24  constant POOL_FEE   = 10000;    // Uniswap v3 1% tier
int24   TICK_LOWER/UPPER    = ±887200;  // full range
uint256 constant MAX_TOTAL_FEE_BPS = 500;
All rounding favors the pool (Math.ceilDiv on reserve division) so the invariant k never decreases.
Deployed addresses are to be announced — see Developer Overview for the canonical Uniswap and WETH addresses on Robinhood Chain, and check this page again at launch.