Skip to content

Commit 52931da

Browse files
committed
new PermissionedBurn instruction
1 parent f9133d3 commit 52931da

File tree

3 files changed

+64
-14
lines changed

3 files changed

+64
-14
lines changed

interface/src/extension/permissioned_burn/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
33
use {
44
crate::extension::{Extension, ExtensionType},
55
bytemuck::{Pod, Zeroable},
6-
spl_pod::optional_keys::OptionalNonZeroPubkey
6+
spl_pod::optional_keys::OptionalNonZeroPubkey,
77
};
88

99
/// Instruction types for the permissioned burn extension

program/src/pod_instruction.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ pub(crate) enum PodTokenInstruction {
115115
ConfidentialMintBurnExtension,
116116
ScaledUiAmountExtension,
117117
PausableExtension,
118+
// 45
118119
PermissionedBurnExtension,
120+
PermissionedBurn,
119121
}
120122

121123
fn unpack_pubkey_option(input: &[u8]) -> Result<PodCOption<Pubkey>, ProgramError> {

program/src/processor.rs

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,57 @@ impl Processor {
10861086
accounts: &[AccountInfo],
10871087
amount: u64,
10881088
instruction_variant: InstructionVariant,
1089+
) -> ProgramResult {
1090+
Self::do_process_burn(program_id, accounts, amount, instruction_variant)
1091+
}
1092+
1093+
/// Processes a [`PermissionedBurn`](enum.TokenInstruction.html) instruction.
1094+
pub(crate) fn process_permissioned_burn(
1095+
program_id: &Pubkey,
1096+
accounts: &[AccountInfo],
1097+
amount: u64,
1098+
instruction_variant: InstructionVariant,
1099+
) -> ProgramResult {
1100+
let account_info_iter = &mut accounts.iter();
1101+
1102+
let source_account_info = next_account_info(account_info_iter)?;
1103+
let mint_info = next_account_info(account_info_iter)?;
1104+
let authority_info = next_account_info(account_info_iter)?;
1105+
let authority_info_data_len = authority_info.data_len();
1106+
1107+
let mut mint_data = mint_info.data.borrow_mut();
1108+
let mint = PodStateWithExtensionsMut::<PodMint>::unpack(&mut mint_data)?;
1109+
1110+
if let Ok(ext) = mint.get_extension::<PermissionedBurnConfig>() {
1111+
// Pull the required extra signer from the accounts
1112+
let approver_ai = next_account_info(account_info_iter)?;
1113+
1114+
if !approver_ai.is_signer {
1115+
return Err(ProgramError::MissingRequiredSignature);
1116+
}
1117+
1118+
let maybe_burn_authority: Option<Pubkey> = ext.authority.into();
1119+
if Some(*approver_ai.key) != maybe_burn_authority {
1120+
return Err(ProgramError::InvalidAccountData);
1121+
}
1122+
}
1123+
1124+
let remaining_after = account_info_iter.as_slice();
1125+
let mut forward = vec![
1126+
source_account_info.clone(),
1127+
mint_info.clone(),
1128+
authority_info.clone(),
1129+
];
1130+
forward.extend_from_slice(remaining_after);
1131+
1132+
Self::do_process_burn(program_id, &forward, amount, instruction_variant)
1133+
}
1134+
1135+
fn do_process_burn(
1136+
program_id: &Pubkey,
1137+
accounts: &[AccountInfo],
1138+
amount: u64,
1139+
instruction_variant: InstructionVariant,
10891140
) -> ProgramResult {
10901141
let account_info_iter = &mut accounts.iter();
10911142

@@ -1123,19 +1174,6 @@ impl Processor {
11231174
return Err(TokenError::MintPaused.into());
11241175
}
11251176
}
1126-
if let Ok(ext) = mint.get_extension::<PermissionedBurnConfig>() {
1127-
// Pull the required extra signer from the accounts
1128-
let approver_ai = next_account_info(account_info_iter)?;
1129-
1130-
if !approver_ai.is_signer {
1131-
return Err(ProgramError::MissingRequiredSignature);
1132-
}
1133-
1134-
let maybe_burn_authority: Option<Pubkey> = ext.authority.into();
1135-
if Some(*approver_ai.key) != maybe_burn_authority {
1136-
return Err(ProgramError::InvalidAccountData);
1137-
}
1138-
}
11391177

11401178
let maybe_permanent_delegate = get_permanent_delegate(&mint);
11411179

@@ -1775,6 +1813,16 @@ impl Processor {
17751813
InstructionVariant::Unchecked,
17761814
)
17771815
}
1816+
PodTokenInstruction::PermissionedBurn => {
1817+
msg!("Instruction: PermissionedBurn");
1818+
let data = decode_instruction_data::<AmountData>(input)?;
1819+
Self::process_burn(
1820+
program_id,
1821+
accounts,
1822+
data.amount.into(),
1823+
InstructionVariant::Unchecked,
1824+
)
1825+
}
17781826
PodTokenInstruction::CloseAccount => {
17791827
msg!("Instruction: CloseAccount");
17801828
Self::process_close_account(program_id, accounts)

0 commit comments

Comments
 (0)