Skip to content

Commit 640f93e

Browse files
committed
[wip]: More fixes
1 parent 32a3f7f commit 640f93e

File tree

4 files changed

+21
-51
lines changed

4 files changed

+21
-51
lines changed

interface/src/instruction.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
33
use pinocchio::program_error::ProgramError;
44

5-
use crate::error::TokenError;
6-
75
/// Instructions supported by the token program.
86
#[repr(u8)]
97
#[derive(Clone, Debug, PartialEq)]
@@ -510,21 +508,15 @@ pub enum AuthorityType {
510508
CloseAccount,
511509
}
512510

513-
impl AuthorityType {
514-
pub fn into(&self) -> u8 {
515-
match self {
516-
AuthorityType::MintTokens => 0,
517-
AuthorityType::FreezeAccount => 1,
518-
AuthorityType::AccountOwner => 2,
519-
AuthorityType::CloseAccount => 3,
520-
}
521-
}
511+
impl TryFrom<u8> for AuthorityType {
512+
type Error = ProgramError;
522513

523514
#[inline(always)]
524-
pub fn from(value: u8) -> Result<Self, ProgramError> {
515+
fn try_from(value: u8) -> Result<Self, Self::Error> {
525516
match value {
517+
// SAFETY: `value` is guaranteed to be in the range of the enum variants.
526518
0..=3 => Ok(unsafe { core::mem::transmute::<u8, AuthorityType>(value) }),
527-
_ => Err(TokenError::InvalidInstruction.into()),
519+
_ => Err(ProgramError::InvalidInstructionData),
528520
}
529521
}
530522
}

p-token/src/processor/mod.rs

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
use core::{
2-
mem::MaybeUninit,
3-
slice::{from_raw_parts, from_raw_parts_mut},
4-
str::from_utf8_unchecked,
5-
};
1+
use core::{slice::from_raw_parts, str::from_utf8_unchecked};
62
use pinocchio::{
7-
account_info::AccountInfo, memory::sol_memcpy, program_error::ProgramError, pubkey::Pubkey,
3+
account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, syscalls::sol_memcpy_,
84
ProgramResult,
95
};
106
use spl_token_interface::{
@@ -71,9 +67,6 @@ pub use transfer::process_transfer;
7167
pub use transfer_checked::process_transfer_checked;
7268
pub use ui_amount_to_amount::process_ui_amount_to_amount;
7369

74-
/// An uninitialized byte.
75-
const UNINIT_BYTE: MaybeUninit<u8> = MaybeUninit::uninit();
76-
7770
/// Maximum number of digits in a formatted `u64`.
7871
///
7972
/// The maximum number of digits is equal to the maximum number
@@ -164,41 +157,26 @@ fn try_ui_amount_into_amount(ui_amount: &str, decimals: u8) -> Result<u64, Progr
164157
return Err(ProgramError::InvalidArgument);
165158
}
166159

167-
let mut digits = [UNINIT_BYTE; MAX_FORMATTED_DIGITS];
168-
// SAFETY: `digits` is an array of `MaybeUninit<u8>`, which has the same
169-
// memory layout as `u8`.
170-
let slice: &mut [u8] =
171-
unsafe { from_raw_parts_mut(digits.as_mut_ptr() as *mut _, MAX_FORMATTED_DIGITS) };
160+
let mut digits = [b'0'; MAX_FORMATTED_DIGITS];
172161

173162
// SAFETY: the total length of `amount_str` and `after_decimal` is less than
174163
// `MAX_FORMATTED_DIGITS`.
175164
unsafe {
176-
sol_memcpy(slice, amount_str.as_bytes(), length);
165+
sol_memcpy_(digits.as_mut_ptr(), amount_str.as_ptr(), length as u64);
177166

178-
sol_memcpy(
179-
&mut slice[length..],
180-
after_decimal.as_bytes(),
181-
after_decimal.len(),
167+
sol_memcpy_(
168+
digits.as_mut_ptr().add(length),
169+
after_decimal.as_ptr(),
170+
after_decimal.len() as u64,
182171
);
183172
}
184173

185-
let length = amount_str.len() + after_decimal.len();
186174
let remaining = decimals.saturating_sub(after_decimal.len());
187-
188-
// SAFETY: `digits` is an array of `MaybeUninit<u8>`, which has the same memory
189-
// layout as `u8`.
190-
let ptr = unsafe { digits.as_mut_ptr().add(length) };
191-
192-
for offset in 0..remaining {
193-
// SAFETY: `ptr` is within the bounds of `digits`.
194-
unsafe {
195-
(ptr.add(offset) as *mut u8).write(b'0');
196-
}
197-
}
175+
let length = amount_str.len() + after_decimal.len() + remaining;
198176

199177
// SAFETY: `digits` only contains valid UTF-8 bytes.
200178
unsafe {
201-
from_utf8_unchecked(from_raw_parts(digits.as_ptr() as _, length + remaining))
179+
from_utf8_unchecked(from_raw_parts(digits.as_ptr(), length))
202180
.parse::<u64>()
203181
.map_err(|_| ProgramError::InvalidArgument)
204182
}

p-token/src/processor/set_authority.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ impl SetAuthority<'_> {
125125
unsafe {
126126
match bytes.len() {
127127
2 if *bytes.get_unchecked(1) == 0 => Ok(SetAuthority {
128-
authority_type: AuthorityType::from(*bytes.get_unchecked(0))?,
128+
authority_type: (*bytes.get_unchecked(0)).try_into()?,
129129
new_authority: None,
130130
_data: PhantomData,
131131
}),
132132
34 if *bytes.get_unchecked(1) == 1 => Ok(SetAuthority {
133-
authority_type: AuthorityType::from(*bytes.get_unchecked(0))?,
133+
authority_type: (*bytes.get_unchecked(0)).try_into()?,
134134
new_authority: Some(&*(bytes.as_ptr().add(2) as *const Pubkey)),
135135
_data: PhantomData,
136136
}),

p-token/src/processor/shared/initialize_mint.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ pub struct InitializeMint<'a> {
8080
impl InitializeMint<'_> {
8181
#[inline]
8282
pub fn try_from_bytes(bytes: &[u8]) -> Result<InitializeMint, ProgramError> {
83-
// The minimum expected size of the instruction data.
84-
// - decimals (1 byte)
85-
// - mint_authority (32 bytes)
86-
// - option + freeze_authority (1 byte + 32 bytes)
83+
// The minimum expected size of the instruction data is either 34 or 66 bytes:
84+
// - decimals (1 byte)
85+
// - mint_authority (32 bytes)
86+
// - option + freeze_authority (1 byte + 32 bytes)
8787
if bytes.len() < 34 || (bytes[33] == 1 && bytes.len() < 66) {
8888
return Err(ProgramError::InvalidInstructionData);
8989
}

0 commit comments

Comments
 (0)