From 174c12a2c473862754479b35250811242f0aaec7 Mon Sep 17 00:00:00 2001 From: ananas Date: Wed, 11 Feb 2026 19:52:23 +0000 Subject: [PATCH] refactor: check system program account ownership at resize, check account state is zeroed pre initialization --- .../program/src/shared/create_pda_account.rs | 6 ++++++ .../program/src/shared/initialize_ctoken_account.rs | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/programs/compressed-token/program/src/shared/create_pda_account.rs b/programs/compressed-token/program/src/shared/create_pda_account.rs index f7eeb6ab12..592a0b9e1b 100644 --- a/programs/compressed-token/program/src/shared/create_pda_account.rs +++ b/programs/compressed-token/program/src/shared/create_pda_account.rs @@ -43,6 +43,12 @@ pub fn create_pda_account( // Cold Path: if account already has lamports (e.g., from attacker donation), // use Assign + realloc + Transfer instead of CreateAccount which would fail. if new_account.lamports() > 0 { + // Verify account is owned by system program (uninitialized). + // Prevents overwriting an already-initialized account. + if !new_account.is_owned_by(&[0u8; 32]) { + return Err(ProgramError::AccountAlreadyInitialized); + } + let current_lamports = new_account.lamports(); Assign { diff --git a/programs/compressed-token/program/src/shared/initialize_ctoken_account.rs b/programs/compressed-token/program/src/shared/initialize_ctoken_account.rs index da6afdaa2c..1a19e89a76 100644 --- a/programs/compressed-token/program/src/shared/initialize_ctoken_account.rs +++ b/programs/compressed-token/program/src/shared/initialize_ctoken_account.rs @@ -213,14 +213,13 @@ pub fn initialize_ctoken_account( // Access the token account data as mutable bytes let mut token_account_data = AccountInfoTrait::try_borrow_mut_data(token_account_info)?; - // Zero all base token bytes before initialization to prevent pre-set values - // (e.g., amount field via IDL buffer) from persisting through new_zero_copy, - // which only sets mint, owner, and state without zeroing other fields. - if token_account_data.len() < 165 { - msg!("Token account data too small: {}", token_account_data.len()); - return Err(ProgramError::InvalidAccountData); + // Verify account data is zeroed. System-program-owned accounts from transfers + // have 0-length data, and resize zeros new bytes. Non-zero data indicates + // an unexpected state that should not be silently overwritten. + if token_account_data.iter().any(|&b| b != 0) { + msg!("Token account data is not zeroed"); + return Err(ProgramError::AccountAlreadyInitialized); } - token_account_data[..165].fill(0); // Use new_zero_copy to initialize the token account // This sets mint, owner, state, account_type, and extensions