Skip to content

Commit 37adc6b

Browse files
authored
Add address tree validation checks to all programs (#23)
Validate that address tree pubkeys match allowed constants before creating compressed accounts or deriving addresses: - V1 programs check against ADDRESS_TREE_V1 - V2 programs check against ADDRESS_TREE_V2 This prevents use of unauthorized address trees in instructions.
1 parent c29554d commit 37adc6b

17 files changed

Lines changed: 212 additions & 63 deletions

File tree

account-comparison/programs/account-comparison/src/lib.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use anchor_lang::prelude::*;
44
use light_sdk::{
55
account::LightAccount,
66
address::v1::derive_address,
7+
constants::ADDRESS_TREE_V1,
78
cpi::{v1::CpiAccounts, CpiSigner},
89
derive_light_cpi_signer,
910
instruction::{account_meta::CompressedAccountMeta, PackedAddressTreeInfo, ValidityProof},
@@ -58,11 +59,18 @@ pub mod account_comparison {
5859
CPI_SIGNER,
5960
);
6061

62+
let address_tree_pubkey = address_tree_info
63+
.get_tree_pubkey(&light_cpi_accounts)
64+
.map_err(|err| ProgramError::from(LightSdkError::from(err)))?;
65+
66+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
67+
msg!("Invalid address tree");
68+
return Err(ProgramError::InvalidAccountData.into());
69+
}
70+
6171
let (address, address_seed) = derive_address(
6272
&[b"account", ctx.accounts.user.key().as_ref()],
63-
&address_tree_info
64-
.get_tree_pubkey(&light_cpi_accounts)
65-
.map_err(|err| ProgramError::from(LightSdkError::from(err)))?,
73+
&address_tree_pubkey,
6674
&crate::ID,
6775
);
6876

basic-operations/anchor/burn/programs/burn/src/lib.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anchor_lang::{prelude::*, AnchorDeserialize, AnchorSerialize};
55
use light_sdk::{
66
account::LightAccount,
77
address::v1::derive_address,
8+
constants::ADDRESS_TREE_V1,
89
cpi::{v1::CpiAccounts, CpiSigner},
910
derive_light_cpi_signer,
1011
instruction::{account_meta::CompressedAccountMetaBurn, PackedAddressTreeInfo, ValidityProof},
@@ -38,11 +39,18 @@ pub mod burn {
3839
crate::LIGHT_CPI_SIGNER,
3940
);
4041

42+
let address_tree_pubkey = address_tree_info
43+
.get_tree_pubkey(&light_cpi_accounts)
44+
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?;
45+
46+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
47+
msg!("Invalid address tree");
48+
return Err(ProgramError::InvalidAccountData.into());
49+
}
50+
4151
let (address, address_seed) = derive_address(
4252
&[b"message", ctx.accounts.signer.key().as_ref()],
43-
&address_tree_info
44-
.get_tree_pubkey(&light_cpi_accounts)
45-
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?,
53+
&address_tree_pubkey,
4654
&crate::ID,
4755
);
4856

basic-operations/anchor/close/programs/close/src/lib.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anchor_lang::{prelude::*, AnchorDeserialize, AnchorSerialize};
55
use light_sdk::{
66
account::LightAccount,
77
address::v1::derive_address,
8+
constants::ADDRESS_TREE_V1,
89
cpi::{v1::CpiAccounts, CpiSigner},
910
derive_light_cpi_signer,
1011
instruction::{account_meta::CompressedAccountMeta, PackedAddressTreeInfo, ValidityProof},
@@ -38,11 +39,18 @@ pub mod close {
3839
crate::LIGHT_CPI_SIGNER,
3940
);
4041

42+
let address_tree_pubkey = address_tree_info
43+
.get_tree_pubkey(&light_cpi_accounts)
44+
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?;
45+
46+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
47+
msg!("Invalid address tree");
48+
return Err(ProgramError::InvalidAccountData.into());
49+
}
50+
4151
let (address, address_seed) = derive_address(
4252
&[b"message", ctx.accounts.signer.key().as_ref()],
43-
&address_tree_info
44-
.get_tree_pubkey(&light_cpi_accounts)
45-
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?,
53+
&address_tree_pubkey,
4654
&crate::ID,
4755
);
4856

basic-operations/anchor/create/programs/create/src/lib.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anchor_lang::{prelude::*, AnchorDeserialize, AnchorSerialize};
55
use light_sdk::{
66
account::LightAccount,
77
address::v1::derive_address,
8+
constants::ADDRESS_TREE_V1,
89
cpi::{v1::CpiAccounts, CpiSigner},
910
derive_light_cpi_signer,
1011
instruction::{PackedAddressTreeInfo, ValidityProof},
@@ -38,11 +39,18 @@ pub mod create {
3839
crate::LIGHT_CPI_SIGNER,
3940
);
4041

42+
let address_tree_pubkey = address_tree_info
43+
.get_tree_pubkey(&light_cpi_accounts)
44+
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?;
45+
46+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
47+
msg!("Invalid address tree");
48+
return Err(ProgramError::InvalidAccountData.into());
49+
}
50+
4151
let (address, address_seed) = derive_address(
4252
&[b"message", ctx.accounts.signer.key().as_ref()],
43-
&address_tree_info
44-
.get_tree_pubkey(&light_cpi_accounts)
45-
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?,
53+
&address_tree_pubkey,
4654
&crate::ID,
4755
);
4856

basic-operations/anchor/reinit/programs/reinit/src/lib.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anchor_lang::{prelude::*, AnchorDeserialize, AnchorSerialize};
55
use light_sdk::{
66
account::LightAccount,
77
address::v1::derive_address,
8+
constants::ADDRESS_TREE_V1,
89
cpi::{v1::CpiAccounts, CpiSigner},
910
derive_light_cpi_signer,
1011
instruction::{account_meta::CompressedAccountMeta, PackedAddressTreeInfo, ValidityProof},
@@ -38,11 +39,18 @@ pub mod reinit {
3839
crate::LIGHT_CPI_SIGNER,
3940
);
4041

42+
let address_tree_pubkey = address_tree_info
43+
.get_tree_pubkey(&light_cpi_accounts)
44+
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?;
45+
46+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
47+
msg!("Invalid address tree");
48+
return Err(ProgramError::InvalidAccountData.into());
49+
}
50+
4151
let (address, address_seed) = derive_address(
4252
&[b"message", ctx.accounts.signer.key().as_ref()],
43-
&address_tree_info
44-
.get_tree_pubkey(&light_cpi_accounts)
45-
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?,
53+
&address_tree_pubkey,
4654
&crate::ID,
4755
);
4856

basic-operations/anchor/update/programs/update/src/lib.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anchor_lang::{prelude::*, AnchorDeserialize, AnchorSerialize};
55
use light_sdk::{
66
account::LightAccount,
77
address::v1::derive_address,
8+
constants::ADDRESS_TREE_V1,
89
cpi::{v1::CpiAccounts, CpiSigner},
910
derive_light_cpi_signer,
1011
instruction::{account_meta::CompressedAccountMeta, PackedAddressTreeInfo, ValidityProof},
@@ -38,11 +39,18 @@ pub mod update {
3839
crate::LIGHT_CPI_SIGNER,
3940
);
4041

42+
let address_tree_pubkey = address_tree_info
43+
.get_tree_pubkey(&light_cpi_accounts)
44+
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?;
45+
46+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
47+
msg!("Invalid address tree");
48+
return Err(ProgramError::InvalidAccountData.into());
49+
}
50+
4151
let (address, address_seed) = derive_address(
4252
&[b"message", ctx.accounts.signer.key().as_ref()],
43-
&address_tree_info
44-
.get_tree_pubkey(&light_cpi_accounts)
45-
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?,
53+
&address_tree_pubkey,
4654
&crate::ID,
4755
);
4856

basic-operations/native/programs/burn/src/lib.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use light_macros::pubkey;
88
use light_sdk::{
99
account::sha::LightAccount,
1010
address::v1::derive_address,
11+
constants::ADDRESS_TREE_V1,
1112
cpi::{
1213
v1::{CpiAccounts, LightSystemProgramCpi},
1314
CpiSigner, InvokeLightSystemProgram, LightCpiInstruction,
@@ -81,12 +82,19 @@ fn create(accounts: &[AccountInfo], instruction_data: &[u8]) -> Result<(), Light
8182

8283
let light_cpi_accounts = CpiAccounts::new(signer, &accounts[1..], LIGHT_CPI_SIGNER);
8384

85+
let address_tree_pubkey = instruction_data
86+
.address_tree_info
87+
.get_tree_pubkey(&light_cpi_accounts)
88+
.map_err(|_| ProgramError::NotEnoughAccountKeys)?;
89+
90+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
91+
solana_program::msg!("Invalid address tree");
92+
return Err(LightSdkError::ProgramError(ProgramError::InvalidAccountData));
93+
}
94+
8495
let (address, address_seed) = derive_address(
8596
&[b"message", signer.key.as_ref()],
86-
&instruction_data
87-
.address_tree_info
88-
.get_tree_pubkey(&light_cpi_accounts)
89-
.map_err(|_| ProgramError::NotEnoughAccountKeys)?,
97+
&address_tree_pubkey,
9098
&ID,
9199
);
92100

basic-operations/native/programs/close/src/lib.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use light_macros::pubkey;
88
use light_sdk::{
99
account::sha::LightAccount,
1010
address::v1::derive_address,
11+
constants::ADDRESS_TREE_V1,
1112
cpi::{
1213
v1::{CpiAccounts, LightSystemProgramCpi},
1314
CpiSigner, InvokeLightSystemProgram, LightCpiInstruction,
@@ -81,12 +82,19 @@ fn create(accounts: &[AccountInfo], instruction_data: &[u8]) -> Result<(), Light
8182

8283
let light_cpi_accounts = CpiAccounts::new(signer, &accounts[1..], LIGHT_CPI_SIGNER);
8384

85+
let address_tree_pubkey = instruction_data
86+
.address_tree_info
87+
.get_tree_pubkey(&light_cpi_accounts)
88+
.map_err(|_| ProgramError::NotEnoughAccountKeys)?;
89+
90+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
91+
solana_program::msg!("Invalid address tree");
92+
return Err(LightSdkError::ProgramError(ProgramError::InvalidAccountData));
93+
}
94+
8495
let (address, address_seed) = derive_address(
8596
&[b"message", signer.key.as_ref()],
86-
&instruction_data
87-
.address_tree_info
88-
.get_tree_pubkey(&light_cpi_accounts)
89-
.map_err(|_| ProgramError::NotEnoughAccountKeys)?,
97+
&address_tree_pubkey,
9098
&ID,
9199
);
92100

basic-operations/native/programs/create/src/lib.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use light_macros::pubkey;
88
use light_sdk::{
99
account::sha::LightAccount,
1010
address::v1::derive_address,
11+
constants::ADDRESS_TREE_V1,
1112
cpi::{
1213
v1::{CpiAccounts, LightSystemProgramCpi},
1314
CpiSigner, InvokeLightSystemProgram, LightCpiInstruction,
@@ -93,12 +94,19 @@ pub fn create(
9394

9495
let light_cpi_accounts = CpiAccounts::new(signer, &accounts[1..], LIGHT_CPI_SIGNER);
9596

97+
let address_tree_pubkey = instruction_data
98+
.address_tree_info
99+
.get_tree_pubkey(&light_cpi_accounts)
100+
.map_err(|_| ProgramError::NotEnoughAccountKeys)?;
101+
102+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
103+
solana_program::msg!("Invalid address tree");
104+
return Err(ProgramError::InvalidAccountData);
105+
}
106+
96107
let (address, address_seed) = derive_address(
97108
&[b"message", signer.key.as_ref()],
98-
&instruction_data
99-
.address_tree_info
100-
.get_tree_pubkey(&light_cpi_accounts)
101-
.map_err(|_| ProgramError::NotEnoughAccountKeys)?,
109+
&address_tree_pubkey,
102110
&ID,
103111
);
104112

basic-operations/native/programs/reinit/src/lib.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use light_macros::pubkey;
88
use light_sdk::{
99
account::sha::LightAccount,
1010
address::v1::derive_address,
11+
constants::ADDRESS_TREE_V1,
1112
cpi::{
1213
v1::{CpiAccounts, LightSystemProgramCpi},
1314
CpiSigner, InvokeLightSystemProgram, LightCpiInstruction,
@@ -89,12 +90,19 @@ fn create(accounts: &[AccountInfo], instruction_data: &[u8]) -> Result<(), Light
8990

9091
let light_cpi_accounts = CpiAccounts::new(signer, &accounts[1..], LIGHT_CPI_SIGNER);
9192

93+
let address_tree_pubkey = instruction_data
94+
.address_tree_info
95+
.get_tree_pubkey(&light_cpi_accounts)
96+
.map_err(|_| ProgramError::NotEnoughAccountKeys)?;
97+
98+
if address_tree_pubkey.to_bytes() != ADDRESS_TREE_V1 {
99+
solana_program::msg!("Invalid address tree");
100+
return Err(LightSdkError::ProgramError(ProgramError::InvalidAccountData));
101+
}
102+
92103
let (address, address_seed) = derive_address(
93104
&[b"message", signer.key.as_ref()],
94-
&instruction_data
95-
.address_tree_info
96-
.get_tree_pubkey(&light_cpi_accounts)
97-
.map_err(|_| ProgramError::NotEnoughAccountKeys)?,
105+
&address_tree_pubkey,
98106
&ID,
99107
);
100108

0 commit comments

Comments
 (0)