Challenge Library
Browse all 100 coding challenges across 5 categories. Each includes starter code, solution, tests, and hints.
Generate a Solana Keypair
Create a function that generates a new Solana keypair and returns the public key as a base58 string. Use the @solana/web3.js Keypair class to generate a random keypair.
Derive a PDA from Seeds
Write a function that derives a Program Derived Address (PDA) given a program ID and an array of seed buffers. Return both the PDA public key (base58) and the bump seed.
Build a Transfer Instruction
Create a function that builds a SystemProgram transfer instruction to send SOL from one account to another. Return the TransactionInstruction object.
Create a New Account
Write a function that builds a SystemProgram.createAccount instruction to allocate a new account with a given space and owner program. You must calculate the minimum rent-exempt balance.
Send SOL to an Address
Create a function that builds a complete Transaction containing a SOL transfer instruction. The transaction should be ready to sign and send (minus the recent blockhash).
Parse a Transaction Signature
Write a function that validates a Solana transaction signature. A valid signature is a base58-encoded string of 64 bytes (typically 87-88 characters). Return an object with isValid and the byte length.
Serialize Instruction Data
Implement a Rust function that serializes instruction data using Borsh. Define a struct with a variant (u8) and an amount (u64), then serialize it into a byte vector for use as instruction data.
Calculate Rent Exemption
Write a function that calculates the minimum balance for rent exemption given the account data size. Use the formula: the rent-exempt minimum is roughly (account_size + 128) * 2 years of rent at 3.48 SOL/year per MB, approximated by the constant 6960 lamports per byte.
Check Account Ownership
Write a Rust function that verifies whether a given account is owned by the expected program. This is a fundamental security check in Solana programs to prevent spoofed accounts.
Verify a Transaction Signer
Write a Rust function that checks whether an AccountInfo is a signer of the current transaction. This is critical for authorization checks in on-chain programs.
Build a Versioned Transaction
Create a function that constructs a V0 VersionedTransaction from an array of instructions, a payer, and a recent blockhash. Versioned transactions support address lookup tables and are the modern standard.
Use Compute Budget Instructions
Write a function that prepends compute budget instructions to a transaction — one to set the compute unit limit and one to set the priority fee (price per compute unit in micro-lamports).
Create an Address Lookup Table Entry
Write a function that builds the instructions to create a new address lookup table (ALT) and extend it with a list of addresses. ALTs reduce transaction size by replacing repeated pubkeys with indices.
Multi-Instruction Transaction
Build a function that creates a transaction containing multiple instructions atomically. If any instruction fails, the entire transaction rolls back. Combine a memo instruction with a SOL transfer.
Deserialize Account Data
Write a Rust function that deserializes raw account data bytes into a typed struct using Borsh. The struct represents a simple counter account with an authority (Pubkey) and a count (u64).
Handle Blockhash Expiry
Write a function that checks whether a transaction blockhash is still valid by comparing the current slot against the blockhash slot plus the max age (default 150 blocks). Return status and blocks remaining.
Cross-Program Invocation Basics
Write a Rust function that performs a CPI to transfer SOL via the System Program. This is the foundation for program composability on Solana — one program invoking another.
Simulate a Transaction
Write a function that prepares a transaction for simulation using a Connection. Simulation lets you dry-run a transaction to check for errors and estimate compute units without actually submitting it to the network.
Parse Transaction Logs
Write a function that parses Solana transaction log messages to extract program invocations, log messages, and compute unit consumption. This is essential for debugging and monitoring on-chain programs.
Build an Anchor Instruction
Write a function that manually constructs an Anchor instruction using the 8-byte discriminator hash, Borsh-serialized arguments, and an accounts array. This teaches the low-level mechanics behind Anchor's generated client code.
Mint SPL Tokens
Write a function that constructs the instructions to mint a specified amount of SPL tokens to a destination token account. The function receives the mint address, destination token account, mint authority, and the raw amount (already adjusted for decimals). Return the transaction instruction.
Transfer Tokens Between Wallets
Implement a function that builds a token transfer instruction. Given a source token account, destination token account, owner, and amount, return the appropriate SPL Token transfer instruction.
Create an Associated Token Account
Write a function that derives the Associated Token Account (ATA) address for a given wallet and mint, and returns the create-ATA instruction if needed. The function should return both the derived address and the instruction.
Calculate Constant Product Swap Output
Implement the constant product AMM formula (x * y = k). Given the input reserve, output reserve, and input amount, calculate the output amount after a swap. Account for a fee expressed in basis points (e.g., 30 = 0.3%).
Compute Liquidity Pool Share
Calculate the LP token amount a depositor should receive when adding liquidity to a constant product pool. Given the current reserves, total LP supply, and the deposited amounts, return the LP tokens to mint. Use the minimum ratio to prevent manipulation.
Oracle Price Feed Parsing
Parse a Pyth price feed account to extract the current price, confidence interval, and exponent. Validate the price is not stale by checking the timestamp against a maximum age parameter. Return a structured price result.
Calculate Lending Interest Rate
Implement a utilization-based interest rate model commonly used in lending protocols (similar to Aave/Solend). The model uses a kink point: below the kink, the rate increases linearly at a base slope; above the kink, a steeper jump slope applies. Return the borrow rate as a percentage with 6 decimal precision.
Determine Collateral Ratio
Calculate the collateral ratio for a lending position. Given the collateral value and borrowed value (both in USD), compute the ratio and classify the position health: "healthy" (>= 150%), "warning" (>= 120% and < 150%), or "liquidatable" (< 120%). Use oracle prices for conversion.
Detect Flash Loan Pattern
Implement a function that analyzes a sequence of transaction instructions to detect a flash loan pattern. A flash loan is identified when: (1) a borrow instruction occurs, (2) arbitrary instructions follow, and (3) a repay instruction for the same or greater amount occurs within the same transaction. The repay must include the flash loan fee.
Compute Yield Farming Rewards
Calculate pending yield farming rewards for a staker. The reward distribution uses a global accumulator pattern: rewards accrue proportionally to each staker's share of the total staked amount. Implement the reward debt model used by MasterChef-style contracts.
Calculate Impermanent Loss
Implement a function to calculate impermanent loss for a liquidity provider in a constant product AMM. Given the initial price and current price of the token pair, compute the loss compared to simply holding the assets. Return the loss as a percentage.
Order Book Matching Engine
Implement a simple order book matching engine. Given a new incoming order (buy or sell) and the existing order book, match the order against resting orders using price-time priority. Return the list of fills and any remaining unfilled quantity.
Calculate Time-Weighted Average Price
Implement a TWAP (Time-Weighted Average Price) calculator. Given a series of price observations with timestamps, compute the TWAP over a specified time window. Each price is weighted by the duration it was active.
Fee Structure Implementation
Implement a tiered fee structure for a DEX protocol. Fees decrease based on the user's 30-day trading volume. The tiers are: Tier 1 (< 10K) = 30 bps, Tier 2 (10K-100K) = 25 bps, Tier 3 (100K-1M) = 20 bps, Tier 4 (1M-10M) = 15 bps, Tier 5 (>= 10M) = 10 bps. Also implement maker-taker split where makers get a 40% rebate on fees.
Slippage Protection Check
Implement a comprehensive slippage protection module for a DEX. Given the expected output amount and a maximum slippage tolerance (in bps), calculate the minimum acceptable output. Also implement price impact estimation by comparing the execution price to the mid-market price, and reject trades that exceed configurable impact limits.
Multi-Hop Swap Routing
Implement a multi-hop swap router that finds the best route through multiple liquidity pools. Given a set of pools with their reserves and fees, find the optimal path from input token to output token (up to 3 hops). Use the constant product formula at each hop to calculate the final output.
Vault Deposit and Withdraw Logic
Implement a yield vault that accepts deposits and withdrawals using a shares-based accounting model (like ERC-4626). Depositors receive vault shares proportional to their deposit relative to total assets. Withdrawals burn shares and return the proportional underlying assets. Handle edge cases like first deposit, rounding, and donation attacks.
Staking Reward Distribution
Implement a staking reward distribution system that supports multiple reward tokens, time-locked bonuses, and early unstake penalties. Stakers earn base rewards proportional to their share, plus bonus multipliers based on lock duration (30d=1x, 90d=1.5x, 180d=2x, 365d=3x). Early unstaking forfeits the bonus and incurs a 10% penalty on the base reward.
Governance Token Allocation
Implement a governance token allocation system with vesting schedules. Supports multiple allocation categories (team, investors, community, treasury) with different vesting cliffs and linear unlock periods. Calculate the total unlocked, claimable, and still-vesting amounts at any given timestamp.
Protocol Fee Accounting
Implement a protocol fee accounting system that tracks fees across multiple pools, distributes them to stakeholders (protocol treasury, stakers, referrers), and handles fee epochs for periodic distribution. The system must maintain an audit trail and support fee parameter changes that take effect at the next epoch boundary.
Define NFT Metadata Structure
Create a TypeScript interface and factory function for NFT metadata following the Metaplex Token Metadata standard. The metadata must include name, symbol, uri, seller_fee_basis_points, and a creators array.
Create a Metaplex Core Asset
Write a TypeScript function that builds the instruction data for creating a Metaplex Core asset. The function should assemble the correct account keys and arguments for the create instruction.
Build a Collection
Implement a Rust struct and constructor for an on-chain NFT collection. The collection tracks name, uri, size, and the current number of minted items.
Parse NFT Attributes
Write a TypeScript function that parses a JSON metadata string and extracts NFT attributes into a structured map. Handle the standard Metaplex attributes array format.
Enforce Royalty Percentages
Implement a Rust function that validates and enforces royalty configurations for NFT sales. Royalties use basis points (1 bp = 0.01%). The total across all recipients must not exceed a maximum.
Verify Creator Addresses
Write a TypeScript function that validates a list of NFT creators. Each creator must have a valid base58 public key, and exactly one creator must be marked as verified. Creator shares must sum to 100.
Generate Metadata URI
Implement a TypeScript function that constructs an off-chain metadata JSON object compliant with the Metaplex standard and returns a data URI. The metadata must include image, external_url, attributes, and properties.files.
Compressed NFT (cNFT) Basics
Implement a TypeScript function that constructs the leaf data for a compressed NFT. The leaf schema includes owner, delegate, nonce, data hash, and creator hash, packed into a single hash.
Merkle Tree for cNFTs
Build a simple Merkle tree implementation in TypeScript for compressed NFT leaf verification. Implement tree construction from leaves and root computation.
Verify Merkle Proof
Implement a Rust function that verifies a Merkle proof for a compressed NFT leaf. Given a leaf hash, proof hashes, and the expected root, verify the leaf belongs to the tree.
NFT Transfer Hook
Implement a Rust transfer hook that validates NFT transfers. The hook checks a cooldown period between transfers and optionally enforces a whitelist of allowed recipients.
Burn an NFT
Write a TypeScript function that constructs the instruction data for burning an NFT. The function must verify ownership, handle both regular and compressed NFTs, and build the correct accounts list.
Set Delegate Authority
Implement a Rust function that manages delegate authority for Metaplex Core assets. Support setting, revoking, and validating delegates with different roles (Transfer, Sale, Utility).
Freeze/Thaw NFT
Implement a TypeScript state machine that manages NFT freeze and thaw operations. Track freeze state, authority, and enforce proper state transitions with a freeze history log.
Update Authority Pattern
Implement a Rust authority management system for NFT collections that supports multisig update authority, timelocked transitions, and authority rotation with a pending/accept pattern.
Collection Verification
Implement a Rust on-chain collection verification system. The verifier validates that an NFT belongs to a collection using PDA derivation, checks the collection authority signature, and manages verified/unverified states.
Calculate Trait Rarity
Build a TypeScript rarity calculation engine for NFT collections. Compute statistical rarity scores, percentile rankings, and information-theoretic rarity (Shannon entropy) for trait combinations.
Candy Machine Configuration
Implement a Rust Candy Machine configuration builder that validates guard settings, phases, whitelist allocation, and pricing tiers. Enforce constraints like max supply, start/end times, and mint limits.
Guard Group Setup
Implement a TypeScript guard group configuration system for Candy Machine v3. Support multiple guard types (SOL payment, token gate, NFT gate, allow list, mint limit) with validation and serialization.
NFT Token Gating
Implement a Rust token gating system that grants access based on NFT ownership. Support multiple gating criteria: single NFT ownership, collection membership, trait-based access, and minimum holding duration.
Validate Account Owner
Implement a function that validates whether an account is owned by the expected program. On Solana, any account can be passed to an instruction — failing to verify the owner allows attackers to substitute forged accounts with arbitrary data.
Verify Transaction Signer
Write a function that verifies an account has signed the transaction. Without signer verification, anyone can invoke privileged instructions by passing an unsigned authority account.
PDA Seed Validation
Implement a function that validates a PDA account by re-deriving it from expected seeds and comparing the result. Failing to verify PDA derivation lets attackers substitute a PDA from a different seed set to bypass access control.
Detect Arithmetic Overflow
Implement safe arithmetic operations that detect overflow instead of silently wrapping. Unchecked math in token/balance logic can lead to catastrophic fund loss — e.g., wrapping u64::MAX + 1 back to 0.
Reinitialization Guard
Implement a guard that prevents an already-initialized account from being reinitialized. Without this check, an attacker can call the initialize instruction again to overwrite critical state such as the authority pubkey.
Closing Account Drain Prevention
Implement secure account closing logic that zeroes out account data and transfers all lamports to the recipient atomically. Improper closing allows attackers to exploit the account before it is garbage-collected by the runtime, or to intercept the lamport transfer.
Type Confusion Detection
Write a validation function that checks an account discriminator to prevent type confusion attacks. In Anchor, every account type has an 8-byte discriminator prefix. If you skip this check when using raw AccountInfo, an attacker can pass a VaultAccount where a UserAccount is expected.
CPI Privilege Escalation Check
Implement a function that validates the target program of a CPI call before invoking it. Without this check, an attacker can substitute a malicious program ID in the CPI accounts, causing your program to invoke attacker-controlled code with elevated privileges.
Duplicate Mutable Accounts
Implement a check that detects when the same account is passed twice in mutable positions. If two mutable references alias the same account, the second write silently overwrites the first — enabling double-spend attacks on vaults.
Bump Seed Canonicalization
Implement PDA creation and validation that stores and reuses the canonical bump seed. Recalculating bumps on every call wastes CU, and using a non-canonical bump can create a different PDA than expected — breaking account lookups and enabling subtle substitution attacks.
Authority Validation Pattern
Implement a multi-level authority validation system that supports both a primary authority and an optional delegate, with different permission levels. This pattern is common in DeFi protocols where operations need tiered access control.
Rent Exemption Verification
Implement a function that verifies an account holds enough lamports to be rent-exempt. Accounts below the rent-exempt threshold are gradually drained by the runtime and eventually garbage-collected, causing unexpected data loss mid-protocol.
Instruction Introspection
Implement instruction introspection to verify that a specific instruction exists in the current transaction. This technique is used to enforce that certain safety instructions (e.g., a price oracle refresh) are called in the same transaction, preventing stale data exploits.
Cross-Program Signer Verification
Implement verification logic for cross-program invocations that ensures a PDA signer from the calling program is legitimate. When program A invokes program B via CPI with PDA signer seeds, program B must verify that the signer PDA is actually owned by program A and derived from expected seeds.
Account Data Matching
Implement validation that cross-references data between multiple accounts to detect inconsistencies. For example, verifying that a token account belongs to the expected mint and owner — preventing an attacker from substituting a token account they control.
Deserialization Attack Prevention
Implement safe deserialization that validates data integrity before processing. Malformed or truncated data passed to unchecked deserialization can cause panics, read out-of-bounds memory, or produce silently incorrect values that corrupt protocol state.
Time-Based Attack Vector Check
Implement a time-lock mechanism with validation against clock manipulation attacks. Validators control the Clock sysvar, so on-chain timestamps can drift. Your implementation must account for reasonable clock skew while still enforcing time-based constraints like cooldowns and vesting schedules.
Front-Running Prevention
Implement a commit-reveal scheme to prevent front-running on Solana. In a commit phase, users submit a hash of their action. In the reveal phase, they provide the preimage. This prevents validators or MEV bots from seeing the action and inserting their own transaction first.
Sandwich Attack Detection
Implement a client-side sandwich attack detector that analyzes a transaction's surrounding transactions in a block to identify potential sandwich patterns. A sandwich attack places a buy before and a sell after a victim's swap to extract value.
Remaining Accounts Privilege Check
Implement validation for Anchor's `remaining_accounts` — the untyped escape hatch that bypasses Anchor's automatic account validation. Without manual checks, remaining accounts are a common attack vector where an attacker passes unauthorized or malicious accounts.
Token-2022 Program Basics
Create a new Token-2022 mint using the SPL Token-2022 program. Initialize the mint with a specified number of decimals and a mint authority. This is the foundation for all Token Extensions work.
NonTransferable Token Mint
Create a soulbound token by initializing a Token-2022 mint with the NonTransferable extension. Tokens minted from this mint cannot be transferred between wallets, making them ideal for XP, reputation, or credential tokens.
PermanentDelegate Setup
Initialize a Token-2022 mint with the PermanentDelegate extension. This grants an authority permanent delegate access over ALL token accounts for this mint, enabling force burns or transfers -- useful for compliance, clawback, or game mechanics.
TransferFee Configuration
Configure a Token-2022 mint with the TransferFee extension. Every transfer automatically withholds a percentage fee in the recipient token account. This enables protocol-level fee collection without smart contract intermediaries.
Harvest Withheld Transfer Fees
Implement fee harvesting for a TransferFee-enabled Token-2022 mint. Withheld fees accumulate in recipient token accounts and must be harvested (moved to the mint) before withdrawal. Implement both the harvest and withdraw steps.
MintCloseAuthority Extension
Create a Token-2022 mint with the MintCloseAuthority extension. By default, SPL Token mints cannot be closed. This extension allows a designated authority to close the mint and reclaim the rent-exempt SOL, provided the supply is zero.
DefaultAccountState Extension
Implement a Token-2022 mint with DefaultAccountState set to Frozen in Rust. Every new token account created for this mint will start frozen, requiring an explicit thaw from the freeze authority before tokens can be transferred. This is useful for KYC-gated tokens.
ImmutableOwner Extension
Create a token account with the ImmutableOwner extension. This prevents the owner of a token account from being reassigned, protecting against a class of token account hijacking attacks. Note: Associated Token Accounts (ATAs) for Token-2022 already include this extension by default.
MemoTransfer Requirement
Create a token account with the MemoTransfer extension enabled. When enabled, all incoming transfers to this account require a preceding memo instruction in the same transaction. This is useful for compliance, exchange deposits, and audit trails.
InterestBearing Token Mint
Create a Token-2022 mint with the InterestBearingConfig extension. This extension allows the UI display amount to grow over time based on a configurable interest rate, without actually minting new tokens. The on-chain balance stays constant but the "amount to UI amount" conversion factors in accrued interest.
ConfidentialTransfer Basics
Set up a Token-2022 mint with the ConfidentialTransfer extension. This extension enables encrypted token balances using zero-knowledge proofs (ElGamal encryption). Configure the mint, prepare a token account for confidential transfers, and deposit tokens into the confidential balance.
TransferHook Program
Implement a TransferHook program in Rust that is invoked automatically on every token transfer. The hook validates custom conditions (e.g., allowlist check) and can reject transfers. Includes the mint setup with TransferHook extension pointing to your program.
CPI Guard Configuration
Enable the CPI Guard extension on a Token-2022 token account. When enabled, CPI Guard prevents certain dangerous actions from being performed via Cross-Program Invocations (CPIs), such as transferring tokens or closing the account through a malicious program. This protects users from CPI-based exploits.
MetadataPointer Extension
Initialize a Token-2022 mint with the MetadataPointer extension. This extension tells clients where to find the token metadata -- it can point to the mint itself (when using the TokenMetadata extension), an external Metaplex metadata account, or any other address. This is the foundation for on-chain token metadata.
TokenMetadata Extension
Create a Token-2022 mint with both MetadataPointer and TokenMetadata extensions. Store the token name, symbol, URI, and custom additional fields directly on the mint account -- no external metadata program needed. This is the native Token-2022 approach to on-chain metadata.
GroupPointer Extension
Configure a Token-2022 mint with the GroupPointer extension. This extension designates a mint as a "group" that can contain member tokens. Combined with GroupMemberPointer, this enables on-chain token collections, game item sets, or course credential groups -- all natively in Token-2022.
GroupMemberPointer Extension
Create a Token-2022 mint with the GroupMemberPointer extension to designate it as a member of a token group. This mint references its parent group mint, enabling on-chain collection relationships. Together with GroupPointer, this creates a full group/member hierarchy for credential sets, NFT collections, or course modules.
Token Wrapping: Legacy to Token-2022
Implement token wrapping to convert legacy SPL tokens into Token-2022 tokens with extensions. Create a wrapping vault that holds legacy tokens and mints equivalent Token-2022 tokens with metadata. This pattern enables adding extensions (metadata, transfer fees, etc.) to existing tokens.
Realloc: Adding Extensions to Existing Mints
Reallocate a Token-2022 mint account to add new extensions after creation. Token-2022 supports reallocating mint accounts to accommodate additional extensions that were not included at creation time. This uses the Reallocate instruction to grow the account and then initializes the new extension.
Multi-Extension Mint Creation
Create a Token-2022 mint with multiple extensions enabled simultaneously. Combine NonTransferable, PermanentDelegate, MintCloseAuthority, and MetadataPointer in a single mint -- the pattern used by Superteam Academy for soulbound XP tokens. Understanding extension composition is essential for production Token-2022 work.