Full Report
Lamports are the smallest denomination of SOL on Solana. Sending SOL to an account can cause major havoc to an executing program in certain situations. They have a game called the king of SOL as a demonstration. At a high level, whoever has donated the most SOL wins, and it reimburses 95% of the funds to the original king. However, several DoS bugs are lurking in this codebase. In Solana, an account (place where data is stored) has a minimum balance of lamports to be alive. Storage has a cost. So, this is used to combat account DoS attacks. Rent exemption is itself an attack vector though. Consider the case where a transfer is going from one account to another. If the account goes below rent-exemption then the transaction will always fail. Accounts in Solana have a few properties - readable, writable, and executable. An account that is executable is unable to receive SOL via set_lamports. So, forcing a transfer to happen this way will also lead to a DoS. Some programs are silently downgrades from writable to read-only. This happens for reserved system programs/accounts. In Anchor, specifying an account to have the writable requirement is common. By combining both of these, we can create situations where a transfer of lamports will always fail. Overall, this is an interesting article on transferring imports and the security consequences associated with it. I didn't know all of these!
Analysis Summary
# Vulnerability: Denial of Service via Malicious Lamport Transfer Targets
## CVE Details
- **CVE ID**: N/A (Logic/Runtime design flaw specific to Solana Program Library/SVM)
- **CVSS Score**: 7.5 (High) - Estimated: High Availability impact on smart contracts.
- **CWE**: CWE-755: Improper Handling of Exceptional Conditions; CWE-400: Uncontrolled Resource Consumption (DoS).
## Affected Systems
- **Products**: Solana Smart Contracts (Programs) written in Rust/Anchor.
- **Versions**: All versions utilizing direct `transfer` or `set_lamports` to user-provided accounts.
- **Configurations**: Contracts that require successful lamport transfers to arbitrary accounts to complete state transitions (e.g., auctions, games, or payment distributions).
## Vulnerability Description
The vulnerability arises from three primary Solana runtime behaviors that allow an attacker to provide a "poisoned" account as a transfer recipient, causing the entire transaction to revert:
1. **Rent-Exemption Trap**: If a transfer results in an account balance falling between 0 and the rent-exemption threshold, the runtime rejects the transaction. Attackers can provide accounts that would end up in this "no-man's land" to block logic.
2. **Executable Account Restriction**: Accounts marked with the `executable` flag (holding program code) are treated as immutable by the runtime. Any instruction attempting to credit lamports to an executable account via `set_lamports` or similar transfer logic will fail.
3. **Write-Demotion (Reserved Accounts)**: Certain system-reserved accounts (e.g., the `Secp256r1` program) are "silently demoted" from writable to read-only by the runtime, regardless of the transaction's instructions. If a program attempts a transfer to such an account assuming it is writable (as required by Anchor’s `AccountInfo`), the transaction reverts.
## Exploitation
- **Status**: PoC available (demonstrated via "King of the SOL" game logic).
- **Complexity**: Low.
- **Attack Vector**: Network (Smart Contract Interaction).
## Impact
- **Confidentiality**: None.
- **Integrity**: Low (Prevents legitimate state updates).
- **Availability**: High (Can permanently "brick" a contract’s primary function, such as preventing a new king from being crowned or a pot from being claimed).
## Remediation
### Patches
- There is no global patch; this is a fundamental design aspect of the Solana Virtual Machine (SVM). Developers must implement defensive coding patterns.
### Workarounds
- **Pull-over-Push Pattern**: Instead of pushing funds to a user, store funds in a Program Derived Address (PDA) vault and allow users to "withdraw" their own funds in a separate transaction.
- **Validation Checks**: Ensure the recipient account is not `executable` and is not a known `ReservedAccount`.
- **Rent Checks**: Calculate and verify that the post-transfer balance meets the `Rent::get()?.minimum_balance(data_len)` requirement.
## Detection
- **Indicators of Compromised Logic**: Transactions consistently reverting with `InstructionError::ReadOnlyUpdate` or `InstructionError::ExecutableDataModified` when interacting with specific user-provided accounts.
- **Detection Methods**: Static analysis tools (like Anchor's safety checks) or manual code audits focusing on `transfer` calls to `AccountInfo` without sufficient validation.
## References
- [Solana Runtime Rent Logic - Agave Repository](https://github.com/anza-xyz/agave/blob/7a1e57469a5b1aeed617457c0519803620ba953f/svm-rent-collector/src/svm_rent_collector.rs)
- [Original Article: Solana: The hidden dangers of lamport transfers](https://osec.io/blog/2025-05-14-king-of-the-sol/)
- [Jito Bug Bounty Report Reference](https://x.com/nick0ve)