Inside invoke and invoke_signed , RefCell checking is performed first to ensure that the account RefCells are consistent with the request:
The RefCell checking can be compute unit expensive due to nested loops.
To avoid that expense, dapps may choose to use invoke_unchecked and invoke_signed_unchecked, the unchecked version of invoke and invoke_signed respectively, which do not check RefCells. However, use invoke_unchecked and invoke_signed_uncheckedat your own risk: only when you are certain that the accounts used in instruction are consistent with those in the account_infos.
The Solana Native Loader and BPF loaders
In Solana, every account including Solana programs has an owner. When a Solana program is invoked in a cross program invocation, its owner is used to process the instruction (invoke or invoke_signed). For Solana programs, their owners are either the native loader or a BPF loader.
The native loader (NativeLoader1111111111111111111111111111111) is a special program that is the owner of most native Solana programs (those program_ids ended with 111111111111111111111111111).
When a native Solana program is invoked in a cross program invocation, the native loader is used to load the native program into the Solana runtime and process the instruction.
The native loader is also the owner of three BPF loaders:
BPFLoaderUpgradeab1e (the upgradeable Solana BPF loader. The upgradeable BPF loader is responsible for deploying, upgrading, and executing BPF programs.)
BPFLoader2 (The latest Solana BPF loader. The BPF loader is responsible for loading, finalizing, and executing BPF programs.)
BPFLoader (The original and nowdeprecated Solana BPF loader)
Most Solana smart contracts use Upgradeable BPF Loader to deploy the program, so their owner is BPFLoaderUpgradeab1e and they can be upgraded (by an upgrade authority set at the program deployment time).
Some Solana programs are immutable, as they are loaded by BPFLoader2 or BPFLoader.
For example, the SPL Token spl_token and the Associated Token spl_associated_token_accountprogramsare loaded by BPFLoader2, and they are immutable.
The System Program is probably the most frequently invoked program, often called with the following two instructions:
The System Program provides several important functionalities:
create new accounts
allocate account data
assign accounts to owning programs
transfer lamports from System Program owned accounts
pay transaction fees.
The System Program is the owner of all wallet accounts.
Note: only the owner of an account has write access to the account. If an account is not owned by a program, the program is only permitted to read its data and credit the account (but not debit the account).
The System Program is also the default owner of an account when the account is created by create_account. It is then allowed to transfer lamports and importantly assign account ownership, i.e., changing owner to a different program id.
The SPL Token Program provides functions for creating and managing tokens (including both fungible and non-fungible tokens, i.e. NFTs).
spl_token is commonly used to create new tokens, mint, burn, and distribute to users. The following instructions are frequently used in Solana smart contracts:
Create a token account: spl_token::instruction::initialize_account
Create a token mint: spl_token::instruction::initialize_mint
Mint new tokens to an account: spl_token::instruction::mint_to
Transfers tokens from one account to another: spl_token::instruction::transfer
Burns tokens by removing them from an account: spl_token::instruction::burn
Approves a delegate: spl_token::instruction::approve
The Associated Token Program allows a user to create a main token account for each token they own. Internally, it maps the user’s wallet address to a unique associated token account for each token mint.
Specifically, to create an associated token account for the given wallet address and token mint: create_associated_token_account
The Stake Program is used to create and manage accounts representing stake and rewards for validators or their delegators.
The following instructions are often used:
Initialize a stake with lockup and authorization information: stake::instruction::initialize
Authorize a key to manage stake or withdrawal: stake::instruction::authorize
Withdraw unstaked lamports from the stake account: stake::instruction::withdraw
Set stake lockup: stake::instruction::set_lockup
Deactivates the stake in the account: stake::instruction::deactivate_stake
Merge two stake accounts: stake::instruction::merge
Split stake off a stake account into another stake account: stake::instruction::split
Delegate a stake to a particular vote account: stake::instruction::delegate_stake
The Vote Program is used to create and manage accounts that track validator voting state and rewards.
The Config Program is used to add configuration data to the chain including the list of public keys that are permitted to modify the data.
vote and config are primarily used by Solana validators, so we omit details here.
By default, signatures are verified in parallel using all available CPU cores. When perf-libs are available signature verification is offloaded to the GPU.
Multiple signatures can be verified. If any of the signatures fail to verify, an error is returned.
The Secp256k1 Recover Program is used to recover Secp256k1 public key from a signed message (ecrecover). It is added to support Ethereum / Solana bridge.
Secp256k1 is the name of the elliptic curve used by popular blockchains (e.g., Bitcoin, Ethereum) to implement public key cryptography. All points on this curve are valid public keys.
Both Ed25519 and Secp256k1 programs are precompiled in Solana to maximize performance.
From a security perspective
It should be noted that although these native programs are generally trustworthy and (mostly) stable, to ensure security it is important to understand their assumptions and use instructions in their expected way.
We use a security case of the SPL Token program to illustrate this point.
Before spl-token v3.1.1 (released on 2021–05–18), there was a vulnerability in the token instruction code that allows invoking an arbitrary program (instead of the real spl-token program). The fixes are in this commit.
The fixes add check_program_account in all the token instruction functions to ensure the user-provided “token_program_id” is the same as the spl-token program_id (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA).
The check_program_account function is shown below:
The root cause of this vulnerability lies in an inconsistent assumption between the expected usages of the spl-token program and its potential usages.
Therefore, to avoid such vulnerabilities (thus attacks) in general, it is important to
check the expected usages of these native programs
add necessary user checks, and
always use the bug-fixed versions (e.g., spl-token v3.1.1 and above).
Soteria is founded by leading minds in the fields of blockchain security and software verification.