Reference/interfaces
Interfaces
The structs, functions, events and custom errors you build against, copied from the deployed source.
The surface you build against, taken from the deployed source. Every contract is verified on Blockscout, so the canonical ABI is always one click away from any address — this page is the map, not a substitute.
#Conventions
- Custom errors everywhere. Nothing reverts with a string. Decode revert data against the ABI to get a user-facing message; string-matching will fail.
- Amounts are raw base units. Every token’s own
decimals(); WETH and ETH are 18. - Basis points are out of 10 000.
MAX_BPSis 10 000 in every contract that uses them. - Ownable2Step, not Ownable. Ownership transfers on the protocol contracts need an explicit accept, so a typo cannot orphan a contract.
#HoodLauncher
soliditylaunching
struct LaunchParams {
uint8 venueId;
string name; string symbol; string image; string description;
string socials; string metadataURI;
bytes32 userSalt;
int24 tickIfToken0IsNewToken;
uint256 supply; // 0 => DEFAULT_SUPPLY
bool sniperGuard;
uint256 devBuyMinOut;
bytes tokenFeeConfig; // abi.encode(uint16 policyId, bytes data)
bytes creatorFeeConfig;
}
function launch(LaunchParams calldata p) external payable
returns (address token, address pool, uint256 positionId);
function computeTokenAddress(address deployer, LaunchParams calldata p)
external view returns (address);solidityregistry + config reads
struct LaunchInfo { address creator; address pool; uint256 positionId;
uint64 createdAt; uint8 venueId; }
function launches(address token) external view returns (LaunchInfo memory);
function getLaunch(address token) external view returns (LaunchInfo memory);
function allTokens(uint256 index) external view returns (address);
function tokenCount() external view returns (uint256);
struct Venue { INonfungiblePositionManager npm; IUniswapV3Factory factory;
address swapRouter; RouterKind routerKind; address feeLocker; }
function getVenue(uint8 venueId) external view returns (Venue memory);
function venueExists(uint8 venueId) external view returns (bool);
function launchFee() external view returns (uint256);
function creatorBps() external view returns (uint16);
function minFdvWei() external view returns (uint256);
function maxFdvWei() external view returns (uint256);
function minSupply() external view returns (uint256);
function maxSupply() external view returns (uint256);
function maxWalletBps() external view returns (uint16);
function restrictionBlocks() external view returns (uint32);
uint24 constant POOL_FEE = 10_000; // 1% tier
int24 constant TICK_SPACING = 200;
uint16 constant MIN_CREATOR_BPS = 1_000; // 10% creator floor
uint256 constant DEFAULT_SUPPLY = 1_000_000_000e18;
uint256 constant MAX_LAUNCH_FEE = 1 ether;#TokenLaunched
solidity
event TokenLaunched(
address indexed token,
address indexed creator,
address indexed pool,
uint8 venueId,
uint256 positionId,
uint256 supply,
int24 startTick,
uint16 creatorBps,
uint16 maxWalletBps,
uint32 restrictionBlocks,
string name,
string symbol,
string metadataURI,
uint256 devBuyEth,
uint256 devBuyTokens
);Deliberately fat: everything an indexer needs is in the event, so a launch can be fully reconstructed without a single follow-up call.
#Errors
| Error | Cause |
|---|---|
| UnknownVenue(venueId) | That venue is not registered. |
| InvalidTick | Tick is not a multiple of 200, or is out of range. |
| InvalidSupply | Supply outside the current band. |
| MarketCapOutOfRange | Implied starting FDV outside [minFdvWei, maxFdvWei]. |
| InsufficientValue | msg.value below the launch fee. |
| PoolPriceMismatch | The pool already existed at a different price. |
| NotSingleSided | The mint consumed WETH, or produced zero liquidity. |
| EmptyString | Name or symbol is empty. |
#HoodToken
solidity
// standard ERC-20 + ERC20Burnable: burn(uint256), burnFrom(address,uint256)
function image() external view returns (string memory);
function logo() external view returns (string memory);
function description() external view returns (string memory);
function socials() external view returns (string memory);
function contractURI() external view returns (string memory); // ERC-7572
function setImage(string calldata) external; // owner-gated
function setDescription(string calldata) external;
function setSocials(string calldata) external;
function setContractURI(string calldata) external;
function tokenOwner() external view returns (address);
function pool() external view returns (address);
function isExempt(address account) external view returns (bool);
function isFeeVenue(address venue) external view returns (bool);
function launcher() external view returns (address);
function creator() external view returns (address);
function launchBlock() external view returns (uint256);
function restrictionEndBlock() external view returns (uint256);
function maxWalletAmount() external view returns (uint256);
error LaunchBlockBuy();
error MaxWalletExceeded();
error OnlyTokenOwner();#TokenOwnerRegistry
solidity
function ownerOf(address token) external view returns (address);
function registered(address token) external view returns (bool);
function transferTokenOwnership(address token, address newOwner) external;
event TokenOwnershipTransferred(address indexed token,
address indexed previousOwner,
address indexed newOwner);#FeeLocker & V3FeeReceiver
solidityFeeLocker
struct PositionConfig { address creator; uint16 creatorBps;
address token0; address token1; }
function collect(uint256 tokenId) external returns (uint256 amount0, uint256 amount1);
function collectMany(uint256[] calldata tokenIds) external; // keeper batch
function getConfig(uint256 tokenId) external view returns (PositionConfig memory);
function updateCreatorRecipient(uint256 tokenId, address newCreator) external; // token owner
function npm() external view returns (address);
function launcher() external view returns (address);
function feeReceiver() external view returns (address);
event PositionLocked(uint256 indexed tokenId, address indexed pool,
address token0, address token1,
address indexed creator, uint16 creatorBps);
event FeesCollected(uint256 indexed tokenId, address indexed receiver,
uint256 amount0, uint256 amount1);solidityV3FeeReceiver
function claimable(address recipient, address token) external view returns (uint256);
function claim(address token) external; // pull-fallback
function protocolRecipient() external view returns (address);
event FeesDistributed(uint256 indexed tokenId, address indexed token,
address indexed creator, uint256 creatorAmount, uint256 protocolAmount);
event FeesDelegated(uint256 indexed tokenId, address indexed asset,
address indexed manager, uint256 amount);
event FeeCredited(address indexed recipient, address indexed token, uint256 amount);#Fee policies
solidityFeePolicyManager (deployed twice — token side and creator side)
struct TokenPolicy { uint16 policyId; address module; address venue; }
function feeAsset() external view returns (address); // 0 = the launched token
function getPolicy(address token) external view returns (TokenPolicy memory);
function moduleOf(address token) external view returns (address);
function hasPolicy(address token) external view returns (bool);
function modules(uint16 policyId) external view returns (address);
/// Permissionless. Pulls the fee asset from the caller into the token's venue,
/// then notifies the module. Calling it yourself is a donation to that policy.
function handleFee(address token, uint256 amount) external;soliditythe modules
// BurnFeeModule — token policy 1
function totalBurned(address token) external view returns (uint256);
// VestingFeeModule — token policy 2
struct FeeVesting { address recipient; uint16 dailyReleaseBps; uint64 lastClaimAt;
uint256 accrued; uint256 released; }
function vestings(address token) external view returns (FeeVesting memory);
function claim(address token) external; // permissionless, once per 24h
function setRecipient(address token, address recipient) external; // token owner
uint64 constant CLAIM_INTERVAL = 1 days;
// BuyBurnFeeModuleV2 — creator policy 2
function pendingWeth(address token) external view returns (uint256);
function lastBuyback(address token) external view returns (uint256);
function totalWethSpent(address token) external view returns (uint256);
function totalTokensBurned(address token) external view returns (uint256);
function executeBuyback(address token, uint256 wethIn, uint256 minTokensOut) external;
uint256 constant PUBLIC_AFTER = 90 days;
// StakingFeeModule — policy 3 on both managers
function poolOf(address token) external view returns (address);
// BackingFeeModule — creator policy 4 ("FLOOR")
function vaultOf(address token) external view returns (address);#TokenBackingVault
solidityone clone per token that picks policy 4
/// Burn tokens for a pro-rata slice of the vault, in native ETH, less the 1% skim.
/// Approve the vault for that amount first — it burns with burnFrom and never custodies.
function redeem(uint256 amount, uint256 minEthOut, address to)
external returns (uint256 ethOut);
function backing() external view returns (uint256); // ETH + WETH held here
function circulatingSupply() external view returns (uint256); // totalSupply - position inventory
function launchPositionInventory() external view returns (uint256);
function floorPrice() external view returns (uint256); // wad, ETH per whole token
function previewRedeem(uint256 amount) external view returns (uint256 ethOut);
function token() external view returns (address);
function launchPool() external view returns (address);
function launchPositionId() external view returns (uint256);
function syncLaunch() external returns (bool resolved); // permissionless, idempotent
uint256 public constant REDEEM_SKIM_BPS = 100; // 1%, a constant — no admin
event Redeemed(address indexed caller, address indexed to, uint256 tokensBurned,
uint256 ethOut, uint256 backingAfter, uint256 circulatingAfter);
error NothingToRedeem(); // the share rounded to zero
error SlippageExceeded(uint256 ethOut, uint256 minEthOut);
error LaunchNotFound(); // no launch record => no honest denominatornote
backingAfter and circulatingAfter on the event are post-state, so an indexer can derive the resulting floor without a second read. Note the second one is circulating supply, not totalSupply().#TokenStakingPool
solidity
function deposit(uint256 amount) external;
function withdraw(uint256 amount) external;
function claimRewards() external returns (uint256 tokenAmount, uint256 wethAmount);
function exit() external;
function donateRewards(uint256 amount) external;
function donateWethRewards(uint256 amount) external;
function donateEthRewards() external payable;
function earned(address user) external view returns (uint256 tokenAmount, uint256 wethAmount);
function getStake(address user) external view returns (StakeInfo memory);
function totalStaked() external view returns (uint256);
uint64 constant LOCK_DURATION = 1 days;
error StillLocked(uint64 lockedUntil);#V4TradeManager
solidity
struct Route { uint8 dex; bytes v3Path; address[] v2Path;
uint24 fee; int24 tickSpacing; address hooks; }
function buy(address token, Route calldata route, uint256 minAmountOut,
uint256 deadline, address ref, bytes calldata refData)
external payable returns (uint256 tokenOut);
function sell(address token, uint256 amountIn, Route calldata route,
uint256 minEthOut, uint256 deadline, address ref, bytes calldata refData)
external returns (uint256 ethToUser);
function adapters(uint8 dexId) external view returns (address);
function dexPaused(uint8 dexId) external view returns (bool);
function platformFeeBps() external view returns (uint16);
function referralBps() external view returns (uint16);
function feeReceiver() external view returns (address);
function referralManager() external view returns (address);
uint16 constant MAX_PLATFORM_FEE_BPS = 200; // 2%
uint16 constant MAX_REFERRAL_BPS = 5_000; // 50% of the fee
error Expired(); error SlippageExceeded(); error NoSwapOutput();
error UnknownDex(uint8 dexId); error DexPaused(uint8 dexId); error AdapterExists(uint8 dexId);Route field meaning belongs to the adapter
The tuple layout is frozen for ABI compatibility, but what each field means depends on the dexId — see the per-venue table on Venues & routing. A venue needing different parameters encodes them into
v3Path as opaque bytes rather than changing the struct.solidityITradeAdapter — implement this to add a venue
interface ITradeAdapter {
function buy(address token, Route calldata route, uint256 minAmountOut,
uint256 deadline, address recipient)
external payable returns (uint256 tokenOut);
function sell(address token, uint256 amountIn, Route calldata route, uint256 deadline)
external returns (uint256 ethOut);
}
// dexId 7 payload, abi.encoded into Route.v3Path
struct V4Hop { address currency0; address currency1; uint24 fee;
int24 tickSpacing; address hooks; }
struct MultiHopPath { bytes v3Leg; V4Hop[] hops; }#ReferralManager
solidity
function pending(address referrer) external view returns (uint256);
function lifetimeEarned(address referrer) external view returns (uint256);
function referrerOf(address trader) external view returns (address); // analytics only
function claim(address to) external returns (uint256 amount);#CashBackFeeReceiver
The manager’s live fee destination, and the only contract that holds a trader-owned balance from trading. Everything a trader controls is unauthenticated to read and self-signed to write — see Cash back.
solidity
function pending(address user) external view returns (uint256); // wei, claimable now
function effectiveRateBps(address user) external view returns (uint16);// override, else default
function defaultRateBps() external view returns (uint16);
function preferredAsset(address user) external view returns (address); // 0 = native ETH
function totalPending() external view returns (uint256); // Σ pending
function freeBalance() external view returns (uint256); // treasury ceiling
function setPreferredAsset(address asset) external; // 0 = native ETH
function claimEth() external; // always available
function claimWeth() external;
function claimInAsset(Route calldata route, uint256 minAmountOut, uint256 deadline) external;
uint16 constant MAX_RATE_BPS = 9_000; // 90% — compiled in
event CashBackAccrued(address indexed user, uint256 amount, uint256 pendingAfter);
event CashBackClaimed(address indexed user, address indexed asset,
uint256 ethAmount, uint256 amountOut, address indexed claimedBy);
event PreferredAssetSet(address indexed user, address indexed asset);
error NothingToClaim(); error NoSwapOutput(); error ExceedsFreeBalance(uint256, uint256);The payout token is never read from the route
claimInAsset takes routing calldata, but the asset it must resolve to comes from on-chain preferredAsset[user] — the adapter validates the route delivers that token, and minAmountOut bounds what a bad route can cost. A hostile route cannot redirect the payout, only waste the caller’s own gas.#Tools
solidityHoodLocker
struct Lock { address token; address owner; address unlocker;
uint256 amount; uint64 unlockTime; bool withdrawn; }
struct Vesting { address token; address creator; address beneficiary;
uint256 total; uint256 released;
uint64 start; uint64 duration; uint32 interval; }
function createLock(address token, uint256 amount, uint64 unlockTime, address unlocker)
external returns (uint256 lockId);
function extendLock(uint256 lockId, uint64 newUnlockTime) external;
function withdraw(uint256 lockId) external;
function createVestings(address token, address[] calldata recipients,
uint256[] calldata amounts,
uint64 start, uint64 duration, uint32 interval)
external returns (uint256 firstVestingId);
function claim(uint256 vestingId) external;
function claimable(uint256 vestingId) external view returns (uint256);
function vestedAmount(uint256 vestingId, uint64 timestamp) external view returns (uint256);
function locksOf(address owner) external view returns (uint256[] memory);
function vestingsOf(address beneficiary) external view returns (uint256[] memory);solidityHoodAirdrop
function airdrop(address token, address[] calldata recipients, uint256[] calldata amounts)
external returns (uint256 total);
function airdropEqual(address token, address[] calldata recipients, uint256 amount)
external returns (uint256 total);
event Airdropped(address indexed token, address indexed sender,
uint256 recipients, uint256 totalAmount);
error ZeroRecipient(uint256 index);
error ZeroAmount(uint256 index);