Browse Source

Fix error codes

febo 5 months ago
parent
commit
2559f844e0
36 changed files with 147 additions and 104 deletions
  1. 1 1
      interface/src/error.rs
  2. 4 2
      interface/src/instruction.rs
  3. 26 16
      interface/src/state/account.rs
  4. 15 0
      interface/src/state/account_state.rs
  5. 19 15
      interface/src/state/mint.rs
  6. 3 3
      interface/src/state/mod.rs
  7. 9 5
      interface/src/state/multisig.rs
  8. 3 3
      p-token/src/entrypoint.rs
  9. 1 1
      p-token/src/processor/amount_to_ui_amount.rs
  10. 3 2
      p-token/src/processor/approve.rs
  11. 3 2
      p-token/src/processor/approve_checked.rs
  12. 3 2
      p-token/src/processor/batch.rs
  13. 3 2
      p-token/src/processor/burn.rs
  14. 3 2
      p-token/src/processor/burn_checked.rs
  15. 1 1
      p-token/src/processor/close_account.rs
  16. 3 4
      p-token/src/processor/initialize_account2.rs
  17. 3 4
      p-token/src/processor/initialize_account3.rs
  18. 1 1
      p-token/src/processor/initialize_immutable_owner.rs
  19. 3 2
      p-token/src/processor/initialize_multisig.rs
  20. 3 2
      p-token/src/processor/initialize_multisig2.rs
  21. 3 2
      p-token/src/processor/mint_to.rs
  22. 3 2
      p-token/src/processor/mint_to_checked.rs
  23. 1 1
      p-token/src/processor/revoke.rs
  24. 5 5
      p-token/src/processor/set_authority.rs
  25. 1 1
      p-token/src/processor/shared/approve.rs
  26. 2 2
      p-token/src/processor/shared/burn.rs
  27. 2 2
      p-token/src/processor/shared/initialize_account.rs
  28. 2 2
      p-token/src/processor/shared/initialize_mint.rs
  29. 1 1
      p-token/src/processor/shared/initialize_multisig.rs
  30. 2 2
      p-token/src/processor/shared/mint_to.rs
  31. 4 4
      p-token/src/processor/shared/toggle_account_state.rs
  32. 3 3
      p-token/src/processor/shared/transfer.rs
  33. 3 2
      p-token/src/processor/transfer.rs
  34. 3 2
      p-token/src/processor/transfer_checked.rs
  35. 1 2
      p-token/src/processor/ui_amount_to_amount.rs
  36. 1 1
      p-token/src/processor/withdraw_excess_lamports.rs

+ 1 - 1
interface/src/error.rs

@@ -124,7 +124,7 @@ impl TryFrom<u32> for TokenError {
             17 => Ok(TokenError::AccountFrozen),
             18 => Ok(TokenError::MintDecimalsMismatch),
             19 => Ok(TokenError::NonNativeNotSupported),
-            _ => Err(ProgramError::InvalidArgument),
+            _ => Err(TokenError::InvalidInstruction.into()),
         }
     }
 }

+ 4 - 2
interface/src/instruction.rs

@@ -2,6 +2,8 @@
 
 use pinocchio::program_error::ProgramError;
 
+use crate::error::TokenError;
+
 /// Instructions supported by the token program.
 #[repr(u8)]
 #[derive(Clone, Debug, PartialEq)]
@@ -531,7 +533,7 @@ impl TryFrom<u8> for TokenInstruction {
         match value {
             // SAFETY: `value` is guaranteed to be in the range of the enum variants.
             0..=24 | 38 | 255 => Ok(unsafe { core::mem::transmute::<u8, TokenInstruction>(value) }),
-            _ => Err(ProgramError::InvalidInstructionData),
+            _ => Err(TokenError::InvalidInstruction.into()),
         }
     }
 }
@@ -559,7 +561,7 @@ impl TryFrom<u8> for AuthorityType {
         match value {
             // SAFETY: `value` is guaranteed to be in the range of the enum variants.
             0..=3 => Ok(unsafe { core::mem::transmute::<u8, AuthorityType>(value) }),
-            _ => Err(ProgramError::InvalidInstructionData),
+            _ => Err(TokenError::InvalidInstruction.into()),
         }
     }
 }

+ 26 - 16
interface/src/state/account.rs

@@ -1,6 +1,6 @@
 use {
     super::{account_state::AccountState, COption, Initializable, Transmutable},
-    pinocchio::pubkey::Pubkey,
+    pinocchio::{program_error::ProgramError, pubkey::Pubkey},
 };
 
 /// Incinerator address.
@@ -27,7 +27,7 @@ pub struct Account {
     delegate: COption<Pubkey>,
 
     /// The account's state.
-    pub state: AccountState,
+    state: u8,
 
     /// Indicates whether this account represents a native token or not.
     is_native: [u8; 4],
@@ -46,6 +46,16 @@ pub struct Account {
 }
 
 impl Account {
+    #[inline(always)]
+    pub fn set_account_state(&mut self, state: AccountState) {
+        self.state = state as u8;
+    }
+
+    #[inline(always)]
+    pub fn account_state(&self) -> Result<AccountState, ProgramError> {
+        AccountState::try_from(self.state)
+    }
+
     #[inline(always)]
     pub fn set_amount(&mut self, amount: u64) {
         self.amount = amount.to_le_bytes();
@@ -68,11 +78,11 @@ impl Account {
     }
 
     #[inline(always)]
-    pub fn delegate(&self) -> Option<&Pubkey> {
-        if self.delegate.0[0] == 1 {
-            Some(&self.delegate.1)
-        } else {
-            None
+    pub fn delegate(&self) -> Result<Option<&Pubkey>, ProgramError> {
+        match self.delegate.0 {
+            [0, 0, 0, 0] => Ok(None),
+            [1, 0, 0, 0] => Ok(Some(&self.delegate.1)),
+            _ => Err(ProgramError::InvalidAccountData),
         }
     }
 
@@ -122,17 +132,17 @@ impl Account {
     }
 
     #[inline(always)]
-    pub fn close_authority(&self) -> Option<&Pubkey> {
-        if self.close_authority.0[0] == 1 {
-            Some(&self.close_authority.1)
-        } else {
-            None
+    pub fn close_authority(&self) -> Result<Option<&Pubkey>, ProgramError> {
+        match self.close_authority.0 {
+            [0, 0, 0, 0] => Ok(None),
+            [1, 0, 0, 0] => Ok(Some(&self.close_authority.1)),
+            _ => Err(ProgramError::InvalidAccountData),
         }
     }
 
     #[inline(always)]
-    pub fn is_frozen(&self) -> bool {
-        self.state == AccountState::Frozen
+    pub fn is_frozen(&self) -> Result<bool, ProgramError> {
+        Ok(AccountState::try_from(self.state)? == AccountState::Frozen)
     }
 
     #[inline(always)]
@@ -147,7 +157,7 @@ impl Transmutable for Account {
 
 impl Initializable for Account {
     #[inline(always)]
-    fn is_initialized(&self) -> bool {
-        self.state != AccountState::Uninitialized
+    fn is_initialized(&self) -> Result<bool, ProgramError> {
+        Ok(AccountState::try_from(self.state)? != AccountState::Uninitialized)
     }
 }

+ 15 - 0
interface/src/state/account_state.rs

@@ -1,3 +1,5 @@
+use pinocchio::program_error::ProgramError;
+
 #[repr(u8)]
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub enum AccountState {
@@ -13,3 +15,16 @@ pub enum AccountState {
     /// this account.
     Frozen,
 }
+
+impl TryFrom<u8> for AccountState {
+    type Error = ProgramError;
+
+    #[inline(always)]
+    fn try_from(value: u8) -> Result<Self, Self::Error> {
+        match value {
+            // SAFETY: `value` is guaranteed to be in the range of the enum variants.
+            0..=2 => Ok(unsafe { core::mem::transmute::<u8, AccountState>(value) }),
+            _ => Err(ProgramError::InvalidAccountData),
+        }
+    }
+}

+ 19 - 15
interface/src/state/mint.rs

@@ -1,6 +1,6 @@
 use {
     super::{COption, Initializable, Transmutable},
-    pinocchio::pubkey::Pubkey,
+    pinocchio::{program_error::ProgramError, pubkey::Pubkey},
 };
 
 /// Internal representation of a mint data.
@@ -10,7 +10,7 @@ pub struct Mint {
     /// be provided during mint creation. If no mint authority is present
     /// then the mint has a fixed supply and no further tokens may be
     /// minted.
-    pub mint_authority: COption<Pubkey>,
+    mint_authority: COption<Pubkey>,
 
     /// Total supply of tokens.
     supply: [u8; 8],
@@ -24,7 +24,7 @@ pub struct Mint {
     // Indicates whether the freeze authority is present or not.
     //freeze_authority_option: [u8; 4],
     /// Optional authority to freeze token accounts.
-    pub freeze_authority: COption<Pubkey>,
+    freeze_authority: COption<Pubkey>,
 }
 
 impl Mint {
@@ -55,11 +55,11 @@ impl Mint {
     }
 
     #[inline(always)]
-    pub fn mint_authority(&self) -> Option<&Pubkey> {
-        if self.mint_authority.0[0] == 1 {
-            Some(&self.mint_authority.1)
-        } else {
-            None
+    pub fn mint_authority(&self) -> Result<Option<&Pubkey>, ProgramError> {
+        match self.mint_authority.0 {
+            [0, 0, 0, 0] => Ok(None),
+            [1, 0, 0, 0] => Ok(Some(&self.mint_authority.1)),
+            _ => Err(ProgramError::InvalidAccountData),
         }
     }
 
@@ -75,11 +75,11 @@ impl Mint {
     }
 
     #[inline(always)]
-    pub fn freeze_authority(&self) -> Option<&Pubkey> {
-        if self.freeze_authority.0[0] == 1 {
-            Some(&self.freeze_authority.1)
-        } else {
-            None
+    pub fn freeze_authority(&self) -> Result<Option<&Pubkey>, ProgramError> {
+        match self.freeze_authority.0 {
+            [0, 0, 0, 0] => Ok(None),
+            [1, 0, 0, 0] => Ok(Some(&self.freeze_authority.1)),
+            _ => Err(ProgramError::InvalidAccountData),
         }
     }
 }
@@ -91,7 +91,11 @@ impl Transmutable for Mint {
 
 impl Initializable for Mint {
     #[inline(always)]
-    fn is_initialized(&self) -> bool {
-        self.is_initialized == 1
+    fn is_initialized(&self) -> Result<bool, ProgramError> {
+        match self.is_initialized {
+            0 => Ok(false),
+            1 => Ok(true),
+            _ => Err(ProgramError::InvalidAccountData),
+        }
     }
 }

+ 3 - 3
interface/src/state/mod.rs

@@ -23,7 +23,7 @@ pub trait Transmutable {
 /// Trait to represent a type that can be initialized.
 pub trait Initializable {
     /// Return `true` if the object is initialized.
-    fn is_initialized(&self) -> bool;
+    fn is_initialized(&self) -> Result<bool, ProgramError>;
 }
 
 /// Return a reference for an initialized `T` from the given bytes.
@@ -35,7 +35,7 @@ pub trait Initializable {
 pub unsafe fn load<T: Initializable + Transmutable>(bytes: &[u8]) -> Result<&T, ProgramError> {
     load_unchecked(bytes).and_then(|t: &T| {
         // checks if the data is initialized
-        if t.is_initialized() {
+        if t.is_initialized()? {
             Ok(t)
         } else {
             Err(ProgramError::UninitializedAccount)
@@ -69,7 +69,7 @@ pub unsafe fn load_mut<T: Initializable + Transmutable>(
 ) -> Result<&mut T, ProgramError> {
     load_mut_unchecked(bytes).and_then(|t: &mut T| {
         // checks if the data is initialized
-        if t.is_initialized() {
+        if t.is_initialized()? {
             Ok(t)
         } else {
             Err(ProgramError::UninitializedAccount)

+ 9 - 5
interface/src/state/multisig.rs

@@ -1,6 +1,6 @@
 use {
     super::{Initializable, Transmutable},
-    pinocchio::pubkey::Pubkey,
+    pinocchio::{program_error::ProgramError, pubkey::Pubkey},
 };
 
 /// Minimum number of multisignature signers (min N)
@@ -18,10 +18,10 @@ pub struct Multisig {
     /// Number of valid signers.
     pub n: u8,
 
-    /// Is `true` if this structure has been initialized
+    /// Is `true` if this structure has been initialized.
     is_initialized: u8,
 
-    /// Signer public keys
+    /// Signer public keys.
     pub signers: [Pubkey; MAX_SIGNERS as usize],
 }
 
@@ -45,7 +45,11 @@ impl Transmutable for Multisig {
 
 impl Initializable for Multisig {
     #[inline(always)]
-    fn is_initialized(&self) -> bool {
-        self.is_initialized == 1
+    fn is_initialized(&self) -> Result<bool, ProgramError> {
+        match self.is_initialized {
+            0 => Ok(false),
+            1 => Ok(true),
+            _ => Err(ProgramError::InvalidAccountData),
+        }
     }
 }

+ 3 - 3
p-token/src/entrypoint.rs

@@ -36,7 +36,7 @@ pub fn process_instruction(
     instruction_data: &[u8],
 ) -> ProgramResult {
     let [discriminator, remaining @ ..] = instruction_data else {
-        return Err(ProgramError::InvalidInstructionData);
+        return Err(TokenError::InvalidInstruction.into());
     };
 
     let result = if *discriminator == 255 {
@@ -78,7 +78,7 @@ pub(crate) fn inner_process_instruction(
     instruction_data: &[u8],
 ) -> ProgramResult {
     let [discriminator, instruction_data @ ..] = instruction_data else {
-        return Err(ProgramError::InvalidInstructionData);
+        return Err(TokenError::InvalidInstruction.into());
     };
 
     match *discriminator {
@@ -280,6 +280,6 @@ fn inner_process_remaining_instruction(
 
             process_withdraw_excess_lamports(accounts)
         }
-        _ => Err(ProgramError::InvalidInstructionData),
+        _ => Err(TokenError::InvalidInstruction.into()),
     }
 }

+ 1 - 1
p-token/src/processor/amount_to_ui_amount.rs

@@ -19,7 +19,7 @@ pub fn process_amount_to_ui_amount(
     let amount = u64::from_le_bytes(
         instruction_data
             .try_into()
-            .map_err(|_error| ProgramError::InvalidInstructionData)?,
+            .map_err(|_error| TokenError::InvalidInstruction)?,
     );
 
     let mint_info = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?;

+ 3 - 2
p-token/src/processor/approve.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -8,7 +9,7 @@ pub fn process_approve(accounts: &[AccountInfo], instruction_data: &[u8]) -> Pro
     let amount = u64::from_le_bytes(
         instruction_data
             .try_into()
-            .map_err(|_error| ProgramError::InvalidInstructionData)?,
+            .map_err(|_error| TokenError::InvalidInstruction)?,
     );
 
     shared::approve::process_approve(accounts, amount, None)

+ 3 - 2
p-token/src/processor/approve_checked.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -13,7 +14,7 @@ pub fn process_approve_checked(accounts: &[AccountInfo], instruction_data: &[u8]
             decimals.first().copied(),
         )
     } else {
-        return Err(ProgramError::InvalidInstructionData);
+        return Err(TokenError::InvalidInstruction.into());
     };
 
     shared::approve::process_approve(accounts, amount, decimals)

+ 3 - 2
p-token/src/processor/batch.rs

@@ -1,6 +1,7 @@
 use {
     crate::entrypoint::inner_process_instruction,
     pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 /// The size of the batch instruction header.
@@ -17,7 +18,7 @@ pub fn process_batch(mut accounts: &[AccountInfo], mut instruction_data: &[u8])
 
         if instruction_data.len() < IX_HEADER_SIZE {
             // The instruction data must have at least two bytes.
-            return Err(ProgramError::InvalidInstructionData);
+            return Err(TokenError::InvalidInstruction.into());
         }
 
         // SAFETY: The instruction data is guaranteed to have at least two bytes
@@ -27,7 +28,7 @@ pub fn process_batch(mut accounts: &[AccountInfo], mut instruction_data: &[u8])
         let data_offset = IX_HEADER_SIZE + unsafe { *instruction_data.get_unchecked(1) as usize };
 
         if instruction_data.len() < data_offset || data_offset == IX_HEADER_SIZE {
-            return Err(ProgramError::InvalidInstructionData);
+            return Err(TokenError::InvalidInstruction.into());
         }
 
         if accounts.len() < expected_accounts {

+ 3 - 2
p-token/src/processor/burn.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -8,7 +9,7 @@ pub fn process_burn(accounts: &[AccountInfo], instruction_data: &[u8]) -> Progra
     let amount = u64::from_le_bytes(
         instruction_data
             .try_into()
-            .map_err(|_error| ProgramError::InvalidInstructionData)?,
+            .map_err(|_error| TokenError::InvalidInstruction)?,
     );
 
     shared::burn::process_burn(accounts, amount, None)

+ 3 - 2
p-token/src/processor/burn_checked.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -13,7 +14,7 @@ pub fn process_burn_checked(accounts: &[AccountInfo], instruction_data: &[u8]) -
             decimals.first().copied(),
         )
     } else {
-        return Err(ProgramError::InvalidInstructionData);
+        return Err(TokenError::InvalidInstruction.into());
     };
 
     shared::burn::process_burn(accounts, amount, decimals)

+ 1 - 1
p-token/src/processor/close_account.rs

@@ -33,7 +33,7 @@ pub fn process_close_account(accounts: &[AccountInfo]) -> ProgramResult {
         }
 
         let authority = source_account
-            .close_authority()
+            .close_authority()?
             .unwrap_or(&source_account.owner);
 
         if !source_account.is_owned_by_system_program_or_incinerator() {

+ 3 - 4
p-token/src/processor/initialize_account2.rs

@@ -1,8 +1,7 @@
 use {
     super::shared,
-    pinocchio::{
-        account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
-    },
+    pinocchio::{account_info::AccountInfo, pubkey::Pubkey, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -12,7 +11,7 @@ pub fn process_initialize_account2(
 ) -> ProgramResult {
     let owner: &Pubkey = instruction_data
         .try_into()
-        .map_err(|_error| ProgramError::InvalidInstructionData)?;
+        .map_err(|_error| TokenError::InvalidInstruction)?;
 
     shared::initialize_account::process_initialize_account(accounts, Some(owner), true)
 }

+ 3 - 4
p-token/src/processor/initialize_account3.rs

@@ -1,8 +1,7 @@
 use {
     super::shared,
-    pinocchio::{
-        account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
-    },
+    pinocchio::{account_info::AccountInfo, pubkey::Pubkey, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -12,7 +11,7 @@ pub fn process_initialize_account3(
 ) -> ProgramResult {
     let owner: &Pubkey = instruction_data
         .try_into()
-        .map_err(|_error| ProgramError::InvalidInstructionData)?;
+        .map_err(|_error| TokenError::InvalidInstruction)?;
 
     shared::initialize_account::process_initialize_account(accounts, Some(owner), false)
 }

+ 1 - 1
p-token/src/processor/initialize_immutable_owner.rs

@@ -13,7 +13,7 @@ pub fn process_initialize_immutable_owner(accounts: &[AccountInfo]) -> ProgramRe
     // SAFETY: single immutable borrow to `token_account_info` account data.
     let account = unsafe { load_unchecked::<Account>(token_account_info.borrow_data_unchecked())? };
 
-    if account.is_initialized() {
+    if account.is_initialized()? {
         return Err(TokenError::AlreadyInUse.into());
     }
     // Please upgrade to SPL Token 2022 for immutable owner support.

+ 3 - 2
p-token/src/processor/initialize_multisig.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -10,7 +11,7 @@ pub fn process_initialize_multisig(
 ) -> ProgramResult {
     let m = instruction_data
         .first()
-        .ok_or(ProgramError::InvalidInstructionData)?;
+        .ok_or(TokenError::InvalidInstruction)?;
 
     shared::initialize_multisig::process_initialize_multisig(accounts, *m, true)
 }

+ 3 - 2
p-token/src/processor/initialize_multisig2.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 pub fn process_initialize_multisig2(
@@ -9,6 +10,6 @@ pub fn process_initialize_multisig2(
 ) -> ProgramResult {
     let m = instruction_data
         .first()
-        .ok_or(ProgramError::InvalidInstructionData)?;
+        .ok_or(TokenError::InvalidInstruction)?;
     shared::initialize_multisig::process_initialize_multisig(accounts, *m, false)
 }

+ 3 - 2
p-token/src/processor/mint_to.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -8,7 +9,7 @@ pub fn process_mint_to(accounts: &[AccountInfo], instruction_data: &[u8]) -> Pro
     let amount = u64::from_le_bytes(
         instruction_data
             .try_into()
-            .map_err(|_error| ProgramError::InvalidInstructionData)?,
+            .map_err(|_error| TokenError::InvalidInstruction)?,
     );
 
     shared::mint_to::process_mint_to(accounts, amount, None)

+ 3 - 2
p-token/src/processor/mint_to_checked.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -13,7 +14,7 @@ pub fn process_mint_to_checked(accounts: &[AccountInfo], instruction_data: &[u8]
             decimals.first().copied(),
         )
     } else {
-        return Err(ProgramError::InvalidInstructionData);
+        return Err(TokenError::InvalidInstruction.into());
     };
 
     shared::mint_to::process_mint_to(accounts, amount, decimals)

+ 1 - 1
p-token/src/processor/revoke.rs

@@ -18,7 +18,7 @@ pub fn process_revoke(accounts: &[AccountInfo], _instruction_data: &[u8]) -> Pro
     let source_account =
         unsafe { load_mut::<Account>(source_account_info.borrow_mut_data_unchecked())? };
 
-    if source_account.is_frozen() {
+    if source_account.is_frozen()? {
         return Err(TokenError::AccountFrozen.into());
     }
 

+ 5 - 5
p-token/src/processor/set_authority.rs

@@ -27,7 +27,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
                 AuthorityType::try_from(*instruction_data.get_unchecked(0))?,
                 Some(&*(instruction_data.as_ptr().add(2) as *const Pubkey)),
             ),
-            _ => return Err(ProgramError::InvalidInstructionData),
+            _ => return Err(TokenError::InvalidInstruction.into()),
         }
     };
 
@@ -42,7 +42,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
         // `load_mut` validates that the account is initialized.
         let account = unsafe { load_mut::<Account>(account_info.borrow_mut_data_unchecked())? };
 
-        if account.is_frozen() {
+        if account.is_frozen()? {
             return Err(TokenError::AccountFrozen.into());
         }
 
@@ -64,7 +64,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
                 }
             }
             AuthorityType::CloseAccount => {
-                let authority = account.close_authority().unwrap_or(&account.owner);
+                let authority = account.close_authority()?.unwrap_or(&account.owner);
                 validate_owner(authority, authority_info, remaining)?;
 
                 if let Some(authority) = new_authority {
@@ -86,7 +86,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
             AuthorityType::MintTokens => {
                 // Once a mint's supply is fixed, it cannot be undone by setting a new
                 // mint_authority.
-                let mint_authority = mint.mint_authority().ok_or(TokenError::FixedSupply)?;
+                let mint_authority = mint.mint_authority()?.ok_or(TokenError::FixedSupply)?;
 
                 validate_owner(mint_authority, authority_info, remaining)?;
 
@@ -100,7 +100,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
                 // Once a mint's freeze authority is disabled, it cannot be re-enabled by
                 // setting a new freeze_authority.
                 let freeze_authority = mint
-                    .freeze_authority()
+                    .freeze_authority()?
                     .ok_or(TokenError::MintCannotFreeze)?;
 
                 validate_owner(freeze_authority, authority_info, remaining)?;

+ 1 - 1
p-token/src/processor/shared/approve.rs

@@ -51,7 +51,7 @@ pub fn process_approve(
     let source_account =
         unsafe { load_mut::<Account>(source_account_info.borrow_mut_data_unchecked())? };
 
-    if source_account.is_frozen() {
+    if source_account.is_frozen()? {
         return Err(TokenError::AccountFrozen.into());
     }
 

+ 2 - 2
p-token/src/processor/shared/burn.rs

@@ -22,7 +22,7 @@ pub fn process_burn(
     let source_account =
         unsafe { load_mut::<Account>(source_account_info.borrow_mut_data_unchecked())? };
 
-    if source_account.is_frozen() {
+    if source_account.is_frozen()? {
         return Err(TokenError::AccountFrozen.into());
     }
     if source_account.is_native() {
@@ -53,7 +53,7 @@ pub fn process_burn(
     }
 
     if !source_account.is_owned_by_system_program_or_incinerator() {
-        match source_account.delegate() {
+        match source_account.delegate()? {
             Some(delegate) if authority_info.key() == delegate => {
                 validate_owner(delegate, authority_info, remaining)?;
 

+ 2 - 2
p-token/src/processor/shared/initialize_account.rs

@@ -62,7 +62,7 @@ pub fn process_initialize_account(
     let account =
         unsafe { load_mut_unchecked::<Account>(new_account_info.borrow_mut_data_unchecked())? };
 
-    if account.is_initialized() {
+    if account.is_initialized()? {
         return Err(TokenError::AlreadyInUse.into());
     }
 
@@ -80,7 +80,7 @@ pub fn process_initialize_account(
         };
     }
 
-    account.state = AccountState::Initialized;
+    account.set_account_state(AccountState::Initialized);
     account.mint = *mint_info.key();
     account.owner = *owner;
 

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

@@ -37,7 +37,7 @@ pub fn process_initialize_mint(
                 &*(instruction_data.as_ptr().add(1) as *const Pubkey),
                 Some(&*(instruction_data.as_ptr().add(34) as *const Pubkey)),
             ),
-            _ => return Err(ProgramError::InvalidInstructionData),
+            _ => return Err(TokenError::InvalidInstruction.into()),
         }
     };
 
@@ -58,7 +58,7 @@ pub fn process_initialize_mint(
     // SAFETY: single mutable borrow to `mint_info` account data.
     let mint = unsafe { load_mut_unchecked::<Mint>(mint_info.borrow_mut_data_unchecked())? };
 
-    if mint.is_initialized() {
+    if mint.is_initialized()? {
         return Err(TokenError::AlreadyInUse.into());
     }
 

+ 1 - 1
p-token/src/processor/shared/initialize_multisig.rs

@@ -46,7 +46,7 @@ pub fn process_initialize_multisig(
     let multisig =
         unsafe { load_mut_unchecked::<Multisig>(multisig_info.borrow_mut_data_unchecked())? };
 
-    if multisig.is_initialized() {
+    if multisig.is_initialized()? {
         return Err(TokenError::AlreadyInUse.into());
     }
 

+ 2 - 2
p-token/src/processor/shared/mint_to.rs

@@ -25,7 +25,7 @@ pub fn process_mint_to(
     let destination_account =
         unsafe { load_mut::<Account>(destination_account_info.borrow_mut_data_unchecked())? };
 
-    if destination_account.is_frozen() {
+    if destination_account.is_frozen()? {
         return Err(TokenError::AccountFrozen.into());
     }
 
@@ -47,7 +47,7 @@ pub fn process_mint_to(
         }
     }
 
-    match mint.mint_authority() {
+    match mint.mint_authority()? {
         Some(mint_authority) => validate_owner(mint_authority, owner_info, remaining)?,
         None => return Err(TokenError::FixedSupply.into()),
     }

+ 4 - 4
p-token/src/processor/shared/toggle_account_state.rs

@@ -18,7 +18,7 @@ pub fn process_toggle_account_state(accounts: &[AccountInfo], freeze: bool) -> P
     let source_account =
         unsafe { load_mut::<Account>(source_account_info.borrow_mut_data_unchecked())? };
 
-    if freeze == source_account.is_frozen() {
+    if freeze == source_account.is_frozen()? {
         return Err(TokenError::InvalidState.into());
     }
     if source_account.is_native() {
@@ -34,16 +34,16 @@ pub fn process_toggle_account_state(accounts: &[AccountInfo], freeze: bool) -> P
     // passed in, one of them will fail the `load` check.
     let mint = unsafe { load::<Mint>(mint_info.borrow_data_unchecked())? };
 
-    match mint.freeze_authority() {
+    match mint.freeze_authority()? {
         Some(authority) => validate_owner(authority, authority_info, remaining),
         None => Err(TokenError::MintCannotFreeze.into()),
     }?;
 
-    source_account.state = if freeze {
+    source_account.set_account_state(if freeze {
         AccountState::Frozen
     } else {
         AccountState::Initialized
-    };
+    });
 
     Ok(())
 }

+ 3 - 3
p-token/src/processor/shared/transfer.rs

@@ -77,7 +77,7 @@ pub fn process_transfer(
     //     destination accounts are not frozen, have the same mint, and the source
     //     account has enough tokens.
     let remaining_amount = if self_transfer {
-        if source_account.is_frozen() {
+        if source_account.is_frozen()? {
             return Err(TokenError::AccountFrozen.into());
         }
 
@@ -92,7 +92,7 @@ pub fn process_transfer(
         let destination_account =
             unsafe { load::<Account>(destination_account_info.borrow_data_unchecked())? };
 
-        if source_account.is_frozen() || destination_account.is_frozen() {
+        if source_account.is_frozen()? || destination_account.is_frozen()? {
             return Err(TokenError::AccountFrozen.into());
         }
 
@@ -126,7 +126,7 @@ pub fn process_transfer(
 
     // Validates the authority (delegate or owner).
 
-    if source_account.delegate() == Some(authority_info.key()) {
+    if source_account.delegate()? == Some(authority_info.key()) {
         validate_owner(authority_info.key(), authority_info, remaining)?;
 
         let delegated_amount = source_account

+ 3 - 2
p-token/src/processor/transfer.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -8,7 +9,7 @@ pub fn process_transfer(accounts: &[AccountInfo], instruction_data: &[u8]) -> Pr
     let amount = u64::from_le_bytes(
         instruction_data
             .try_into()
-            .map_err(|_error| ProgramError::InvalidInstructionData)?,
+            .map_err(|_error| TokenError::InvalidInstruction)?,
     );
 
     shared::transfer::process_transfer(accounts, amount, None)

+ 3 - 2
p-token/src/processor/transfer_checked.rs

@@ -1,6 +1,7 @@
 use {
     super::shared,
-    pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
+    pinocchio::{account_info::AccountInfo, ProgramResult},
+    spl_token_interface::error::TokenError,
 };
 
 #[inline(always)]
@@ -16,7 +17,7 @@ pub fn process_transfer_checked(
             decimals.first().copied(),
         )
     } else {
-        return Err(ProgramError::InvalidInstructionData);
+        return Err(TokenError::InvalidInstruction.into());
     };
 
     shared::transfer::process_transfer(accounts, amount, decimals)

+ 1 - 2
p-token/src/processor/ui_amount_to_amount.rs

@@ -15,8 +15,7 @@ pub fn process_ui_amount_to_amount(
     accounts: &[AccountInfo],
     instruction_data: &[u8],
 ) -> ProgramResult {
-    let ui_amount =
-        from_utf8(instruction_data).map_err(|_error| ProgramError::InvalidInstructionData)?;
+    let ui_amount = from_utf8(instruction_data).map_err(|_error| TokenError::InvalidInstruction)?;
 
     let mint_info = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?;
     check_account_owner(mint_info)?;

+ 1 - 1
p-token/src/processor/withdraw_excess_lamports.rs

@@ -36,7 +36,7 @@ pub fn process_withdraw_excess_lamports(accounts: &[AccountInfo]) -> ProgramResu
             // SAFETY: `source_data` has the same length as `Mint`.
             let mint = unsafe { load::<Mint>(source_data)? };
 
-            if let Some(mint_authority) = mint.mint_authority() {
+            if let Some(mint_authority) = mint.mint_authority()? {
                 validate_owner(mint_authority, authority_info, remaining)?;
             } else {
                 return Err(TokenError::AuthorityTypeNotSupported.into());