Skip to content

Commit f59ffa1

Browse files
authored
fix: (de)compression transfer ix token pool check (#1032)
* fix: (de)compression transfer ix token pool check * fix comments
1 parent b9fd19d commit f59ffa1

File tree

4 files changed

+55
-17
lines changed

4 files changed

+55
-17
lines changed

programs/compressed-token/src/instructions/transfer.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use light_system_program::{
66
sdk::accounts::{InvokeAccounts, SignerAccounts},
77
};
88

9-
use crate::POOL_SEED;
109
#[derive(Accounts)]
1110
pub struct TransferInstruction<'info> {
1211
/// UNCHECKED: only pays fees.
@@ -34,7 +33,7 @@ pub struct TransferInstruction<'info> {
3433
/// (different program) checked in light system program to derive
3534
/// cpi_authority_pda and check that this program is the signer of the cpi.
3635
pub self_program: Program<'info, crate::program::LightCompressedToken>,
37-
#[account(mut, seeds = [POOL_SEED, &token_pool_pda.mint.key().to_bytes()],bump)]
36+
#[account(mut)]
3837
pub token_pool_pda: Option<Account<'info, TokenAccount>>,
3938
#[account(mut, constraint= if token_pool_pda.is_some() {Ok(token_pool_pda.as_ref().unwrap().key() != compress_or_decompress_token_account.key())}else {err!(crate::ErrorCode::TokenPoolPdaUndefined)}? @crate::ErrorCode::IsTokenPoolPda)]
4039
pub compress_or_decompress_token_account: Option<Account<'info, TokenAccount>>,

programs/compressed-token/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,5 @@ pub enum ErrorCode {
183183
TokenPoolPdaUndefined,
184184
#[msg("Compress or decompress recipient is the same account as the token pool pda.")]
185185
IsTokenPoolPda,
186+
InvalidTokenPoolPda,
186187
}

programs/compressed-token/src/spl_compression.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use anchor_spl::token::Transfer;
33

44
use crate::{
55
process_transfer::get_cpi_signer_seeds, CompressedTokenInstructionDataTransfer,
6-
TransferInstruction,
6+
TransferInstruction, POOL_SEED,
77
};
88

99
pub fn process_compression_or_decompression<'info>(
@@ -17,6 +17,20 @@ pub fn process_compression_or_decompression<'info>(
1717
}
1818
}
1919

20+
pub fn spl_token_pool_derivation(
21+
mint: &Pubkey,
22+
program_id: &Pubkey,
23+
token_pool_pubkey: &Pubkey,
24+
) -> Result<()> {
25+
let seeds = &[POOL_SEED, &mint.to_bytes()[..]];
26+
let (pda, _bump_seed) = Pubkey::find_program_address(seeds, program_id);
27+
if pda == *token_pool_pubkey {
28+
Ok(())
29+
} else {
30+
err!(crate::ErrorCode::InvalidTokenPoolPda)
31+
}
32+
}
33+
2034
pub fn decompress_spl_tokens<'info>(
2135
inputs: &CompressedTokenInstructionDataTransfer,
2236
ctx: &Context<'_, '_, '_, 'info, TransferInstruction<'info>>,
@@ -29,6 +43,8 @@ pub fn decompress_spl_tokens<'info>(
2943
Some(token_pool_pda) => token_pool_pda.to_account_info(),
3044
None => return err!(crate::ErrorCode::CompressedPdaUndefinedForDecompress),
3145
};
46+
spl_token_pool_derivation(&inputs.mint, &crate::ID, &token_pool_pda.key())?;
47+
3248
let amount = match inputs.compress_or_decompress_amount {
3349
Some(amount) => amount,
3450
None => return err!(crate::ErrorCode::DeCompressAmountUndefinedForDecompress),
@@ -50,10 +66,11 @@ pub fn compress_spl_tokens<'info>(
5066
inputs: &CompressedTokenInstructionDataTransfer,
5167
ctx: &Context<'_, '_, '_, 'info, TransferInstruction<'info>>,
5268
) -> Result<()> {
53-
let recipient = match ctx.accounts.token_pool_pda.as_ref() {
69+
let recipient_token_pool = match ctx.accounts.token_pool_pda.as_ref() {
5470
Some(token_pool_pda) => token_pool_pda.to_account_info(),
5571
None => return err!(crate::ErrorCode::CompressedPdaUndefinedForCompress),
5672
};
73+
spl_token_pool_derivation(&inputs.mint, &crate::ID, &recipient_token_pool.key())?;
5774
let amount = match inputs.compress_or_decompress_amount {
5875
Some(amount) => amount,
5976
None => return err!(crate::ErrorCode::DeCompressAmountUndefinedForCompress),
@@ -65,7 +82,7 @@ pub fn compress_spl_tokens<'info>(
6582
.as_ref()
6683
.unwrap()
6784
.to_account_info(),
68-
&recipient,
85+
&recipient_token_pool,
6986
&ctx.accounts.authority.to_account_info(),
7087
&ctx.accounts
7188
.token_program

test-programs/compressed-token-test/tests/test.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2655,7 +2655,7 @@ async fn test_failing_decompression() {
26552655
&mut context,
26562656
&mut test_indexer,
26572657
input_compressed_account.clone(),
2658-
decompress_amount, // need to be consistent with compression amount
2658+
decompress_amount, // needs to be consistent with compression amount
26592659
&merkle_tree_pubkey,
26602660
decompress_amount,
26612661
false,
@@ -2667,7 +2667,7 @@ async fn test_failing_decompression() {
26672667
.await
26682668
.unwrap_err();
26692669
}
2670-
// Test 2: invalid token pool pda
2670+
// Test 2: invalid token pool pda (compress and decompress)
26712671
{
26722672
let invalid_token_account_keypair = Keypair::new();
26732673
create_token_account(&mut context, &mint, &invalid_token_account_keypair, &payer)
@@ -2678,14 +2678,35 @@ async fn test_failing_decompression() {
26782678
&mut context,
26792679
&mut test_indexer,
26802680
input_compressed_account.clone(),
2681-
decompress_amount, // need to be consistent with compression amount
2681+
decompress_amount, // needs to be consistent with compression amount
26822682
&merkle_tree_pubkey,
2683-
decompress_amount - 1,
2683+
decompress_amount,
26842684
false,
26852685
&token_account_keypair.pubkey(),
26862686
Some(invalid_token_account_keypair.pubkey()),
26872687
&mint,
2688-
anchor_lang::error::ErrorCode::ConstraintSeeds.into(),
2688+
ErrorCode::InvalidTokenPoolPda.into(),
2689+
)
2690+
.await
2691+
.unwrap();
2692+
2693+
let invalid_token_account_keypair = Keypair::new();
2694+
create_token_account(&mut context, &mint, &invalid_token_account_keypair, &payer)
2695+
.await
2696+
.unwrap();
2697+
failing_compress_decompress(
2698+
&sender,
2699+
&mut context,
2700+
&mut test_indexer,
2701+
input_compressed_account.clone(),
2702+
0, // needs to be consistent with compression amount
2703+
&merkle_tree_pubkey,
2704+
0,
2705+
true,
2706+
&token_account_keypair.pubkey(),
2707+
Some(invalid_token_account_keypair.pubkey()),
2708+
&mint,
2709+
ErrorCode::InvalidTokenPoolPda.into(),
26892710
)
26902711
.await
26912712
.unwrap();
@@ -2697,7 +2718,7 @@ async fn test_failing_decompression() {
26972718
&mut context,
26982719
&mut test_indexer,
26992720
input_compressed_account.clone(),
2700-
decompress_amount, // need to be consistent with compression amount
2721+
decompress_amount, // needs to be consistent with compression amount
27012722
&merkle_tree_pubkey,
27022723
decompress_amount - 1,
27032724
false,
@@ -2716,7 +2737,7 @@ async fn test_failing_decompression() {
27162737
&mut context,
27172738
&mut test_indexer,
27182739
input_compressed_account.clone(),
2719-
decompress_amount, // need to be consistent with compression amount
2740+
decompress_amount, // needs to be consistent with compression amount
27202741
&merkle_tree_pubkey,
27212742
decompress_amount + 1,
27222743
false,
@@ -2735,7 +2756,7 @@ async fn test_failing_decompression() {
27352756
&mut context,
27362757
&mut test_indexer,
27372758
input_compressed_account.clone(),
2738-
decompress_amount, // need to be consistent with compression amount
2759+
decompress_amount, // needs to be consistent with compression amount
27392760
&merkle_tree_pubkey,
27402761
0,
27412762
false,
@@ -2754,7 +2775,7 @@ async fn test_failing_decompression() {
27542775
&mut context,
27552776
&mut test_indexer,
27562777
input_compressed_account.clone(),
2757-
decompress_amount, // need to be consistent with compression amount
2778+
decompress_amount, // needs to be consistent with compression amount
27582779
&merkle_tree_pubkey,
27592780
decompress_amount,
27602781
false,
@@ -2787,7 +2808,7 @@ async fn test_failing_decompression() {
27872808
&mut context,
27882809
&mut test_indexer,
27892810
Vec::new(),
2790-
compress_amount, // need to be consistent with compression amount
2811+
compress_amount, // needs to be consistent with compression amount
27912812
&merkle_tree_pubkey,
27922813
compress_amount - 1,
27932814
true,
@@ -2806,7 +2827,7 @@ async fn test_failing_decompression() {
28062827
&mut context,
28072828
&mut test_indexer,
28082829
Vec::new(),
2809-
compress_amount, // need to be consistent with compression amount
2830+
compress_amount, // needs to be consistent with compression amount
28102831
&merkle_tree_pubkey,
28112832
compress_amount + 1,
28122833
true,
@@ -2825,7 +2846,7 @@ async fn test_failing_decompression() {
28252846
&mut context,
28262847
&mut test_indexer,
28272848
Vec::new(),
2828-
compress_amount, // need to be consistent with compression amount
2849+
compress_amount, // needs to be consistent with compression amount
28292850
&merkle_tree_pubkey,
28302851
0,
28312852
true,

0 commit comments

Comments
 (0)