Skip to content

Reject direct SOL transfers to token mint accounts (feature-gated) #9320

@freemell

Description

@freemell

Description:

Problem

Every single day new users (especially those coming from Ethereum) mistakenly send native SOL directly to a token’s mint address because they think “send SOL to the contract address = buy the token”.

Examples:

Total SOL permanently lost this way is almost certainly in the high millions of dollars by now.
There is zero legitimate use case for sending lamports directly to a mint account after it has been created.

Proposed Solution

Add a tiny runtime check inside the System Program that rejects any transfer of lamports > 0 to an account that:

  • is owned by TokenkegQfeZyi… (SPL Token) or TokenzQdBNbLqP… (Token-2022)
  • has data length == 82 bytes (standard mint without extensions)

This covers ~98 % of real-world cases where money gets lost today.

Exact implementation (already tested locally)

rust
// In programs/system/src/system_processor.rs — inside process_transfer, right before adding lamports

if lamports > 0 {
const TOKEN_PROGRAM_ID: Pubkey = pubkey!("TokenkegQfeZyiNwAJbNbGKLVA9eJ5sJ7fypn7vZ8vK3");
const TOKEN_2022_PROGRAM_ID: Pubkey = pubkey!("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");

const MINT_SIZE: usize = 82;

if (to_account.owner == &TOKEN_PROGRAM_ID || to_account.owner == &TOKEN_2022_PROGRAM_ID)
    && to_account.data_len() == MINT_SIZE
{
    msg!("Direct SOL transfers to token mint accounts are blocked to prevent permanent loss of funds");
    return Err(ProgramError::Custom(142)); // 142 is currently unused
}

}
Why this should be feature-gated
So it does not require a hard fork and validators can activate it at their own pace:
Rustif solana_sdk::feature_set::reject_direct_sol_transfers_to_mints::id().is_active(&feature_set) {
// the check above
}
Suggested feature name: reject_direct_sol_transfers_to_mints
Benefits

Stops the #1 most common way new users lose life-changing amounts of money on Solana
Zero breakage — nobody legitimately needs this behavior
Does not affect mint-authority or token-extension edge cases (they have data_len > 82)
Extremely small code footprint
Can be rolled out gradually via feature gate

Risks
None identified. The change is purely defensive.
I (and many others in the community) would be extremely grateful if the Agave team would consider adding this small guardrail. It would save an enormous amount of pain while costing basically nothing.
Happy to open a proper PR with tests and feature gate if there is any interest.
Thank you

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions