Integration
Program addresses, token identification, the transfer gate, PDAs, instruction and account layouts, and errors for HODL tokens on the bonding curve.
This page is the integration reference for HODL tokens during the bonding phase. After graduation a HODL token is a standard Token-2022 token trading on Meteora DAMM v2, and nothing on this page applies to it.
Programs
| Program | Address |
|---|---|
| HODL launchpad | HoDLBfygFHh76gjH7tnMxYqLt9VLCR3GgonXsodtfoPR |
| HODL transfer hook | HoDLrkxn9ShXX6Zk7wLVWLtbiAt3RngibB3atKrkBGw9 |
| Meteora Dynamic Bonding Curve (DBC) | dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN |
| Meteora DAMM v2 | cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG |
| Token-2022 (base token) | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
| SPL Token (quote token) | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA |
| Associated Token Account | ATokenGPvbdGVxr1b1hFzfegA1Wzh8VbJEFe8oBa2Lz5 |
| Constant | Value |
|---|---|
| Quote mint | Wrapped SOL, So11111111111111111111111111111111111111112 |
| Base token supply | 1,000,000,000, 6 decimals |
| Fomo signer | AgmLJBMDCqWynYnQiPCuj9ewsNNsBJXyzoUhD9LJzN51 |
| Global config | 7kY1FqUgESxSwuQEN8BZE7qe4rUDXWEMMPXo1nrYcW7d |
| DBC pool authority | FhVo3mqL8PW5pH5U2CN4XE33DokiyZnUwuGpH2hmHLuM |
| DBC event authority | 8Ks12pbrD6PXxfty1hVQiE9sc289zgU1zHkvXhrSdriF |
| DAMM v2 migration config | A8gMrEPJkacWkcb3DGwtJwTe16HktSEfvwtuDh2MCtck |
Identifying a HODL token
HODL pools are DBC pools. Filtering by the DBC program ID alone matches every DBC pool. Use either method below.
| Method | Condition |
|---|---|
| Creating transaction | The transaction's top-level instruction is launchpad create_launch, with the mint at account index 1 and trading_fees at index 4 equal to ["fees", mint] under the launchpad. A CPI into create_launch does not qualify. |
| Pool state | The pool's DBC config has fee_claimer equal to ["fees", base_mint] under the launchpad. |
Every launch creates its own DBC config. There is no shared HODL config to match against.
Transfer gate
While the hook is attached to the mint, Token-2022 calls the hook on every transfer of the base token. The hook reads the transaction through the instructions sysvar, and the transfer succeeds only if one of the following holds:
| Condition | Used by |
|---|---|
| The Fomo signer is a signer account of a top-level instruction in the transaction. A signature from a key that no top-level instruction lists is not visible to the hook. | Every bonding-phase buy, sell and transfer. |
| The top-level instruction the transfer runs under belongs to the launchpad. | The opening buy inside create_launch. |
Any other transfer fails with hook error 6000 UnauthorizedTransfer. The launchpad condition applies only to the instruction it is: a launchpad instruction elsewhere in the transaction does not authorize a transfer under another instruction.
The swap that completes the curve revokes the transfer hook and clears its authority. From then on the token transfers without the hook.
PDAs
| Account | Program | Seeds |
|---|---|---|
| Global config | Launchpad | ["global_config"] |
| Trading fees | Launchpad | ["fees", base_mint] |
| Extra account meta list | Hook | ["extra-account-metas", base_mint] |
| DBC pool | DBC | ["pool", dbc_config, larger(base_mint, quote_mint), smaller(base_mint, quote_mint)] |
| DBC vault | DBC | ["token_vault", mint, pool] |
| DBC event authority | DBC | ["__event_authority"] |
| DAMM v2 pool | DAMM v2 | ["pool", damm_config, larger(base_mint, quote_mint), smaller(base_mint, quote_mint)] |
larger and smaller compare the two mints as 32-byte arrays. The extra account meta list resolves one extra account, the instructions sysvar.
Instructions
Launchpad: create_launch
Creates the launch's DBC config, the Token-2022 mint with the hook attached, the DBC pool, the mint's extra account meta list and the trading_fees account, then executes the opening buy. Permissionless. No Fomo signature is required.
Discriminator ef df ff 86 27 79 7f 3e
| # | Account | Writable | Signer | Address or derivation |
|---|---|---|---|---|
| 0 | creator | Yes | Yes | Fee payer and buyer |
| 1 | base_mint | Yes | Yes | New keypair |
| 2 | dbc_config | Yes | Yes | New keypair |
| 3 | global_config | No | No | ["global_config"], launchpad |
| 4 | trading_fees | Yes | No | ["fees", base_mint], launchpad |
| 5 | pool_authority | No | No | DBC pool authority |
| 6 | pool | Yes | No | DBC pool PDA |
| 7 | base_vault | Yes | No | DBC vault PDA for base_mint |
| 8 | quote_vault | Yes | No | DBC vault PDA for the quote mint |
| 9 | quote_mint | No | No | Wrapped SOL |
| 10 | creator_quote_account | Yes | No | Creator's WSOL associated token account |
| 11 | recipient_wallet | No | No | Receives the opening buy's tokens: the dev's Fomo wallet. Any address except the default pubkey; never signs |
| 12 | recipient_base_account | Yes | No | recipient_wallet's Token-2022 associated token account for base_mint, created by the instruction |
| 13 | extra_account_meta_list | Yes | No | ["extra-account-metas", base_mint], hook |
| 14 | dbc_event_authority | No | No | DBC event authority |
| 15 | dbc_program | No | No | DBC |
| 16 | hook_program | No | No | Hook |
| 17 | instructions_sysvar | No | No | Sysvar1nstructions1111111111111111111111111 |
| 18 | token_base_program | No | No | Token-2022 |
| 19 | token_quote_program | No | No | SPL Token |
| 20 | associated_token_program | No | No | Associated Token Account |
| 21 | system_program | No | No | 11111111111111111111111111111111 |
Changed 2026-09-27. Account 11 was creator_base_account, the creator's own token account, which received the opening buy. The tokens now go to recipient_wallet (11) through its token account (12), and every account after them moved down by one. The creator still pays and spends its own WSOL. Until graduation only a Fomo wallet can sell, because every curve trade needs Fomo's signature; tokens sent to any other wallet cannot be sold before the token graduates.
Arguments: CreateLaunchParams
| Field | Type | Constraint |
|---|---|---|
name | string | 1 to 32 bytes |
symbol | string | 1 to 10 bytes |
uri | string | Up to 200 bytes |
tier | u8 | 0 to 4 (A to E) |
trading_fee_bps | u16 | 125 to 500, the fee for the life of the token, before and after graduation |
recipients | Vec<FeeRecipient> | 1 to 5, share_bps summing to 10000, no duplicates |
buy_amount | u64 | Opening buy in lamports of WSOL, at least global_config.minimum_opening_buy_lamports (500,000,000, 0.5 SOL, when the config is created) |
minimum_amount_out | u64 | Minimum base token received, in base units |
| Tier | Graduation raise | Supply to the migrated pool |
|---|---|---|
| 0 (A) | 125 SOL | 20% |
| 1 (B) | 250 SOL | 12% |
| 2 (C) | 500 SOL | 7% |
| 3 (D) | 1,000 SOL | 4% |
| 4 (E) | 2,000 SOL | 2% |
Requirements:
- Fund and sync
creator_quote_accountwith at leastbuy_amountWSOL before this instruction. - Set a compute unit limit of at least 1,400,000.
- The creator pays about 0.0087 SOL of rent for the DBC config, which is not recoverable.
- Send the launch as a v0 transaction over the address lookup table named
launchLookupTablein the cluster's manifest (mainnet:GdMdweWebDuHJi4ipAYpUGJM14zr51LeyvyukmCv9LbB). It holds the eleven accounts common to every launch:global_config,pool_authority,quote_mint,dbc_event_authority,dbc_program,hook_program,instructions_sysvar,token_base_program,token_quote_program,associated_token_program,system_program. The largest launch the program accepts (a 32 character name, a 10 character symbol, a 200 character uri, a separaterecipient_wallet) is 1,183 bytes this way. - This used to say a legacy transaction was enough for up to three or four fee recipients. That was wrong. It was counted with an empty
uri. A real metadata URL and a separaterecipient_walletwith a single recipient came to 1,241 bytes, over the 1,232 byte limit, and the site's launches failed until they moved to v0.
Launchpad: claim_fees
Claims the launch's accrued DBC trading fees into trading_fees and pays them out in the same transaction: HODL's share to the HODL fee wallet and the remainder to the launch's recipients by share_bps, the last recipient receiving any rounding remainder. Payouts are in SOL. Permissionless: any wallet may crank it and pays only the transaction fee, since the temporary token accounts are closed and their rent returned to it.
Discriminator 52 fb e9 9c 0c 34 b8 ca
| # | Account | Writable | Signer | Address or derivation |
|---|---|---|---|---|
| 0 | cranker | Yes | Yes | Any wallet |
| 1 | global_config | No | No | ["global_config"], launchpad |
| 2 | trading_fees | Yes | No | ["fees", base_mint], launchpad |
| 3 | dbc_config | No | No | The launch's DBC config |
| 4 | pool_authority | No | No | DBC pool authority |
| 5 | pool | Yes | No | DBC pool PDA |
| 6 | base_vault | Yes | No | DBC vault PDA for base_mint |
| 7 | quote_vault | Yes | No | DBC vault PDA for the quote mint |
| 8 | base_mint | No | No | The token |
| 9 | quote_mint | No | No | Wrapped SOL |
| 10 | trading_fees_quote_account | Yes | No | WSOL associated token account of trading_fees |
| 11 | trading_fees_base_account | Yes | No | Token-2022 associated token account of trading_fees for base_mint |
| 12 | token_base_program | No | No | Token-2022 |
| 13 | token_quote_program | No | No | SPL Token |
| 14 | dbc_event_authority | No | No | DBC event authority |
| 15 | dbc_program | No | No | DBC |
| 16 | associated_token_program | No | No | Associated Token Account |
| 17 | system_program | No | No | 11111111111111111111111111111111 |
Remaining accounts, writable, in order:
| # | Account |
|---|---|
| 0 | global_config.hodl_fee_wallet |
| 1 to n | trading_fees.recipients[0..recipient_count].wallet, in stored order |
No arguments. Claims apply to fees accrued on the bonding curve. Fees accrued after graduation belong to the DAMM v2 position and are claimed with claim_graduated_fees.
Launchpad: claim_graduated_fees
Claims a graduated launch's fees from its DAMM v2 position and pays them out with the same split as claim_fees. At migration DBC gives the whole position, permanently locked, to trading_fees; the lock prevents withdrawing liquidity, not claiming fees. The migrated pool collects fees in SOL only (DAMM v2 OnlyB, token B being the quote mint), so the claim is SOL and the base account receives nothing. HODL's share is computed from the pool's own protocol_fee_percent. Permissionless, with the temporary token accounts closed and their rent returned to the cranker.
Discriminator d9 fc e2 00 bb 0a ed a3
| # | Account | Writable | Signer | Address or derivation |
|---|---|---|---|---|
| 0 | cranker | Yes | Yes | Any wallet |
| 1 | global_config | No | No | ["global_config"], launchpad |
| 2 | trading_fees | Yes | No | ["fees", base_mint], launchpad |
| 3 | dbc_config | No | No | The launch's DBC config; its fee_claimer must be trading_fees |
| 4 | damm_pool_authority | No | No | ["pool_authority"], DAMM v2 |
| 5 | pool | No | No | The migrated DAMM v2 pool; token A base_mint, token B the quote mint |
| 6 | position | Yes | No | ["position", position_nft_mint], DAMM v2 |
| 7 | position_nft_account | No | No | ["position_nft_account", position_nft_mint], DAMM v2, owned by trading_fees |
| 8 | base_vault | Yes | No | ["token_vault", base_mint, pool], DAMM v2 |
| 9 | quote_vault | Yes | No | ["token_vault", quote_mint, pool], DAMM v2 |
| 10 | base_mint | No | No | The token |
| 11 | quote_mint | No | No | Wrapped SOL |
| 12 | trading_fees_quote_account | Yes | No | WSOL associated token account of trading_fees |
| 13 | trading_fees_base_account | Yes | No | Token-2022 associated token account of trading_fees for base_mint |
| 14 | token_base_program | No | No | Token-2022 |
| 15 | token_quote_program | No | No | SPL Token |
| 16 | damm_event_authority | No | No | ["__event_authority"], DAMM v2 |
| 17 | damm_program | No | No | DAMM v2 |
| 18 | associated_token_program | No | No | Associated Token Account |
| 19 | system_program | No | No | 11111111111111111111111111111111 |
Remaining accounts are the same as for claim_fees. No arguments. position_nft_mint is the first position NFT mint passed to migration_damm_v2.
DBC: swap2_with_transfer_hook (Fomo)
Buys and sells on the bonding curve are DBC swaps executed by Fomo. The swap itself carries no Fomo account. The Fomo signer authorizes the transfer by being a signer account of another top-level instruction in the same transaction, for example the funding account of the trader's idempotent associated token account creation (see Transfer gate).
Discriminator b7 5d 99 28 18 e6 c2 97
| # | Account | Writable | Signer | Address or derivation |
|---|---|---|---|---|
| 0 | pool_authority | No | No | DBC pool authority |
| 1 | config | No | No | The launch's DBC config |
| 2 | pool | Yes | No | DBC pool PDA |
| 3 | input_token_account | Yes | No | Trader's WSOL account (buy) or Token-2022 base account (sell) |
| 4 | output_token_account | Yes | No | Trader's Token-2022 base account (buy) or WSOL account (sell) |
| 5 | base_vault | Yes | No | DBC vault PDA for base_mint |
| 6 | quote_vault | Yes | No | DBC vault PDA for the quote mint |
| 7 | base_mint | Yes | No | The token; writable because the completing swap revokes the hook |
| 8 | quote_mint | No | No | Wrapped SOL |
| 9 | payer | No | Yes | Trader |
| 10 | token_base_program | No | No | Token-2022 |
| 11 | token_quote_program | No | No | SPL Token |
| 12 | referral_token_account | Yes | No | Optional; pass the DBC program ID for none |
| 13 | event_authority | No | No | DBC event authority |
| 14 | program | No | No | DBC |
Remaining accounts, in order:
| # | Account | Signer |
|---|---|---|
| 0 | Instructions sysvar | No |
| 1 | ["extra-account-metas", base_mint], hook | No |
| 2 | Instructions sysvar | No |
| 3 | Hook program | No |
Arguments
| Field | Type | Value |
|---|---|---|
params.amount_0 | u64 | Exact in and partial fill: amount in. Exact out: amount out |
params.amount_1 | u64 | Exact in and partial fill: minimum amount out. Exact out: maximum amount in |
params.swap_mode | u8 | 0 exact in, 1 partial fill, 2 exact out |
transfer_hook_accounts_info.slices | Vec<RemainingAccountsSlice> | One slice: accounts_type TransferHookBase, length 3 (accounts 1 to 3 above) |
DBC permits exactly one remaining account ahead of the declared slices, and it must be the instructions sysvar at index 0.
DBC: migration_damm_v2
Migrates a completed curve to DAMM v2. Permissionless and executed by Meteora's keeper on mainnet. Pass A8gMrEPJkacWkcb3DGwtJwTe16HktSEfvwtuDh2MCtck as remaining account 0. The migrated liquidity is permanently locked to the launch's trading_fees account. The migrated pool charges the launch's trading_fee_bps.
Launchpad: administrative
initialize_global_config and update_global_config are signed by the launchpad admin and are not used by integrations. update_global_config sets, among others, minimum_opening_buy_lamports, which must be above 0.
Hook
initialize_extra_account_meta_list is called by create_launch. execute is called by Token-2022 on each transfer. Neither is called directly.
Account layouts
All HODL accounts are Anchor accounts serialized with Borsh: an 8-byte discriminator followed by the fields in order, without padding.
GlobalConfig
Discriminator 95 08 9c ca a0 fc b0 d9, size 561 bytes, Borsh.
| Offset | Field | Type | Size |
|---|---|---|---|
| 0 | discriminator | [u8; 8] | 8 |
| 8 | admin | pubkey | 32 |
| 40 | hodl_fee_wallet | pubkey | 32 |
| 72 | holder_rewards_wallet | pubkey | 32 |
| 104 | tiers | [LaunchTier; 5] | 445 |
| 549 | multiple_fee_recipients_enabled | bool | 1 |
| 550 | holder_rewards_enabled | bool | 1 |
| 551 | allow_stock_tokens | bool | 1 |
| 552 | minimum_opening_buy_lamports | u64 | 8 |
| 560 | bump | u8 | 1 |
TradingFees
Discriminator 43 f2 ce 1c 9b 83 9f 8d, size 213 bytes, Borsh.
| Offset | Field | Type | Size |
|---|---|---|---|
| 0 | discriminator | [u8; 8] | 8 |
| 8 | base_mint | pubkey | 32 |
| 40 | recipients | [FeeRecipient; 5] | 170 |
| 210 | recipient_count | u8 | 1 |
| 211 | tier | u8 | 1 |
| 212 | bump | u8 | 1 |
LaunchTier (89 bytes)
| Offset | Field | Type | Size |
|---|---|---|---|
| 0 | migration_quote_threshold | u64 | 8 |
| 8 | sqrt_start_price | u128 | 16 |
| 24 | curve | [CurvePoint; 2] | 64 |
| 88 | curve_point_count | u8 | 1 |
CurvePoint (32 bytes)
| Offset | Field | Type | Size |
|---|---|---|---|
| 0 | sqrt_price | u128 | 16 |
| 16 | liquidity | u128 | 16 |
FeeRecipient (34 bytes)
| Offset | Field | Type | Size |
|---|---|---|---|
| 0 | wallet | pubkey | 32 |
| 32 | share_bps | u16 | 2 |
Errors
Launchpad errors
| Code | Name | Message |
|---|---|---|
| 6000 | OpeningBuyBelowMinimum | Opening buy is below the global config's minimum |
| 6001 | InvalidMetadata | Token name, symbol or uri is empty or too long |
| 6002 | UnknownTier | Tier must be A, B, C, D or E |
| 6003 | TierNotConfigured | That tier has not been configured yet |
| 6004 | FeeOutOfRange | Trading fee must be between 1.25% and 5% |
| 6005 | NoRecipients | A launch must name at least one fee recipient |
| 6006 | TooManyRecipients | A launch may name at most five fee recipients |
| 6007 | RecipientSharesDoNotSum | Fee recipient shares must total 10000 basis points |
| 6008 | RecipientShareIsZero | A fee recipient share must be greater than zero |
| 6009 | InvalidRecipient | A fee recipient wallet is the default pubkey |
| 6010 | DuplicateRecipient | The same wallet is listed as a fee recipient twice |
| 6011 | MultipleRecipientsDisabled | Naming more than one fee recipient is not enabled |
| 6012 | HolderRewardsDisabled | Naming the holder rewards wallet is not enabled |
| 6013 | NotAdmin | Only the admin may change the global config |
| 6014 | NothingToClaim | There are no fees to claim |
| 6015 | ClaimPayoutAccountsMismatch | Pass the HODL fee wallet and then every fee recipient, in the order the launch stored them |
| 6016 | FeeRateBelowHodlCut | This launch's fee rate is too low to cover HODL's cut |
| 6017 | RecipientWalletIsDefault | The recipient wallet is the default pubkey |
Hook errors
| Code | Name | Message |
|---|---|---|
| 6000 | UnauthorizedTransfer | Transaction is not signed by an authorized operator |
| 6001 | MalformedInstructionsSysvar | Instructions sysvar data is malformed |
| 6002 | MintHookMismatch | Mint does not have this program set as its transfer hook |
| 6003 | NotToken2022Mint | Mint is not a Token-2022 mint |
| 6004 | MetaListTooSmall | Existing extra-account-meta list is too small for the current layout |
DBC errors specific to hooked pools
| Error | Cause |
|---|---|
InvalidRemainingAccountsLength | More than one remaining account ahead of the declared slices, or the one present is not the instructions sysvar. |
PoolTypeMismatch | transfer_hook_accounts_info was None on a hooked pool. |
InsufficientLiquidity | The curve cannot fill the requested amount. Use partial fill. |
PoolIsCompleted | The curve has graduated. Trade the DAMM v2 pool. |