Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading