Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 0181955

Browse files
committed
address pull request comments
1 parent a89d6cc commit 0181955

File tree

7 files changed

+268
-93
lines changed

7 files changed

+268
-93
lines changed

stake-pool/program/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ pub enum StakePoolError {
132132
/// Too much SOL withdrawn from the stake pool's reserve account
133133
#[error("SolWithdrawalTooLarge")]
134134
SolWithdrawalTooLarge,
135+
/// Provided metadata account does not match metadata account derived for pool mint
136+
#[error("InvalidMetadataAccount")]
137+
InvalidMetadataAccount,
135138
}
136139
impl From<StakePoolError> for ProgramError {
137140
fn from(e: StakePoolError) -> Self {

stake-pool/program/src/instruction.rs

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
33
#![allow(clippy::too_many_arguments)]
44

5-
use crate::AUTHORITY_WITHDRAW;
6-
use mpl_token_metadata::state::PREFIX;
7-
use solana_program::info;
8-
use std::str::FromStr;
95
use {
106
crate::{
117
find_deposit_authority_program_address, find_stake_program_address,
@@ -14,6 +10,7 @@ use {
1410
MAX_VALIDATORS_TO_UPDATE,
1511
},
1612
borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
13+
mpl_token_metadata::pda::find_metadata_account,
1714
solana_program::{
1815
instruction::{AccountMeta, Instruction},
1916
pubkey::Pubkey,
@@ -383,10 +380,10 @@ pub enum StakePoolInstruction {
383380
/// Create token metadata for the stake-pool token in the
384381
/// metaplex-token program
385382
/// 0. `[]` Stake pool
386-
/// 1. `[]` Manager
383+
/// 1. `[s]` Manager
387384
/// 2. `[]` Stake pool withdraw authority
388385
/// 3. `[]` Pool token mint account
389-
/// 4. `[]` Payer for creation of token metadata account
386+
/// 4. `[s, w]` Payer for creation of token metadata account
390387
/// 5. `[w]` Token metadata account
391388
/// 6. `[]` Metadata program id
392389
/// 7. `[]` System program id
@@ -406,7 +403,7 @@ pub enum StakePoolInstruction {
406403
/// metaplex-token program
407404
///
408405
/// 0. `[]` Stake pool
409-
/// 1. `[]` Manager
406+
/// 1. `[s]` Manager
410407
/// 2. `[]` Stake pool withdraw authority
411408
/// 3. `[w]` Token metadata account
412409
/// 4. `[]` Metadata program id
@@ -1336,23 +1333,15 @@ pub fn update_token_metadata(
13361333
uri: String,
13371334
) -> Instruction {
13381335
let (stake_pool_withdraw_authority, _) =
1339-
Pubkey::find_program_address(&[&stake_pool.to_bytes(), AUTHORITY_WITHDRAW], &program_id);
1340-
1341-
let mpl_token_metadata_program_id = mpl_token_metadata::id();
1342-
let metadata_seeds = &[
1343-
PREFIX.as_bytes(),
1344-
mpl_token_metadata_program_id.as_ref(),
1345-
pool_mint.as_ref(),
1346-
];
1347-
let (token_metadata, _) =
1348-
Pubkey::find_program_address(metadata_seeds, &mpl_token_metadata_program_id);
1336+
find_withdraw_authority_program_address(program_id, stake_pool);
1337+
let (token_metadata, _) = find_metadata_account(pool_mint);
13491338

13501339
let accounts = vec![
13511340
AccountMeta::new_readonly(*stake_pool, false),
13521341
AccountMeta::new_readonly(*manager, true),
13531342
AccountMeta::new_readonly(stake_pool_withdraw_authority, false),
13541343
AccountMeta::new(token_metadata, false),
1355-
AccountMeta::new_readonly(mpl_token_metadata_program_id, false),
1344+
AccountMeta::new_readonly(mpl_token_metadata::id(), false),
13561345
];
13571346

13581347
Instruction {
@@ -1377,25 +1366,17 @@ pub fn create_token_metadata(
13771366
uri: String,
13781367
) -> Instruction {
13791368
let (stake_pool_withdraw_authority, _) =
1380-
Pubkey::find_program_address(&[&stake_pool.to_bytes(), AUTHORITY_WITHDRAW], &program_id);
1381-
1382-
let mpl_token_metadata_program_id = mpl_token_metadata::id();
1383-
let metadata_seeds = &[
1384-
PREFIX.as_bytes(),
1385-
mpl_token_metadata_program_id.as_ref(),
1386-
pool_mint.as_ref(),
1387-
];
1388-
let (token_metadata, _) =
1389-
Pubkey::find_program_address(metadata_seeds, &mpl_token_metadata_program_id);
1369+
find_withdraw_authority_program_address(program_id, stake_pool);
1370+
let (token_metadata, _) = find_metadata_account(pool_mint);
13901371

13911372
let accounts = vec![
13921373
AccountMeta::new_readonly(*stake_pool, false),
13931374
AccountMeta::new_readonly(*manager, true),
13941375
AccountMeta::new_readonly(stake_pool_withdraw_authority, false),
13951376
AccountMeta::new_readonly(*pool_mint, false),
1396-
AccountMeta::new_readonly(*payer, false),
1377+
AccountMeta::new(*payer, true),
13971378
AccountMeta::new(token_metadata, false),
1398-
AccountMeta::new_readonly(mpl_token_metadata_program_id, false),
1379+
AccountMeta::new_readonly(mpl_token_metadata::id(), false),
13991380
AccountMeta::new_readonly(system_program::id(), false),
14001381
AccountMeta::new_readonly(sysvar::rent::id(), false),
14011382
];

stake-pool/program/src/processor.rs

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
//! Program state processor
22
3-
use mpl_token_metadata::instruction::{create_metadata_accounts_v3, update_metadata_accounts_v2};
4-
use mpl_token_metadata::state::DataV2;
5-
63
use {
74
crate::{
85
error::StakePoolError,
@@ -16,6 +13,11 @@ use {
1613
AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED_PREFIX,
1714
},
1815
borsh::{BorshDeserialize, BorshSerialize},
16+
mpl_token_metadata::{
17+
instruction::{create_metadata_accounts_v3, update_metadata_accounts_v2},
18+
pda::find_metadata_account,
19+
state::DataV2,
20+
},
1921
num_traits::FromPrimitive,
2022
solana_program::{
2123
account_info::{next_account_info, AccountInfo},
@@ -92,6 +94,19 @@ fn check_transient_stake_address(
9294
}
9395
}
9496

97+
/// Check mpl metadata account address for the pool mint
98+
fn check_mpl_metadata_account_address(
99+
metadata_address: &Pubkey,
100+
pool_mint: &Pubkey,
101+
) -> Result<(), ProgramError> {
102+
let (metadata_account_pubkey, _) = find_metadata_account(pool_mint);
103+
if metadata_account_pubkey != *metadata_address {
104+
Err(StakePoolError::InvalidMetadataAccount.into())
105+
} else {
106+
Ok(())
107+
}
108+
}
109+
95110
/// Check system program address
96111
fn check_system_program(program_id: &Pubkey) -> Result<(), ProgramError> {
97112
if *program_id != system_program::id() {
@@ -120,6 +135,34 @@ fn check_stake_program(program_id: &Pubkey) -> Result<(), ProgramError> {
120135
}
121136
}
122137

138+
/// Check mpl metadata program
139+
fn check_mpl_metadata_program(program_id: &Pubkey) -> Result<(), ProgramError> {
140+
if *program_id != mpl_token_metadata::id() {
141+
msg!(
142+
"Expected mpl metadata program {}, received {}",
143+
mpl_token_metadata::id(),
144+
program_id
145+
);
146+
Err(ProgramError::IncorrectProgramId)
147+
} else {
148+
Ok(())
149+
}
150+
}
151+
152+
/// Check rent sysvar correctness
153+
fn check_rent_sysvar(sysvar_key: &Pubkey) -> Result<(), ProgramError> {
154+
if *sysvar_key != solana_program::sysvar::rent::id() {
155+
msg!(
156+
"Expected rent sysvar {}, received {}",
157+
solana_program::sysvar::rent::id(),
158+
sysvar_key
159+
);
160+
Err(ProgramError::InvalidArgument)
161+
} else {
162+
Ok(())
163+
}
164+
}
165+
123166
/// Check account owner is the given program
124167
fn check_account_owner(
125168
account_info: &AccountInfo,
@@ -2698,8 +2741,13 @@ impl Processor {
26982741
let system_program_info = next_account_info(account_info_iter)?;
26992742
let rent_sysvar_info = next_account_info(account_info_iter)?;
27002743

2744+
check_system_program(system_program_info.key)?;
2745+
check_rent_sysvar(rent_sysvar_info.key)?;
2746+
check_account_owner(payer_info, &system_program::id())?;
27012747
check_account_owner(stake_pool_info, program_id)?;
2702-
let mut stake_pool = try_from_slice_unchecked::<StakePool>(&stake_pool_info.data.borrow())?;
2748+
check_mpl_metadata_program(mpl_token_metadata_program_info.key)?;
2749+
2750+
let stake_pool = try_from_slice_unchecked::<StakePool>(&stake_pool_info.data.borrow())?;
27032751
if !stake_pool.is_valid() {
27042752
return Err(StakePoolError::InvalidState.into());
27052753
}
@@ -2711,21 +2759,18 @@ impl Processor {
27112759
stake_pool_info.key,
27122760
)?;
27132761
stake_pool.check_mint(pool_mint_info)?;
2762+
check_mpl_metadata_account_address(metadata_info.key, &stake_pool.pool_mint)?;
27142763

27152764
// Token mint authority for stake-pool token is stake-pool withdraw authority
27162765
let token_mint_authority = withdraw_authority_info;
2717-
let mint_key = pool_mint_info.key.clone();
2718-
let token_mint_authority_key = token_mint_authority.key.clone();
2719-
2720-
let metadata_program_id = mpl_token_metadata_program_info.key.clone();
27212766

27222767
let new_metadata_instruction = create_metadata_accounts_v3(
2723-
metadata_program_id,
2724-
metadata_info.key.clone(),
2725-
mint_key,
2726-
token_mint_authority_key,
2727-
payer_info.key.clone(),
2728-
token_mint_authority_key,
2768+
*mpl_token_metadata_program_info.key,
2769+
*metadata_info.key,
2770+
*pool_mint_info.key,
2771+
*token_mint_authority.key,
2772+
*payer_info.key,
2773+
*token_mint_authority.key,
27292774
name,
27302775
symbol,
27312776
uri,
@@ -2782,7 +2827,10 @@ impl Processor {
27822827
let mpl_token_metadata_program_info = next_account_info(account_info_iter)?;
27832828

27842829
check_account_owner(stake_pool_info, program_id)?;
2785-
let mut stake_pool = try_from_slice_unchecked::<StakePool>(&stake_pool_info.data.borrow())?;
2830+
2831+
check_mpl_metadata_program(mpl_token_metadata_program_info.key)?;
2832+
2833+
let stake_pool = try_from_slice_unchecked::<StakePool>(&stake_pool_info.data.borrow())?;
27862834
if !stake_pool.is_valid() {
27872835
return Err(StakePoolError::InvalidState.into());
27882836
}
@@ -2793,17 +2841,15 @@ impl Processor {
27932841
program_id,
27942842
stake_pool_info.key,
27952843
)?;
2844+
check_mpl_metadata_account_address(metadata_info.key, &stake_pool.pool_mint)?;
27962845

27972846
// Token mint authority for stake-pool token is withdraw authority only
27982847
let token_mint_authority = withdraw_authority_info;
2799-
let token_mint_authority_key = token_mint_authority.key.clone();
2800-
2801-
let metadata_program_id = mpl_token_metadata_program_info.key.clone();
28022848

28032849
let update_metadata_accounts_instruction = update_metadata_accounts_v2(
2804-
metadata_program_id,
2805-
metadata_info.key.clone(),
2806-
token_mint_authority_key,
2850+
*mpl_token_metadata_program_info.key,
2851+
*metadata_info.key,
2852+
*token_mint_authority.key,
28072853
None,
28082854
Some(DataV2 {
28092855
name,
@@ -3081,11 +3127,11 @@ impl Processor {
30813127
Self::process_withdraw_sol(program_id, accounts, pool_tokens)
30823128
}
30833129
StakePoolInstruction::CreateTokenMetadata { name, symbol, uri } => {
3084-
msg!("Instruction: Create token metadata");
3130+
msg!("Instruction: CreateTokenMetadata");
30853131
Self::process_create_pool_token_metadata(program_id, accounts, name, symbol, uri)
30863132
}
30873133
StakePoolInstruction::UpdateTokenMetadata { name, symbol, uri } => {
3088-
msg!("Instruction: Create token metadata");
3134+
msg!("Instruction: UpdateTokenMetadata");
30893135
Self::process_update_pool_token_metadata(program_id, accounts, name, symbol, uri)
30903136
}
30913137
}
@@ -3136,6 +3182,7 @@ impl PrintProgramError for StakePoolError {
31363182
StakePoolError::TransientAccountInUse => msg!("Error: Provided validator stake account already has a transient stake account in use"),
31373183
StakePoolError::InvalidSolWithdrawAuthority => msg!("Error: Provided sol withdraw authority does not match the program's"),
31383184
StakePoolError::SolWithdrawalTooLarge => msg!("Error: Too much SOL withdrawn from the stake pool's reserve account"),
3185+
StakePoolError::InvalidMetadataAccount => msg!("Error: Metadata account derived from pool mint account does not match the one passed to program")
31393186
}
31403187
}
31413188
}

0 commit comments

Comments
 (0)