Skip to content

Commit

Permalink
program: Create InstructionVariant for checked-ness (#170)
Browse files Browse the repository at this point in the history
#### Problem

In #160, the three different transfer instruction implementations were
made more clearly different through an enum instead of various options,
but the other checked / unchecked instructions are still not clear.

#### Summary of changes

Add `InstructionVariant` enum and use it for mint / burn / approve.
  • Loading branch information
joncinque authored Feb 6, 2025
1 parent 4b68db4 commit 7feaf94
Showing 1 changed file with 48 additions and 21 deletions.
69 changes: 48 additions & 21 deletions program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ pub(crate) enum TransferInstruction {
CheckedWithFee { decimals: u8, fee: u64 },
}

pub(crate) enum InstructionVariant {
Unchecked,
Checked { decimals: u8 },
}

/// Program state handler.
pub struct Processor {}
impl Processor {
Expand Down Expand Up @@ -567,21 +572,22 @@ impl Processor {
}

/// Processes an [`Approve`](enum.TokenInstruction.html) instruction.
pub fn process_approve(
pub(crate) fn process_approve(
program_id: &Pubkey,
accounts: &[AccountInfo],
amount: u64,
expected_decimals: Option<u8>,
instruction_variant: InstructionVariant,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();

let source_account_info = next_account_info(account_info_iter)?;

let expected_mint_info = if let Some(expected_decimals) = expected_decimals {
Some((next_account_info(account_info_iter)?, expected_decimals))
} else {
None
};
let expected_mint_info =
if let InstructionVariant::Checked { decimals } = instruction_variant {
Some((next_account_info(account_info_iter)?, decimals))
} else {
None
};
let delegate_info = next_account_info(account_info_iter)?;
let owner_info = next_account_info(account_info_iter)?;
let owner_info_data_len = owner_info.data_len();
Expand Down Expand Up @@ -965,11 +971,11 @@ impl Processor {
}

/// Processes a [`MintTo`](enum.TokenInstruction.html) instruction.
pub fn process_mint_to(
pub(crate) fn process_mint_to(
program_id: &Pubkey,
accounts: &[AccountInfo],
amount: u64,
expected_decimals: Option<u8>,
instruction_variant: InstructionVariant,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let mint_info = next_account_info(account_info_iter)?;
Expand Down Expand Up @@ -1014,8 +1020,8 @@ impl Processor {
return Err(TokenError::IllegalMintBurnConversion.into());
}

if let Some(expected_decimals) = expected_decimals {
if expected_decimals != mint.base.decimals {
if let InstructionVariant::Checked { decimals } = instruction_variant {
if decimals != mint.base.decimals {
return Err(TokenError::MintDecimalsMismatch.into());
}
}
Expand Down Expand Up @@ -1054,11 +1060,11 @@ impl Processor {
}

/// Processes a [`Burn`](enum.TokenInstruction.html) instruction.
pub fn process_burn(
pub(crate) fn process_burn(
program_id: &Pubkey,
accounts: &[AccountInfo],
amount: u64,
expected_decimals: Option<u8>,
instruction_variant: InstructionVariant,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();

Expand Down Expand Up @@ -1086,8 +1092,8 @@ impl Processor {
return Err(TokenError::MintMismatch.into());
}

if let Some(expected_decimals) = expected_decimals {
if expected_decimals != mint.base.decimals {
if let InstructionVariant::Checked { decimals } = instruction_variant {
if decimals != mint.base.decimals {
return Err(TokenError::MintDecimalsMismatch.into());
}
}
Expand Down Expand Up @@ -1681,7 +1687,12 @@ impl Processor {
PodTokenInstruction::Approve => {
msg!("Instruction: Approve");
let data = decode_instruction_data::<AmountData>(input)?;
Self::process_approve(program_id, accounts, data.amount.into(), None)
Self::process_approve(
program_id,
accounts,
data.amount.into(),
InstructionVariant::Unchecked,
)
}
PodTokenInstruction::Revoke => {
msg!("Instruction: Revoke");
Expand All @@ -1701,12 +1712,22 @@ impl Processor {
PodTokenInstruction::MintTo => {
msg!("Instruction: MintTo");
let data = decode_instruction_data::<AmountData>(input)?;
Self::process_mint_to(program_id, accounts, data.amount.into(), None)
Self::process_mint_to(
program_id,
accounts,
data.amount.into(),
InstructionVariant::Unchecked,
)
}
PodTokenInstruction::Burn => {
msg!("Instruction: Burn");
let data = decode_instruction_data::<AmountData>(input)?;
Self::process_burn(program_id, accounts, data.amount.into(), None)
Self::process_burn(
program_id,
accounts,
data.amount.into(),
InstructionVariant::Unchecked,
)
}
PodTokenInstruction::CloseAccount => {
msg!("Instruction: CloseAccount");
Expand Down Expand Up @@ -1739,7 +1760,9 @@ impl Processor {
program_id,
accounts,
data.amount.into(),
Some(data.decimals),
InstructionVariant::Checked {
decimals: data.decimals,
},
)
}
PodTokenInstruction::MintToChecked => {
Expand All @@ -1749,7 +1772,9 @@ impl Processor {
program_id,
accounts,
data.amount.into(),
Some(data.decimals),
InstructionVariant::Checked {
decimals: data.decimals,
},
)
}
PodTokenInstruction::BurnChecked => {
Expand All @@ -1759,7 +1784,9 @@ impl Processor {
program_id,
accounts,
data.amount.into(),
Some(data.decimals),
InstructionVariant::Checked {
decimals: data.decimals,
},
)
}
PodTokenInstruction::SyncNative => {
Expand Down

0 comments on commit 7feaf94

Please sign in to comment.