Skip to main content

Solana Quizlet 101

要求:聚焦在solana / spl / solana dapp program 的工程实现细节和攻击面 / checklist

Solana Infrastructure

  • What is a solana slot? How long is a solana slot?
  • What is a blockhash? What is Solana PoH? what does blockhash has something to do with PoH?
  • Each Solana account is identifiable by its unique address, represented as 32 bytes in the format of an Ed25519 PublicKey. How is solana account addresses different from ethereum EOA addresses?
  • Why I cannot find a block by blockhash on solana explorers? (only by block id)
  • What is Address Lookup Table Account (ALT) ?

Solana Transaction

  • What's the relationship between a transaction and an instruction (ix)?
  • What is Compute Budget ? Please compare it with Ethereum gas accounting. What's same and what's different ?
  • Please breifly explain what can Compute Budget Program do (ComputeBudget111111111) ? reference tx.
  • What is Compute Uint(CU)? What is CU Limit / CU Price ? What is the differnece between CU Price and CU Limit?
  • Can solana programs set CU Limit and CU price themselfs through CPI ?
  • If I do not set the CU Limit, what's the default value? Is there a max cap for CU Limit ?
  • If I do not set the CU Price, what's the default value? Is there a max cap for CU Price?
  • What is Prioritization Fee ?
  • Consider a tx with a single signer. CU Limit not set. CU Price not set. How much fee will the signer pay for this tx? what's the difference if this tx fails ?
  • Consider a tx with a single signer. CU Limit = 1.4M. CU Price not set. How much fee will the signer pay for this tx? what's the difference if this tx fails ?
  • Consider a tx with a single signer. CU Limit = 1.4M. CU Price = 500k. How much fee will the signer pay for this tx? what's the difference if this tx fails ?
  • Consider a tx with a single signer. CU Limit not set. CU Price = 500k. How much fee will the signer pay for this tx? what's the difference if this tx fails ?
  • Consider a tx with a single signer. CU Limit = 2.8M. CU Price = 500k. How much fee will the signer pay for this tx? what's the difference if this tx fails ?
  • Can I call the set CU Limit ix and set CU price ix at the end of my transaction ?
  • Since users can have multiple ixs in one single transaction, does it eliminate front-running ?
  • What is versioned transaction ? What's the difference between versioned transaction and legacy transaction ?
  • There are three commitment statuses for a tx: 1) Processed 2) Confirmed 3)Finalized What's the difference ?
  • Is there compute unit limitations for each transaction ? How much ?
  • Is there compute unit limitations for each block ? How much ?
  • Is there compute unit limitations for each account per block ? How much ?

Solana Account Model

On Solana, all data is stored in what are referred to as "accounts". The way data is organized on Solana resembles a key-value store, where each entry in the database is called an "account".

  • What types of data can accounts store, and what is the maximum storage capacity?
  • What is the requirement for a rent deposit in SOL for accounts, and how is it related to the amount of data stored?
  • If I create a new account but do not store data in this account, should I pay the rent exempt for this account?
  • Who can modify the data or deduct the lamport balance of an account, and who is allowed to increase the balance?
  • How to query account data on chain ?

Wording

In Solana, the word ==account / authority / mint== is used everywhere. Compare the following words:

  1. ==owner==: Solana Account Model / Solana Token Account
  • In the solana programing model, each account has its owner.

  • In the solana spl token context, each solana token account has its owner.

    Please compare.

  1. ==authority==: Solana Token Mint / Anchor SPL constraint
  • In the solana spl token context, each individual token mint account has a field called mint_authority.

  • In anchor, there is a constraint like token::authority = payer.

    Please compare.

  1. ==mint==: Solana Token Account / Solana Token Mint
  • In the solana spl token context, each solana token account has a field called mint.

  • In the solana spl token context, each individual token mint account has a field called mint_authority.

    Please compare.

Solana Tokens

  1. Please explain what is the sync native instruction of the token program
  2. What is the size of a classic token account
  3. What is the minimum rent exempt for a classic token account
  4. Please explain the difference between a wSOL token and normal token
  5. Do native token accounts has rent exempt ?
  6. Please explain how does tools like https://claimyoursol.com/ works
  7. What will happen when a token account's balance is reduced to zero during a tranfer instruction? Will the empty account be closed and rent exempt returned?
  8. What will happen if I trys to close a native account? Under what circumstances will it fail?
  9. What will happen if I trys to close a non-native account? Under what circumstances will it fail?
  10. Here is the account structure definition of a solana token account. Please explain what does the field mint stands for? What is the u64 number of the field is_native stands for?
/// Account data.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Account {
/// The mint associated with this account
pub mint: Pubkey,
/// The owner of this account.
pub owner: Pubkey,
/// The amount of tokens this account holds.
pub **amount**: u64,
/// If `delegate` is `Some` then `**delegated_amount**` represents
/// the amount authorized by the delegate
pub delegate: COption<Pubkey>,
/// The account's state
pub state: AccountState,
/// If is_native.is_some, this is a native token, and the value logs the rent-exempt reserve. An
/// Account is required to be rent-exempt, so the value is used by the Processor to ensure that
/// wrapped SOL accounts do not drop below this threshold.
pub is_native: COption<u64>, // why not bool : the value logs the rent-exempt reserve
/// The amount delegated
pub delegated_amount: u64,
/// Optional authority to close the account.
pub close_authority: COption<Pubkey>,
}

/// Account state.
#[repr(u8)]
#[derive(Clone, Copy, Debug, Default, PartialEq, IntoPrimitive, TryFromPrimitive)]
pub enum AccountState {
/// Account is not yet initialized
#[default]
Uninitialized,
/// Account is initialized; the account owner and/or delegate may perform
/// permitted operations on this account
Initialized,
/// Account has been frozen by the mint freeze authority. Neither the
/// account owner nor the delegate are able to perform operations on
/// this account.
Frozen,
}
  1. Here is the account structure definition of a solana token mint account. Please explain what does the field mint_authority stands for.
/// Mint data.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Mint {
/// Optional authority used to mint new tokens. The mint authority may only be provided during
/// mint creation. If no mint authority is present then the mint has a fixed supply and no
/// further tokens may be minted.
pub **mint_authority**: COption<Pubkey>,
/// **Total supply of tokens.**
pub **supply**: u64,
/// Number of base 10 digits to the right of the decimal place.
pub decimals: u8,
/// Is `true` if this structure has been initialized
pub is_initialized: bool,
/// Optional authority to freeze token accounts.
pub freeze_authority: COption<Pubkey>,
}
  1. What is the difference between transfer and transfer_checked instruction of the token program?
accounts.push(AccountMeta::new(*source_pubkey, false));
accounts.push(AccountMeta::new(*destination_pubkey, false));
accounts.push(AccountMeta::new_readonly(
*authority_pubkey,
signer_pubkeys.is_empty(),
));

let data = TokenInstruction::Transfer { amount }.pack();
accounts.push(AccountMeta::new(*source_pubkey, false));
accounts.push(AccountMeta::new_readonly(*mint_pubkey, false));
accounts.push(AccountMeta::new(*destination_pubkey, false));
accounts.push(AccountMeta::new_readonly(
*authority_pubkey,
signer_pubkeys.is_empty(),
));

let data = TokenInstruction::TransferChecked { amount, decimals }.pack();
  1. What's token 2022 ? How do token 2022 extends the original token standard ?

Solana Programs

What is solana native program? What's the difference between normal program and native program?

Please enumerate several solana native progarm.

  • is BPF loader a native program ?

  • is system program (11111111111111111111111111111111) a native program ?

  • is token program a natvie program ?

  • is native loader (NativeLoader1111111111111111111111111111111) a natvie program ?

    \

  • What's ebpf ? What's rbpf ? What's sbpf ?

  • What is a transaction ? What is an instruction ?

  • What is account data reloading ? Is it done by anchor automatically ? When should account data be realoaded ?

  • Can solana program call it-self? (self-recursion) Can soalan program call its caller (re-enter) ?

  • How is Call stack depth limited ? How is CPI call depth limited?

Please tell the difference between a Solana program:

  • returning an Error (Result<T, E>)
  • panics while executing (like DivisionByZero)

————

  • Is there a maximum cap for the account number I can pass in to a program invocation ? Or is there any restrictions on the account number / account size I passed in ?
  • When deploying a new program, which instructions are called ?

PDA

  • What is pda? What can it do ? Why solana program need pda ?

  • What is the difference between a pda and a normal account ? How can you differentiate a pda from normal account ?

  • What is the seed of a pda? What is the bump seed of a pda ? What is Canonical Bump Seed?

What is the difference between create_program_address and find_program_address functions?

  • pub fn find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> (Pubkey, u8)
  • pub fn create_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> Result<Pubkey, PubkeyError>

What's the difference between the following two anchor seed constraint group ?

#[account(
mut,
seeds = [b"12", b"3"],
bump
)]
pub a: Account<'info, NewAccount>,
#[account(
mut,
seeds = [b"1", b"23"],
bump
)]
pub a: Account<'info, NewAccount>,
  • What is Cross Program Invocation ?

  • What is the difference between an instruction in a transaction and CPI ?

  • What is invoke() ? What is invoke_signed() ? What's the difference ?

Anchor

Anchor is an all-on-one solana program development framework. Auditor should be famillar with anchor.

  • What's avm ? What will avm do when switching between different anchor versions ?

  • What happens when you run anchor build.

  • What is the differenct between solana cargo-build-sbf and anchor build ?

  • What happens when you run anchor test.

  • What is the minimum size that you should alloc for the following UsdcLedger account ? (Anchor account size)

  • What is the output of std::mem::size_of<UsdcLedger>() ?

use anchor_lang::prelude::*;

#[account]
#[repr(C)]
pub struct UsdcLedger {
pub a: bool,
pub b: u128,
pub c: u8,
pub d: [UsdcHolder; 5],
pub e: Vec<UsdcHolderEnum>, // element number = 5
pub f: Option<String>,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
#[repr(C)]
pub struct UsdcHolder {
pub address: Pubkey,
pub base_amount: u64,
pub balance: f64,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub enum UsdcHolderEnum {
Usdc(u64),
Jlp(u128),
}
  • What is a anchor has_one constraint? What are the final output contraint of these rust attribute marcos?
#[account(mut, has_one = authority)]
pub data: Account<'info, MyData>,
pub authority: Signer<'info>
  • Please compare anchortoken vs associate_token constraint. What are the final output contraint of these rust attribute marcos?
#[account(
init,
payer = payer,
token::mint = mint,
token::authority = payer,
)]
pub token: Account<'info, TokenAccount>,
#[account(
init,
payer = payer,
associated_token::mint = mint,
associated_token::authority = payer,
)]
pub token: Account<'info, TokenAccount>,
  • What is the difference between Option<Account<'info, T>> and Account<'info, T> ? If this account should be a None, what should pass in at this account position ?
pub token: Option<Account<'info, TokenAccount>>,
  • What is the difference between Box<Account<'info, T>> and Account<'info, T> ?

⭐ Please distinguish between the following different anchor account types, What are the final output contraint of these types enforced by anchor ?

* Account<'info, T>
* Program<'info, T>
* Signer<'info>
* SystemAccount<'info>
* Sysvar<'info, T>
* Interface<'info, T>
* InterfaceAccount<'info, T>
* UncheckedAccount<'info>
* AccountInfo<'info>
* AccountLoader<'info, T> (what is **Zero-copy deserialization**)

Does anchor AccountLoader::load_mut() check the account owner?

#[derive(Accounts)]
pub struct SetData<'info> {
#[account(mut)]
pub my_account: Account<'info, MyData>,
pub program: Interface<'info, MyProgram>,
pub my_account: InterfaceAccount<'info, MyData>
pub acc: UncheckedAccount<'info>,
pub oracle: AccountInfo<'info>,
pub bar: AccountLoader<'info, Bar>,
}
  • What's the difference between Interface and InterfaceAccount? What's the difference between Owner and Owners trait.
  • What's the difference between UncheckedAccount and AccountInfo ?
  • Please illustrate the data structure layout that is passed into the solana program, which is then deserlized by anchor framework. Following is a short list, what does each field means?

————

  • u64 - num_accounts
  • num entries:
    • u8 - dup_info
    • u8 - is_signer
    • u8 - is_writable
    • u8 - executable
    • u32 - original_data_len_offset
    • Pubkey - key
    • Pubkey - owner
    • u64 - lamports
    • u64 - data_len
    • data_len - data
    • MAX_PERMITTED_DATA_INCREASE - padding
    • align to 2**8 8个字节对齐
    • u64 - rent_epoch
  • u64 - instruction_data_len
  • instruction_data_len - ix data
  • Pubkey = program_id

————

  • What does the following realloc constraint group means ? What are the final output contraint of these realloc anchor attribute marcos?
#[derive(Accounts)]
#[instruction(len: u32)]
pub struct IncreaseUsdcLedgerCtx<'info> {
#[account(
mut,
realloc = len as usize,
realloc::zero = false,
realloc::payer = signer
)]
pub usdc_holder: AccountLoader<'info, UsdcLedger>,
  • The official solana-program create also has a realloc methold on AccountInfo. What's the difference between anchor realloc constraint group and the AccountInfo::realloc method ? Is there extra checks ?

  • Why reallocation overMAX_PERMITTED_DATA_INCREASEis not allowed ? Please reason about it based on the solana program input parameter layout.

  • What is solana sysvar? How do solana sysvars different from Ethereum global variables?

  • Can a solana program A access other instructions metadata in the transaction that do not interact with program A? How ?

  • Function Signatures: what is the function selector for the initialize function that anchor compiles into ?

#[program]
pub mod defi {
use super::*;

pub fn initialize(ctx: Context<InitializeCtx>) -> Result<()> {
instructions::initialize(ctx)
}
}
  • Account Discriminators: What is the account discriminator the anchor stroes in the first 8 bytes of the following account?
#[account(zero_copy(unsafe))]
#[repr(C)]
pub struct JlpLedger {
pub total_base_amount: u64,
...
}

Common Solana Vulnerabilities

Please illustrate the key points on the following common solana pitfalls. Does anchor completely or partially resolve these issues ?

  • Account Type Confusion
  • Missing Constraint
    • Associated Token Account
    • Signer
  • Integer Overflow / Underflow
  • Arbitrary signed program invocation
  • Account Reloading
  • Account Data Reallocation
  • Bump Seed Canonicalization
  • Seed Collisions
  • Misuse of Anchor's ctx.remaining_accounts

Rust Basics

  • If the following rust program compiles, what's its output ? (rust floating point number division)
fn main() {
let res = 1.0 / 0.0;
println!("{res}");
}
  • If the following rust program compiles, what's its output ? (rust integer division)
fn main() {
f(1,0);
}

fn f(a: u64, b: u64) {
let res = a / b;
println!("{res}")
}
  • What's the difference between debug build & release build? Which build profile does anchor use in default?
  • Please explain how should a Rc<RefCell<T>> type be used and why. For example, here is the AccountInfo struct definition. You can find that both lamports and data field are Rc<RefCell<T>>
/// Account information
#[derive(Clone)]
#[repr(C)]
pub struct AccountInfo<'a> {
/// Public key of the account
pub key: &'a Pubkey,
/// The lamports in the account. Modifiable by programs.
pub lamports: Rc<RefCell<&'a mut u64>>,
/// The data held in this account. Modifiable by programs.
pub data: Rc<RefCell<&'a mut [u8]>>,
/// Program that owns this account
pub **owner**: &'a Pubkey,
/// The epoch at which this account will next owe rent
pub rent_epoch: Epoch,
/// Was the transaction signed by this account's public key?
pub is_signer: bool,
/// Is the account writable?
pub is_writable: bool,
/// This account's data contains a loaded program (and is now read-only)
pub executable: bool,
}
  • Please tell the difference between the following two implementation (one uses the trait while the other not)
pub trait JlpHolderMath {
fn flush(&mut self);
}

impl JlpHolderMath for JlpHolder {
fn flush(&mut self) { }
}
impl JlpHolder {
fn flush(&mut self) { }
}