mint_to.rs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult};
  2. use token_interface::{
  3. error::TokenError,
  4. state::{account::Account, load_mut, mint::Mint},
  5. };
  6. use crate::processor::{check_account_owner, validate_owner};
  7. #[inline(always)]
  8. pub fn process_mint_to(
  9. accounts: &[AccountInfo],
  10. amount: u64,
  11. expected_decimals: Option<u8>,
  12. ) -> ProgramResult {
  13. let [mint_info, destination_account_info, owner_info, remaining @ ..] = accounts else {
  14. return Err(ProgramError::NotEnoughAccountKeys);
  15. };
  16. // Validates the destination account.
  17. let destination_account =
  18. unsafe { load_mut::<Account>(destination_account_info.borrow_mut_data_unchecked())? };
  19. if destination_account.is_frozen() {
  20. return Err(TokenError::AccountFrozen.into());
  21. }
  22. if destination_account.is_native() {
  23. return Err(TokenError::NativeNotSupported.into());
  24. }
  25. if mint_info.key() != &destination_account.mint {
  26. return Err(TokenError::MintMismatch.into());
  27. }
  28. let mint = unsafe { load_mut::<Mint>(mint_info.borrow_mut_data_unchecked())? };
  29. if let Some(expected_decimals) = expected_decimals {
  30. if expected_decimals != mint.decimals {
  31. return Err(TokenError::MintDecimalsMismatch.into());
  32. }
  33. }
  34. match mint.mint_authority() {
  35. Some(mint_authority) => validate_owner(mint_authority, owner_info, remaining)?,
  36. None => return Err(TokenError::FixedSupply.into()),
  37. }
  38. if amount == 0 {
  39. check_account_owner(mint_info)?;
  40. check_account_owner(destination_account_info)?;
  41. } else {
  42. let destination_amount = destination_account
  43. .amount()
  44. .checked_add(amount)
  45. .ok_or(TokenError::Overflow)?;
  46. destination_account.set_amount(destination_amount);
  47. let mint_supply = mint
  48. .supply()
  49. .checked_add(amount)
  50. .ok_or(TokenError::Overflow)?;
  51. mint.set_supply(mint_supply);
  52. }
  53. Ok(())
  54. }