|
1 | | -use core::{marker::PhantomData, mem::size_of}; |
2 | | -use pinocchio::{ |
3 | | - account_info::AccountInfo, |
4 | | - program_error::ProgramError, |
5 | | - pubkey::Pubkey, |
6 | | - sysvars::{rent::Rent, Sysvar}, |
7 | | - ProgramResult, |
8 | | -}; |
9 | | -use token_interface::{ |
10 | | - error::TokenError, |
11 | | - state::{load_mut_unchecked, mint::Mint, Initializable}, |
12 | | -}; |
| 1 | +use pinocchio::{account_info::AccountInfo, ProgramResult}; |
13 | 2 |
|
14 | | -#[inline(always)] |
15 | | -pub fn process_initialize_mint( |
16 | | - accounts: &[AccountInfo], |
17 | | - instruction_data: &[u8], |
18 | | - rent_sysvar_account: bool, |
19 | | -) -> ProgramResult { |
20 | | - // Validates the instruction data. |
21 | | - |
22 | | - let args = InitializeMint::try_from_bytes(instruction_data)?; |
23 | | - |
24 | | - // Validates the accounts. |
25 | | - |
26 | | - let (mint_info, rent_sysvar_info) = if rent_sysvar_account { |
27 | | - let [mint_info, rent_sysvar_info, _remaining @ ..] = accounts else { |
28 | | - return Err(ProgramError::NotEnoughAccountKeys); |
29 | | - }; |
30 | | - (mint_info, Some(rent_sysvar_info)) |
31 | | - } else { |
32 | | - let [mint_info, _remaining @ ..] = accounts else { |
33 | | - return Err(ProgramError::NotEnoughAccountKeys); |
34 | | - }; |
35 | | - (mint_info, None) |
36 | | - }; |
37 | | - |
38 | | - let mint = unsafe { load_mut_unchecked::<Mint>(mint_info.borrow_mut_data_unchecked())? }; |
39 | | - |
40 | | - if mint.is_initialized() { |
41 | | - return Err(TokenError::AlreadyInUse.into()); |
42 | | - } |
43 | | - |
44 | | - // Check rent-exempt status of the mint account. |
45 | | - |
46 | | - let is_exempt = if let Some(rent_sysvar_info) = rent_sysvar_info { |
47 | | - let rent = unsafe { Rent::from_bytes(rent_sysvar_info.borrow_data_unchecked())? }; |
48 | | - rent.is_exempt(mint_info.lamports(), size_of::<Mint>()) |
49 | | - } else { |
50 | | - Rent::get()?.is_exempt(mint_info.lamports(), size_of::<Mint>()) |
51 | | - }; |
52 | | - |
53 | | - if !is_exempt { |
54 | | - return Err(TokenError::NotRentExempt.into()); |
55 | | - } |
56 | | - |
57 | | - // Initialize the mint. |
58 | | - |
59 | | - mint.set_initialized(true); |
60 | | - mint.set_mint_authority(args.mint_authority()); |
61 | | - mint.decimals = args.decimals(); |
| 3 | +use super::shared; |
62 | 4 |
|
63 | | - if let Some(freeze_authority) = args.freeze_authority() { |
64 | | - mint.set_freeze_authority(freeze_authority); |
65 | | - } |
66 | | - |
67 | | - Ok(()) |
68 | | -} |
69 | | - |
70 | | -/// Instruction data for the `InitializeMint` instruction. |
71 | | -pub struct InitializeMint<'a> { |
72 | | - raw: *const u8, |
73 | | - |
74 | | - _data: PhantomData<&'a [u8]>, |
75 | | -} |
76 | | - |
77 | | -impl InitializeMint<'_> { |
78 | | - #[inline] |
79 | | - pub fn try_from_bytes(bytes: &[u8]) -> Result<InitializeMint, ProgramError> { |
80 | | - // The minimum expected size of the instruction data. |
81 | | - // - decimals (1 byte) |
82 | | - // - mint_authority (32 bytes) |
83 | | - // - option + freeze_authority (1 byte + 32 bytes) |
84 | | - if bytes.len() < 34 { |
85 | | - return Err(ProgramError::InvalidInstructionData); |
86 | | - } |
87 | | - |
88 | | - Ok(InitializeMint { |
89 | | - raw: bytes.as_ptr(), |
90 | | - _data: PhantomData, |
91 | | - }) |
92 | | - } |
93 | | - |
94 | | - #[inline] |
95 | | - pub fn decimals(&self) -> u8 { |
96 | | - unsafe { *self.raw } |
97 | | - } |
98 | | - |
99 | | - #[inline] |
100 | | - pub fn mint_authority(&self) -> &Pubkey { |
101 | | - unsafe { &*(self.raw.add(1) as *const Pubkey) } |
102 | | - } |
103 | | - |
104 | | - #[inline] |
105 | | - pub fn freeze_authority(&self) -> Option<&Pubkey> { |
106 | | - unsafe { |
107 | | - if *self.raw.add(33) == 0 { |
108 | | - Option::None |
109 | | - } else { |
110 | | - Option::Some(&*(self.raw.add(34) as *const Pubkey)) |
111 | | - } |
112 | | - } |
113 | | - } |
| 5 | +#[inline(always)] |
| 6 | +pub fn process_initialize_mint(accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult { |
| 7 | + shared::initialize_mint::process_initialize_mint(accounts, instruction_data, true) |
114 | 8 | } |
0 commit comments