From f40e04873520917f00a12248632023bc849e5172 Mon Sep 17 00:00:00 2001 From: ananas-block Date: Fri, 6 Feb 2026 08:08:57 +0100 Subject: [PATCH 1/3] fix: verify mint and owner in idempotent ATA early return Audit issue #4 (LOW): The idempotent ATA path returned Ok() when the account was already owned by the program without verifying the stored mint and owner matched the requested values. Add Token deserialization and field checks before the early return. --- .../program/src/ctoken/create_ata.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/programs/compressed-token/program/src/ctoken/create_ata.rs b/programs/compressed-token/program/src/ctoken/create_ata.rs index a1608aa8cf..c088467d29 100644 --- a/programs/compressed-token/program/src/ctoken/create_ata.rs +++ b/programs/compressed-token/program/src/ctoken/create_ata.rs @@ -67,6 +67,19 @@ fn process_create_associated_token_account_with_mode( if IDEMPOTENT { validate_ata_derivation(associated_token_account, owner_bytes, mint_bytes, bump)?; if associated_token_account.is_owned_by(&crate::LIGHT_CPI_SIGNER.program_id) { + // Verify stored mint and owner match the requested values + let ctoken = + light_token_interface::state::Token::from_account_info_checked( + associated_token_account, + )?; + if ctoken.mint.to_bytes() != *mint_bytes { + msg!("Idempotent ATA: mint mismatch"); + return Err(anchor_compressed_token::ErrorCode::MintMismatch.into()); + } + if ctoken.owner.to_bytes() != *owner_bytes { + msg!("Idempotent ATA: owner mismatch"); + return Err(anchor_compressed_token::ErrorCode::OwnerMismatch.into()); + } return Ok(()); } } From 331d3a9effbbb2d3067749f8e6b2dc488df13162 Mon Sep 17 00:00:00 2001 From: ananas-block Date: Fri, 6 Feb 2026 08:36:14 +0100 Subject: [PATCH 2/3] chore: format --- programs/compressed-token/program/src/ctoken/create_ata.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/programs/compressed-token/program/src/ctoken/create_ata.rs b/programs/compressed-token/program/src/ctoken/create_ata.rs index c088467d29..97fc5d389a 100644 --- a/programs/compressed-token/program/src/ctoken/create_ata.rs +++ b/programs/compressed-token/program/src/ctoken/create_ata.rs @@ -68,10 +68,9 @@ fn process_create_associated_token_account_with_mode( validate_ata_derivation(associated_token_account, owner_bytes, mint_bytes, bump)?; if associated_token_account.is_owned_by(&crate::LIGHT_CPI_SIGNER.program_id) { // Verify stored mint and owner match the requested values - let ctoken = - light_token_interface::state::Token::from_account_info_checked( - associated_token_account, - )?; + let ctoken = light_token_interface::state::Token::from_account_info_checked( + associated_token_account, + )?; if ctoken.mint.to_bytes() != *mint_bytes { msg!("Idempotent ATA: mint mismatch"); return Err(anchor_compressed_token::ErrorCode::MintMismatch.into()); From cf8c62b10c617804550c7912b9947f5920e73254 Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 9 Feb 2026 05:52:56 +0100 Subject: [PATCH 3/3] fix: use pubkey_eq for idempotent ATA mint/owner checks --- programs/compressed-token/program/src/ctoken/create_ata.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/compressed-token/program/src/ctoken/create_ata.rs b/programs/compressed-token/program/src/ctoken/create_ata.rs index 97fc5d389a..4bb4618fb1 100644 --- a/programs/compressed-token/program/src/ctoken/create_ata.rs +++ b/programs/compressed-token/program/src/ctoken/create_ata.rs @@ -3,7 +3,7 @@ use borsh::BorshDeserialize; use light_account_checks::AccountIterator; use light_program_profiler::profile; use light_token_interface::instructions::create_associated_token_account::CreateAssociatedTokenAccountInstructionData; -use pinocchio::{account_info::AccountInfo, instruction::Seed}; +use pinocchio::{account_info::AccountInfo, instruction::Seed, pubkey::pubkey_eq}; use spl_pod::solana_msg::msg; use crate::{ @@ -71,11 +71,11 @@ fn process_create_associated_token_account_with_mode( let ctoken = light_token_interface::state::Token::from_account_info_checked( associated_token_account, )?; - if ctoken.mint.to_bytes() != *mint_bytes { + if !pubkey_eq(ctoken.mint.array_ref(), mint_bytes) { msg!("Idempotent ATA: mint mismatch"); return Err(anchor_compressed_token::ErrorCode::MintMismatch.into()); } - if ctoken.owner.to_bytes() != *owner_bytes { + if !pubkey_eq(ctoken.owner.array_ref(), owner_bytes) { msg!("Idempotent ATA: owner mismatch"); return Err(anchor_compressed_token::ErrorCode::OwnerMismatch.into()); }