The Metaplex Candy Machine is among the most popular smart contracts used for NFT minting on Solana. Recently, it has even implemented sophisticated logics for detecting and taxing bots.
How does the candy machine program work internally? What are its intended use cases and dependencies? How does it detect bots? This article elaborates on these technical details.
The Candy Machine is a distribution program used by
For 1, the distributor must first call the InitializeCandyMachine instruction to create a candy machine:
A candy machine has a few important pieces of information:
The CandyMachineData includes the necessary attributes for NFT minting:
price is the price paid by users to mint an NFT, with optional discount configured in whitelist_mint_settings.
creators specifies the list of creators of the NFT collection.
items_available is number of NFTs in the collection.
For 2, any one can mint NFTs through a candy machine created in Step 1, by calling the MintNFT instruction. MintNFT is a fairly complex instruction (over 600 lines of source code in Rust). We next explain MintNFT in detail.
To mint an NFT on Metaplex, there are several essential steps (see Part 3: Metaplex Token Metadata):
The MintNFT instruction depends on the token metadata program and it includes all the above four steps and, additionally, a logic for users to pay for the minted NFT and logics for detecting and taxing bots.
To process the MintNFT instruction, the function handle_mint_nft is invoked with a number of input accounts, e.g., candy_machine , candy_machine_creator , wallet , metadata , mint , mint_authority , etc.
The user has to pay a price to mint each NFT. The price is specified in the candy machine in the amount of either a SPL token or Sol:
When SPL token is used, the token mint is specified by candy_machine.token_mint and the payment is transferred from the source token account to the candy_machine.wallet account by spl_token_transfer (line 468):
Otherwise, the price amount of Sol is transferred from the payer account to the wallet account directly via system_instruction::transfer (line 482):
The distributor can also offer a discount price for users through configuring whitelist_mint_settings in candy_machine.data:
For every NFT in the collection, the candy machine maintains a ConfigLine containing the NFT’s name and uri:
If candy_machine.data.hidden_settings is set, the minted NFT name is ordered by a mint_number (e.g. Okay Bear #1756):
The mint_number is incremented by one upon each successful MintNFT call.
Otherwise if hidden_settings is not set, the MintNFT instruction uses an index calculated from recent_slothashes.data to determine which NFT to mint from the collection:
The get_config_line function takes the modded index as input and traverses through the remaining NFTs in the collection (using a bit mask):
Finally, after checking all constraints and setting up the CPI account data to call the token metadata program, the following three functions are invoked in the written order to complete the NFT minting process:
Note that the candy_machine_creator account (PDA created by the candy machine program) is also specified as a creator of the NFT:
Readers may wonder, to mint an NFT, why should we use a candy machine instead of calling the token metadata program directly?
These two programs have different use cases:
The candy machine program detects bots and charges a fee (BOT_FEE: 0.01 Sol) for each bot call to the MintNFT instruction:
The bot detection logic is implemented in the handle_mint_nft function, considering a good number of different scenarios:
Step 1. bots calling handle_mint_nft via CPI. Only CPI called by the Gumpdrop program is not considered as bots. GUMDROP_ID: gdrpGjVffourzkdDRrQmySw4aTHr8a3xmQzzxSwFD1a
Step 2. bots missing set collection during the mint instruction (for candy machine with collection set):
Step 3. bot transactions containing any CPI from an unknown program:
The known programs include the System program, SPL Token program, Associated Token program, and the Candy Machine program itself. Transactions containing any CPI not from the known programs are considered as bots.
Step 4. bots calling MintNFT after minting has stopped (after a certain timestamp):
Step 5. bots calling MintNFT after all available NFTs have been redeemed:
Step 6. bots missing gateway token when the candy machine’s gatekeeper is set
Step 7. bots calling MintNFT before the candy machine’s go_live_date:
Step 8. bots calling MintNFT with incorrect whitelist_token_mint:
Step 9. bots calling MintNFT with whitelist_token_account while the candy machine has no discount and no presale (i.e., it has a forced whitelist):
The authority can make changes to the candy machine through a few additional instructions: UpdateCandyMachine, AddConfigLines, SetCollection, RemoveCollection, SetCollectionDuringMint, as well as WithdrawFunds. These instructions are permissioned (signed by candy_machine.authority) otherwise will abort the transaction.
sec3 is a security research firm that prepares Solana projects for millions of users. sec3’s Launch Audit is a rigorous, researcher-led code examination that investigates and certifies mainnet-grade smart contracts; sec3’s continuous auditing software platform, X-ray, integrates with GitHub to progressively scan pull requests, helping projects fortify code before deployment; and sec3’s post-deployment security solution, WatchTower, ensures funds stay safe. sec3 is building technology-based scalable solutions for Web3 projects to ensure protocols stay safe as they scale.
To learn more about sec3, please visit https://www.sec3.dev