Solana has a few built-in (native on-chain) programs (e.g., system_program, spl_token, stake, vote, ed25519, etc) that provide essential instructions and are generally trusted.
In this article, we introduce the internals of these programs, and highlight some of the intricacies.
Every Solana program (including both native and user-deployed smart contracts) has a unique program_id, which corresponds to the program’s pubkey.
Following is a list of native Solana programs with their corresponding program_ids
In addition, spl_token and spl_associated_token_account are official Solana programs that are also frequently used, so we consider them as well:
When a program invokes another program, the callee’s program_id will be supplied to the call, typically through one of the following two functions:
Note: internally, invoke calls invoke_signed without signer_seeds.
The program_id is the first parameter of instruction, as defined below:
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_unchecked at your own risk: only when you are certain that the accounts used in instruction are consistent with those in the account_infos.
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:
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_account programs are 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:
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:
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:
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.
The Ed25519 Signature Verify Program takes an ed25519 signature, public key, and message, and is used to verify if the message is signed by the (corresponding secret) private key.
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.
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
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