Skip to content

Commit 47c1e4c

Browse files
committed
Add unpack helpers
1 parent 129f93c commit 47c1e4c

File tree

10 files changed

+50
-95
lines changed

10 files changed

+50
-95
lines changed

p-token/src/processor/amount_to_ui_amount.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use {
2-
super::{check_account_owner, MAX_FORMATTED_DIGITS, U64_BYTES},
2+
super::{check_account_owner, unpack_amount, MAX_FORMATTED_DIGITS},
33
core::str::from_utf8_unchecked,
44
pinocchio::{
55
account_info::AccountInfo, program::set_return_data, program_error::ProgramError,
@@ -16,12 +16,7 @@ pub fn process_amount_to_ui_amount(
1616
accounts: &[AccountInfo],
1717
instruction_data: &[u8],
1818
) -> ProgramResult {
19-
let amount = if instruction_data.len() >= U64_BYTES {
20-
// SAFETY: The minimum size of the instruction data is `U64_BYTES` bytes.
21-
unsafe { u64::from_le_bytes(*(instruction_data.as_ptr() as *const [u8; U64_BYTES])) }
22-
} else {
23-
return Err(TokenError::InvalidInstruction.into());
24-
};
19+
let amount = unpack_amount(instruction_data)?;
2520

2621
let mint_info = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?;
2722
check_account_owner(mint_info)?;

p-token/src/processor/approve.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_approve(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
9-
let amount = if instruction_data.len() >= U64_BYTES {
10-
// SAFETY: The minimum size of the instruction data is `U64_BYTES` bytes.
11-
unsafe { u64::from_le_bytes(*(instruction_data.as_ptr() as *const [u8; U64_BYTES])) }
12-
} else {
13-
return Err(TokenError::InvalidInstruction.into());
14-
};
8+
let amount = unpack_amount(instruction_data)?;
159

1610
shared::approve::process_approve(accounts, amount, None)
1711
}
Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount_and_decimals},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_approve_checked(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
9-
// expected u64 (8) + u8 (1)
10-
let (amount, decimals) = if instruction_data.len() >= 9 {
11-
let (amount, decimals) = instruction_data.split_at(U64_BYTES);
12-
(
13-
// SAFETY: The size of `amount` is `U64_BYTES` bytes.
14-
unsafe { u64::from_le_bytes(*(amount.as_ptr() as *const [u8; U64_BYTES])) },
15-
decimals.first().copied(),
16-
)
17-
} else {
18-
return Err(TokenError::InvalidInstruction.into());
19-
};
8+
let (amount, decimals) = unpack_amount_and_decimals(instruction_data)?;
209

21-
shared::approve::process_approve(accounts, amount, decimals)
10+
shared::approve::process_approve(accounts, amount, Some(decimals))
2211
}

p-token/src/processor/burn.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_burn(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
9-
let amount = if instruction_data.len() >= U64_BYTES {
10-
// SAFETY: The minimum size of the instruction data is `U64_BYTES` bytes.
11-
unsafe { u64::from_le_bytes(*(instruction_data.as_ptr() as *const [u8; U64_BYTES])) }
12-
} else {
13-
return Err(TokenError::InvalidInstruction.into());
14-
};
8+
let amount = unpack_amount(instruction_data)?;
159

1610
shared::burn::process_burn(accounts, amount, None)
1711
}

p-token/src/processor/burn_checked.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount_and_decimals},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_burn_checked(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
9-
// expected u64 (8) + u8 (1)
10-
let (amount, decimals) = if instruction_data.len() >= 9 {
11-
let (amount, decimals) = instruction_data.split_at(U64_BYTES);
12-
(
13-
// SAFETY: The size of `amount` is `U64_BYTES` bytes.
14-
unsafe { u64::from_le_bytes(*(amount.as_ptr() as *const [u8; U64_BYTES])) },
15-
decimals.first().copied(),
16-
)
17-
} else {
18-
return Err(TokenError::InvalidInstruction.into());
19-
};
8+
let (amount, decimals) = unpack_amount_and_decimals(instruction_data)?;
209

21-
shared::burn::process_burn(accounts, amount, decimals)
10+
shared::burn::process_burn(accounts, amount, Some(decimals))
2211
}

p-token/src/processor/mint_to.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_mint_to(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
9-
let amount = if instruction_data.len() >= U64_BYTES {
10-
// SAFETY: The minimum size of the instruction data is `U64_BYTES` bytes.
11-
unsafe { u64::from_le_bytes(*(instruction_data.as_ptr() as *const [u8; U64_BYTES])) }
12-
} else {
13-
return Err(TokenError::InvalidInstruction.into());
14-
};
8+
let amount = unpack_amount(instruction_data)?;
159

1610
shared::mint_to::process_mint_to(accounts, amount, None)
1711
}
Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount_and_decimals},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_mint_to_checked(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
9-
// expected u64 (8) + u8 (1)
10-
let (amount, decimals) = if instruction_data.len() >= 9 {
11-
let (amount, decimals) = instruction_data.split_at(U64_BYTES);
12-
(
13-
// SAFETY: The size of `amount` is `U64_BYTES` bytes.
14-
unsafe { u64::from_le_bytes(*(amount.as_ptr() as *const [u8; U64_BYTES])) },
15-
decimals.first().copied(),
16-
)
17-
} else {
18-
return Err(TokenError::InvalidInstruction.into());
19-
};
8+
let (amount, decimals) = unpack_amount_and_decimals(instruction_data)?;
209

21-
shared::mint_to::process_mint_to(accounts, amount, decimals)
10+
shared::mint_to::process_mint_to(accounts, amount, Some(decimals))
2211
}

p-token/src/processor/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,31 @@ fn try_ui_amount_into_amount(ui_amount: &str, decimals: u8) -> Result<u64, Progr
183183
.map_err(|_| ProgramError::InvalidArgument)
184184
}
185185
}
186+
187+
/// Unpacks a `u64` amount from the instruction data.
188+
#[inline(always)]
189+
const fn unpack_amount(instruction_data: &[u8]) -> Result<u64, TokenError> {
190+
// expected u64 (8)
191+
if instruction_data.len() >= U64_BYTES {
192+
// SAFETY: The minimum size of the instruction data is `U64_BYTES` bytes.
193+
Ok(unsafe { u64::from_le_bytes(*(instruction_data.as_ptr() as *const [u8; U64_BYTES])) })
194+
} else {
195+
Err(TokenError::InvalidInstruction)
196+
}
197+
}
198+
199+
/// Unpacks a `u64` amount and an optional `u8` from the instruction data.
200+
#[inline(always)]
201+
const fn unpack_amount_and_decimals(instruction_data: &[u8]) -> Result<(u64, u8), TokenError> {
202+
// expected u64 (8) + u8 (1)
203+
if instruction_data.len() >= 9 {
204+
let (amount, decimals) = instruction_data.split_at(U64_BYTES);
205+
Ok((
206+
// SAFETY: The size of `amount` is `U64_BYTES` bytes.
207+
unsafe { u64::from_le_bytes(*(amount.as_ptr() as *const [u8; U64_BYTES])) },
208+
decimals[0],
209+
))
210+
} else {
211+
Err(TokenError::InvalidInstruction)
212+
}
213+
}

p-token/src/processor/transfer.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_transfer(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
9-
let amount = if instruction_data.len() >= U64_BYTES {
10-
// SAFETY: The minimum size of the instruction data is `U64_BYTES` bytes.
11-
unsafe { u64::from_le_bytes(*(instruction_data.as_ptr() as *const [u8; U64_BYTES])) }
12-
} else {
13-
return Err(TokenError::InvalidInstruction.into());
14-
};
8+
let amount = unpack_amount(instruction_data)?;
159

1610
shared::transfer::process_transfer(accounts, amount, None)
1711
}
Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
11
use {
2-
super::{shared, U64_BYTES},
2+
super::{shared, unpack_amount_and_decimals},
33
pinocchio::{account_info::AccountInfo, ProgramResult},
4-
spl_token_interface::error::TokenError,
54
};
65

76
#[inline(always)]
87
pub fn process_transfer_checked(
98
accounts: &[AccountInfo],
109
instruction_data: &[u8],
1110
) -> ProgramResult {
12-
// expected u64 (8) + u8 (1)
13-
let (amount, decimals) = if instruction_data.len() >= 9 {
14-
let (amount, decimals) = instruction_data.split_at(U64_BYTES);
15-
(
16-
// SAFETY: The size of `amount` is `U64_BYTES` bytes.
17-
unsafe { u64::from_le_bytes(*(amount.as_ptr() as *const [u8; U64_BYTES])) },
18-
decimals.first().copied(),
19-
)
20-
} else {
21-
return Err(TokenError::InvalidInstruction.into());
22-
};
11+
let (amount, decimals) = unpack_amount_and_decimals(instruction_data)?;
2312

24-
shared::transfer::process_transfer(accounts, amount, decimals)
13+
shared::transfer::process_transfer(accounts, amount, Some(decimals))
2514
}

0 commit comments

Comments
 (0)