1use {
4 crate::{
5 amount_to_ui_amount_string_trimmed,
6 error::TokenError,
7 instruction::{is_valid_signer_index, AuthorityType, TokenInstruction, MAX_SIGNERS},
8 state::{Account, AccountState, Mint, Multisig},
9 try_ui_amount_into_amount,
10 },
11 miraland_program::{
12 account_info::{next_account_info, AccountInfo},
13 entrypoint::ProgramResult,
14 msg,
15 program::set_return_data,
16 program_error::ProgramError,
17 program_memory::sol_memcmp,
18 program_option::COption,
19 program_pack::{IsInitialized, Pack},
20 pubkey::{Pubkey, PUBKEY_BYTES},
21 system_program,
22 sysvar::{rent::Rent, Sysvar},
23 },
24};
25
26pub struct Processor {}
28impl Processor {
29 fn _process_initialize_mint(
30 accounts: &[AccountInfo],
31 decimals: u8,
32 mint_authority: Pubkey,
33 freeze_authority: COption<Pubkey>,
34 rent_sysvar_account: bool,
35 ) -> ProgramResult {
36 let account_info_iter = &mut accounts.iter();
37 let mint_info = next_account_info(account_info_iter)?;
38 let mint_data_len = mint_info.data_len();
39 let rent = if rent_sysvar_account {
40 Rent::from_account_info(next_account_info(account_info_iter)?)?
41 } else {
42 Rent::get()?
43 };
44
45 let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow())?;
46 if mint.is_initialized {
47 return Err(TokenError::AlreadyInUse.into());
48 }
49
50 if !rent.is_exempt(mint_info.lamports(), mint_data_len) {
51 return Err(TokenError::NotRentExempt.into());
52 }
53
54 mint.mint_authority = COption::Some(mint_authority);
55 mint.decimals = decimals;
56 mint.is_initialized = true;
57 mint.freeze_authority = freeze_authority;
58
59 Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
60
61 Ok(())
62 }
63
64 pub fn process_initialize_mint(
66 accounts: &[AccountInfo],
67 decimals: u8,
68 mint_authority: Pubkey,
69 freeze_authority: COption<Pubkey>,
70 ) -> ProgramResult {
71 Self::_process_initialize_mint(accounts, decimals, mint_authority, freeze_authority, true)
72 }
73
74 pub fn process_initialize_mint2(
76 accounts: &[AccountInfo],
77 decimals: u8,
78 mint_authority: Pubkey,
79 freeze_authority: COption<Pubkey>,
80 ) -> ProgramResult {
81 Self::_process_initialize_mint(accounts, decimals, mint_authority, freeze_authority, false)
82 }
83
84 fn _process_initialize_account(
85 program_id: &Pubkey,
86 accounts: &[AccountInfo],
87 owner: Option<&Pubkey>,
88 rent_sysvar_account: bool,
89 ) -> ProgramResult {
90 let account_info_iter = &mut accounts.iter();
91 let new_account_info = next_account_info(account_info_iter)?;
92 let mint_info = next_account_info(account_info_iter)?;
93 let owner = if let Some(owner) = owner {
94 owner
95 } else {
96 next_account_info(account_info_iter)?.key
97 };
98 let new_account_info_data_len = new_account_info.data_len();
99 let rent = if rent_sysvar_account {
100 Rent::from_account_info(next_account_info(account_info_iter)?)?
101 } else {
102 Rent::get()?
103 };
104
105 let mut account = Account::unpack_unchecked(&new_account_info.data.borrow())?;
106 if account.is_initialized() {
107 return Err(TokenError::AlreadyInUse.into());
108 }
109
110 if !rent.is_exempt(new_account_info.lamports(), new_account_info_data_len) {
111 return Err(TokenError::NotRentExempt.into());
112 }
113
114 let is_native_mint = Self::cmp_pubkeys(mint_info.key, &crate::native_mint::id());
115 if !is_native_mint {
116 Self::check_account_owner(program_id, mint_info)?;
117 let _ = Mint::unpack(&mint_info.data.borrow_mut())
118 .map_err(|_| Into::<ProgramError>::into(TokenError::InvalidMint))?;
119 }
120
121 account.mint = *mint_info.key;
122 account.owner = *owner;
123 account.close_authority = COption::None;
124 account.delegate = COption::None;
125 account.delegated_amount = 0;
126 account.state = AccountState::Initialized;
127 if is_native_mint {
128 let rent_exempt_reserve = rent.minimum_balance(new_account_info_data_len);
129 account.is_native = COption::Some(rent_exempt_reserve);
130 account.amount = new_account_info
131 .lamports()
132 .checked_sub(rent_exempt_reserve)
133 .ok_or(TokenError::Overflow)?;
134 } else {
135 account.is_native = COption::None;
136 account.amount = 0;
137 };
138
139 Account::pack(account, &mut new_account_info.data.borrow_mut())?;
140
141 Ok(())
142 }
143
144 pub fn process_initialize_account(
147 program_id: &Pubkey,
148 accounts: &[AccountInfo],
149 ) -> ProgramResult {
150 Self::_process_initialize_account(program_id, accounts, None, true)
151 }
152
153 pub fn process_initialize_account2(
156 program_id: &Pubkey,
157 accounts: &[AccountInfo],
158 owner: Pubkey,
159 ) -> ProgramResult {
160 Self::_process_initialize_account(program_id, accounts, Some(&owner), true)
161 }
162
163 pub fn process_initialize_account3(
166 program_id: &Pubkey,
167 accounts: &[AccountInfo],
168 owner: Pubkey,
169 ) -> ProgramResult {
170 Self::_process_initialize_account(program_id, accounts, Some(&owner), false)
171 }
172
173 fn _process_initialize_multisig(
174 accounts: &[AccountInfo],
175 m: u8,
176 rent_sysvar_account: bool,
177 ) -> ProgramResult {
178 let account_info_iter = &mut accounts.iter();
179 let multisig_info = next_account_info(account_info_iter)?;
180 let multisig_info_data_len = multisig_info.data_len();
181 let rent = if rent_sysvar_account {
182 Rent::from_account_info(next_account_info(account_info_iter)?)?
183 } else {
184 Rent::get()?
185 };
186
187 let mut multisig = Multisig::unpack_unchecked(&multisig_info.data.borrow())?;
188 if multisig.is_initialized {
189 return Err(TokenError::AlreadyInUse.into());
190 }
191
192 if !rent.is_exempt(multisig_info.lamports(), multisig_info_data_len) {
193 return Err(TokenError::NotRentExempt.into());
194 }
195
196 let signer_infos = account_info_iter.as_slice();
197 multisig.m = m;
198 multisig.n = signer_infos.len() as u8;
199 if !is_valid_signer_index(multisig.n as usize) {
200 return Err(TokenError::InvalidNumberOfProvidedSigners.into());
201 }
202 if !is_valid_signer_index(multisig.m as usize) {
203 return Err(TokenError::InvalidNumberOfRequiredSigners.into());
204 }
205 for (i, signer_info) in signer_infos.iter().enumerate() {
206 multisig.signers[i] = *signer_info.key;
207 }
208 multisig.is_initialized = true;
209
210 Multisig::pack(multisig, &mut multisig_info.data.borrow_mut())?;
211
212 Ok(())
213 }
214
215 pub fn process_initialize_multisig(accounts: &[AccountInfo], m: u8) -> ProgramResult {
218 Self::_process_initialize_multisig(accounts, m, true)
219 }
220
221 pub fn process_initialize_multisig2(accounts: &[AccountInfo], m: u8) -> ProgramResult {
224 Self::_process_initialize_multisig(accounts, m, false)
225 }
226
227 pub fn process_transfer(
229 program_id: &Pubkey,
230 accounts: &[AccountInfo],
231 amount: u64,
232 expected_decimals: Option<u8>,
233 ) -> ProgramResult {
234 let account_info_iter = &mut accounts.iter();
235
236 let source_account_info = next_account_info(account_info_iter)?;
237
238 let expected_mint_info = if let Some(expected_decimals) = expected_decimals {
239 Some((next_account_info(account_info_iter)?, expected_decimals))
240 } else {
241 None
242 };
243
244 let destination_account_info = next_account_info(account_info_iter)?;
245 let authority_info = next_account_info(account_info_iter)?;
246
247 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
248 let mut destination_account = Account::unpack(&destination_account_info.data.borrow())?;
249
250 if source_account.is_frozen() || destination_account.is_frozen() {
251 return Err(TokenError::AccountFrozen.into());
252 }
253 if source_account.amount < amount {
254 return Err(TokenError::InsufficientFunds.into());
255 }
256 if !Self::cmp_pubkeys(&source_account.mint, &destination_account.mint) {
257 return Err(TokenError::MintMismatch.into());
258 }
259
260 if let Some((mint_info, expected_decimals)) = expected_mint_info {
261 if !Self::cmp_pubkeys(mint_info.key, &source_account.mint) {
262 return Err(TokenError::MintMismatch.into());
263 }
264
265 let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
266 if expected_decimals != mint.decimals {
267 return Err(TokenError::MintDecimalsMismatch.into());
268 }
269 }
270
271 let self_transfer =
272 Self::cmp_pubkeys(source_account_info.key, destination_account_info.key);
273
274 match source_account.delegate {
275 COption::Some(ref delegate) if Self::cmp_pubkeys(authority_info.key, delegate) => {
276 Self::validate_owner(
277 program_id,
278 delegate,
279 authority_info,
280 account_info_iter.as_slice(),
281 )?;
282 if source_account.delegated_amount < amount {
283 return Err(TokenError::InsufficientFunds.into());
284 }
285 if !self_transfer {
286 source_account.delegated_amount = source_account
287 .delegated_amount
288 .checked_sub(amount)
289 .ok_or(TokenError::Overflow)?;
290 if source_account.delegated_amount == 0 {
291 source_account.delegate = COption::None;
292 }
293 }
294 }
295 _ => Self::validate_owner(
296 program_id,
297 &source_account.owner,
298 authority_info,
299 account_info_iter.as_slice(),
300 )?,
301 };
302
303 if self_transfer || amount == 0 {
304 Self::check_account_owner(program_id, source_account_info)?;
305 Self::check_account_owner(program_id, destination_account_info)?;
306 }
307
308 if self_transfer {
311 return Ok(());
312 }
313
314 source_account.amount = source_account
315 .amount
316 .checked_sub(amount)
317 .ok_or(TokenError::Overflow)?;
318 destination_account.amount = destination_account
319 .amount
320 .checked_add(amount)
321 .ok_or(TokenError::Overflow)?;
322
323 if source_account.is_native() {
324 let source_starting_lamports = source_account_info.lamports();
325 **source_account_info.lamports.borrow_mut() = source_starting_lamports
326 .checked_sub(amount)
327 .ok_or(TokenError::Overflow)?;
328
329 let destination_starting_lamports = destination_account_info.lamports();
330 **destination_account_info.lamports.borrow_mut() = destination_starting_lamports
331 .checked_add(amount)
332 .ok_or(TokenError::Overflow)?;
333 }
334
335 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
336 Account::pack(
337 destination_account,
338 &mut destination_account_info.data.borrow_mut(),
339 )?;
340
341 Ok(())
342 }
343
344 pub fn process_approve(
346 program_id: &Pubkey,
347 accounts: &[AccountInfo],
348 amount: u64,
349 expected_decimals: Option<u8>,
350 ) -> ProgramResult {
351 let account_info_iter = &mut accounts.iter();
352
353 let source_account_info = next_account_info(account_info_iter)?;
354
355 let expected_mint_info = if let Some(expected_decimals) = expected_decimals {
356 Some((next_account_info(account_info_iter)?, expected_decimals))
357 } else {
358 None
359 };
360 let delegate_info = next_account_info(account_info_iter)?;
361 let owner_info = next_account_info(account_info_iter)?;
362
363 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
364
365 if source_account.is_frozen() {
366 return Err(TokenError::AccountFrozen.into());
367 }
368
369 if let Some((mint_info, expected_decimals)) = expected_mint_info {
370 if !Self::cmp_pubkeys(mint_info.key, &source_account.mint) {
371 return Err(TokenError::MintMismatch.into());
372 }
373
374 let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
375 if expected_decimals != mint.decimals {
376 return Err(TokenError::MintDecimalsMismatch.into());
377 }
378 }
379
380 Self::validate_owner(
381 program_id,
382 &source_account.owner,
383 owner_info,
384 account_info_iter.as_slice(),
385 )?;
386
387 source_account.delegate = COption::Some(*delegate_info.key);
388 source_account.delegated_amount = amount;
389
390 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
391
392 Ok(())
393 }
394
395 pub fn process_revoke(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
397 let account_info_iter = &mut accounts.iter();
398 let source_account_info = next_account_info(account_info_iter)?;
399
400 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
401
402 let owner_info = next_account_info(account_info_iter)?;
403
404 if source_account.is_frozen() {
405 return Err(TokenError::AccountFrozen.into());
406 }
407
408 Self::validate_owner(
409 program_id,
410 &source_account.owner,
411 owner_info,
412 account_info_iter.as_slice(),
413 )?;
414
415 source_account.delegate = COption::None;
416 source_account.delegated_amount = 0;
417
418 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
419
420 Ok(())
421 }
422
423 pub fn process_set_authority(
425 program_id: &Pubkey,
426 accounts: &[AccountInfo],
427 authority_type: AuthorityType,
428 new_authority: COption<Pubkey>,
429 ) -> ProgramResult {
430 let account_info_iter = &mut accounts.iter();
431 let account_info = next_account_info(account_info_iter)?;
432 let authority_info = next_account_info(account_info_iter)?;
433
434 if account_info.data_len() == Account::get_packed_len() {
435 let mut account = Account::unpack(&account_info.data.borrow())?;
436
437 if account.is_frozen() {
438 return Err(TokenError::AccountFrozen.into());
439 }
440
441 match authority_type {
442 AuthorityType::AccountOwner => {
443 Self::validate_owner(
444 program_id,
445 &account.owner,
446 authority_info,
447 account_info_iter.as_slice(),
448 )?;
449
450 if let COption::Some(authority) = new_authority {
451 account.owner = authority;
452 } else {
453 return Err(TokenError::InvalidInstruction.into());
454 }
455
456 account.delegate = COption::None;
457 account.delegated_amount = 0;
458
459 if account.is_native() {
460 account.close_authority = COption::None;
461 }
462 }
463 AuthorityType::CloseAccount => {
464 let authority = account.close_authority.unwrap_or(account.owner);
465 Self::validate_owner(
466 program_id,
467 &authority,
468 authority_info,
469 account_info_iter.as_slice(),
470 )?;
471 account.close_authority = new_authority;
472 }
473 _ => {
474 return Err(TokenError::AuthorityTypeNotSupported.into());
475 }
476 }
477 Account::pack(account, &mut account_info.data.borrow_mut())?;
478 } else if account_info.data_len() == Mint::get_packed_len() {
479 let mut mint = Mint::unpack(&account_info.data.borrow())?;
480 match authority_type {
481 AuthorityType::MintTokens => {
482 let mint_authority = mint
485 .mint_authority
486 .ok_or(Into::<ProgramError>::into(TokenError::FixedSupply))?;
487 Self::validate_owner(
488 program_id,
489 &mint_authority,
490 authority_info,
491 account_info_iter.as_slice(),
492 )?;
493 mint.mint_authority = new_authority;
494 }
495 AuthorityType::FreezeAccount => {
496 let freeze_authority = mint
499 .freeze_authority
500 .ok_or(Into::<ProgramError>::into(TokenError::MintCannotFreeze))?;
501 Self::validate_owner(
502 program_id,
503 &freeze_authority,
504 authority_info,
505 account_info_iter.as_slice(),
506 )?;
507 mint.freeze_authority = new_authority;
508 }
509 _ => {
510 return Err(TokenError::AuthorityTypeNotSupported.into());
511 }
512 }
513 Mint::pack(mint, &mut account_info.data.borrow_mut())?;
514 } else {
515 return Err(ProgramError::InvalidArgument);
516 }
517
518 Ok(())
519 }
520
521 pub fn process_mint_to(
523 program_id: &Pubkey,
524 accounts: &[AccountInfo],
525 amount: u64,
526 expected_decimals: Option<u8>,
527 ) -> ProgramResult {
528 let account_info_iter = &mut accounts.iter();
529 let mint_info = next_account_info(account_info_iter)?;
530 let destination_account_info = next_account_info(account_info_iter)?;
531 let owner_info = next_account_info(account_info_iter)?;
532
533 let mut destination_account = Account::unpack(&destination_account_info.data.borrow())?;
534 if destination_account.is_frozen() {
535 return Err(TokenError::AccountFrozen.into());
536 }
537
538 if destination_account.is_native() {
539 return Err(TokenError::NativeNotSupported.into());
540 }
541 if !Self::cmp_pubkeys(mint_info.key, &destination_account.mint) {
542 return Err(TokenError::MintMismatch.into());
543 }
544
545 let mut mint = Mint::unpack(&mint_info.data.borrow())?;
546 if let Some(expected_decimals) = expected_decimals {
547 if expected_decimals != mint.decimals {
548 return Err(TokenError::MintDecimalsMismatch.into());
549 }
550 }
551
552 match mint.mint_authority {
553 COption::Some(mint_authority) => Self::validate_owner(
554 program_id,
555 &mint_authority,
556 owner_info,
557 account_info_iter.as_slice(),
558 )?,
559 COption::None => return Err(TokenError::FixedSupply.into()),
560 }
561
562 if amount == 0 {
563 Self::check_account_owner(program_id, mint_info)?;
564 Self::check_account_owner(program_id, destination_account_info)?;
565 }
566
567 destination_account.amount = destination_account
568 .amount
569 .checked_add(amount)
570 .ok_or(TokenError::Overflow)?;
571
572 mint.supply = mint
573 .supply
574 .checked_add(amount)
575 .ok_or(TokenError::Overflow)?;
576
577 Account::pack(
578 destination_account,
579 &mut destination_account_info.data.borrow_mut(),
580 )?;
581 Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
582
583 Ok(())
584 }
585
586 pub fn process_burn(
588 program_id: &Pubkey,
589 accounts: &[AccountInfo],
590 amount: u64,
591 expected_decimals: Option<u8>,
592 ) -> ProgramResult {
593 let account_info_iter = &mut accounts.iter();
594
595 let source_account_info = next_account_info(account_info_iter)?;
596 let mint_info = next_account_info(account_info_iter)?;
597 let authority_info = next_account_info(account_info_iter)?;
598
599 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
600 let mut mint = Mint::unpack(&mint_info.data.borrow())?;
601
602 if source_account.is_frozen() {
603 return Err(TokenError::AccountFrozen.into());
604 }
605 if source_account.is_native() {
606 return Err(TokenError::NativeNotSupported.into());
607 }
608 if source_account.amount < amount {
609 return Err(TokenError::InsufficientFunds.into());
610 }
611 if !Self::cmp_pubkeys(mint_info.key, &source_account.mint) {
612 return Err(TokenError::MintMismatch.into());
613 }
614
615 if let Some(expected_decimals) = expected_decimals {
616 if expected_decimals != mint.decimals {
617 return Err(TokenError::MintDecimalsMismatch.into());
618 }
619 }
620
621 if !source_account.is_owned_by_system_program_or_incinerator() {
622 match source_account.delegate {
623 COption::Some(ref delegate) if Self::cmp_pubkeys(authority_info.key, delegate) => {
624 Self::validate_owner(
625 program_id,
626 delegate,
627 authority_info,
628 account_info_iter.as_slice(),
629 )?;
630
631 if source_account.delegated_amount < amount {
632 return Err(TokenError::InsufficientFunds.into());
633 }
634 source_account.delegated_amount = source_account
635 .delegated_amount
636 .checked_sub(amount)
637 .ok_or(TokenError::Overflow)?;
638 if source_account.delegated_amount == 0 {
639 source_account.delegate = COption::None;
640 }
641 }
642 _ => Self::validate_owner(
643 program_id,
644 &source_account.owner,
645 authority_info,
646 account_info_iter.as_slice(),
647 )?,
648 }
649 }
650
651 if amount == 0 {
652 Self::check_account_owner(program_id, source_account_info)?;
653 Self::check_account_owner(program_id, mint_info)?;
654 }
655
656 source_account.amount = source_account
657 .amount
658 .checked_sub(amount)
659 .ok_or(TokenError::Overflow)?;
660 mint.supply = mint
661 .supply
662 .checked_sub(amount)
663 .ok_or(TokenError::Overflow)?;
664
665 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
666 Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
667
668 Ok(())
669 }
670
671 pub fn process_close_account(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
673 let account_info_iter = &mut accounts.iter();
674 let source_account_info = next_account_info(account_info_iter)?;
675 let destination_account_info = next_account_info(account_info_iter)?;
676 let authority_info = next_account_info(account_info_iter)?;
677
678 if Self::cmp_pubkeys(source_account_info.key, destination_account_info.key) {
679 return Err(ProgramError::InvalidAccountData);
680 }
681
682 let source_account = Account::unpack(&source_account_info.data.borrow())?;
683 if !source_account.is_native() && source_account.amount != 0 {
684 return Err(TokenError::NonNativeHasBalance.into());
685 }
686
687 let authority = source_account
688 .close_authority
689 .unwrap_or(source_account.owner);
690 if !source_account.is_owned_by_system_program_or_incinerator() {
691 Self::validate_owner(
692 program_id,
693 &authority,
694 authority_info,
695 account_info_iter.as_slice(),
696 )?;
697 } else if !miraland_program::incinerator::check_id(destination_account_info.key) {
698 return Err(ProgramError::InvalidAccountData);
699 }
700
701 let destination_starting_lamports = destination_account_info.lamports();
702 **destination_account_info.lamports.borrow_mut() = destination_starting_lamports
703 .checked_add(source_account_info.lamports())
704 .ok_or(TokenError::Overflow)?;
705
706 **source_account_info.lamports.borrow_mut() = 0;
707 delete_account(source_account_info)?;
708
709 Ok(())
710 }
711
712 pub fn process_toggle_freeze_account(
715 program_id: &Pubkey,
716 accounts: &[AccountInfo],
717 freeze: bool,
718 ) -> ProgramResult {
719 let account_info_iter = &mut accounts.iter();
720 let source_account_info = next_account_info(account_info_iter)?;
721 let mint_info = next_account_info(account_info_iter)?;
722 let authority_info = next_account_info(account_info_iter)?;
723
724 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
725 if freeze && source_account.is_frozen() || !freeze && !source_account.is_frozen() {
726 return Err(TokenError::InvalidState.into());
727 }
728 if source_account.is_native() {
729 return Err(TokenError::NativeNotSupported.into());
730 }
731 if !Self::cmp_pubkeys(mint_info.key, &source_account.mint) {
732 return Err(TokenError::MintMismatch.into());
733 }
734
735 let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
736 match mint.freeze_authority {
737 COption::Some(authority) => Self::validate_owner(
738 program_id,
739 &authority,
740 authority_info,
741 account_info_iter.as_slice(),
742 ),
743 COption::None => Err(TokenError::MintCannotFreeze.into()),
744 }?;
745
746 source_account.state = if freeze {
747 AccountState::Frozen
748 } else {
749 AccountState::Initialized
750 };
751
752 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
753
754 Ok(())
755 }
756
757 pub fn process_sync_native(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
759 let account_info_iter = &mut accounts.iter();
760 let native_account_info = next_account_info(account_info_iter)?;
761 Self::check_account_owner(program_id, native_account_info)?;
762
763 let mut native_account = Account::unpack(&native_account_info.data.borrow())?;
764
765 if let COption::Some(rent_exempt_reserve) = native_account.is_native {
766 let new_amount = native_account_info
767 .lamports()
768 .checked_sub(rent_exempt_reserve)
769 .ok_or(TokenError::Overflow)?;
770 if new_amount < native_account.amount {
771 return Err(TokenError::InvalidState.into());
772 }
773 native_account.amount = new_amount;
774 } else {
775 return Err(TokenError::NonNativeNotSupported.into());
776 }
777
778 Account::pack(native_account, &mut native_account_info.data.borrow_mut())?;
779 Ok(())
780 }
781
782 pub fn process_get_account_data_size(
784 program_id: &Pubkey,
785 accounts: &[AccountInfo],
786 ) -> ProgramResult {
787 let account_info_iter = &mut accounts.iter();
788 let mint_info = next_account_info(account_info_iter)?;
790 Self::check_account_owner(program_id, mint_info)?;
791 let _ = Mint::unpack(&mint_info.data.borrow())
792 .map_err(|_| Into::<ProgramError>::into(TokenError::InvalidMint))?;
793 set_return_data(&Account::LEN.to_le_bytes());
794 Ok(())
795 }
796
797 pub fn process_initialize_immutable_owner(accounts: &[AccountInfo]) -> ProgramResult {
800 let account_info_iter = &mut accounts.iter();
801 let token_account_info = next_account_info(account_info_iter)?;
802 let account = Account::unpack_unchecked(&token_account_info.data.borrow())?;
803 if account.is_initialized() {
804 return Err(TokenError::AlreadyInUse.into());
805 }
806 msg!("Please upgrade to Solarti Token 2022 for immutable owner support");
807 Ok(())
808 }
809
810 pub fn process_amount_to_ui_amount(
812 program_id: &Pubkey,
813 accounts: &[AccountInfo],
814 amount: u64,
815 ) -> ProgramResult {
816 let account_info_iter = &mut accounts.iter();
817 let mint_info = next_account_info(account_info_iter)?;
818 Self::check_account_owner(program_id, mint_info)?;
819
820 let mint = Mint::unpack(&mint_info.data.borrow_mut())
821 .map_err(|_| Into::<ProgramError>::into(TokenError::InvalidMint))?;
822 let ui_amount = amount_to_ui_amount_string_trimmed(amount, mint.decimals);
823
824 set_return_data(&ui_amount.into_bytes());
825 Ok(())
826 }
827
828 pub fn process_ui_amount_to_amount(
830 program_id: &Pubkey,
831 accounts: &[AccountInfo],
832 ui_amount: &str,
833 ) -> ProgramResult {
834 let account_info_iter = &mut accounts.iter();
835 let mint_info = next_account_info(account_info_iter)?;
836 Self::check_account_owner(program_id, mint_info)?;
837
838 let mint = Mint::unpack(&mint_info.data.borrow_mut())
839 .map_err(|_| Into::<ProgramError>::into(TokenError::InvalidMint))?;
840 let amount = try_ui_amount_into_amount(ui_amount.to_string(), mint.decimals)?;
841
842 set_return_data(&amount.to_le_bytes());
843 Ok(())
844 }
845
846 pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {
848 let instruction = TokenInstruction::unpack(input)?;
849
850 match instruction {
851 TokenInstruction::InitializeMint {
852 decimals,
853 mint_authority,
854 freeze_authority,
855 } => {
856 msg!("Instruction: InitializeMint");
857 Self::process_initialize_mint(accounts, decimals, mint_authority, freeze_authority)
858 }
859 TokenInstruction::InitializeMint2 {
860 decimals,
861 mint_authority,
862 freeze_authority,
863 } => {
864 msg!("Instruction: InitializeMint2");
865 Self::process_initialize_mint2(accounts, decimals, mint_authority, freeze_authority)
866 }
867 TokenInstruction::InitializeAccount => {
868 msg!("Instruction: InitializeAccount");
869 Self::process_initialize_account(program_id, accounts)
870 }
871 TokenInstruction::InitializeAccount2 { owner } => {
872 msg!("Instruction: InitializeAccount2");
873 Self::process_initialize_account2(program_id, accounts, owner)
874 }
875 TokenInstruction::InitializeAccount3 { owner } => {
876 msg!("Instruction: InitializeAccount3");
877 Self::process_initialize_account3(program_id, accounts, owner)
878 }
879 TokenInstruction::InitializeMultisig { m } => {
880 msg!("Instruction: InitializeMultisig");
881 Self::process_initialize_multisig(accounts, m)
882 }
883 TokenInstruction::InitializeMultisig2 { m } => {
884 msg!("Instruction: InitializeMultisig2");
885 Self::process_initialize_multisig2(accounts, m)
886 }
887 TokenInstruction::Transfer { amount } => {
888 msg!("Instruction: Transfer");
889 Self::process_transfer(program_id, accounts, amount, None)
890 }
891 TokenInstruction::Approve { amount } => {
892 msg!("Instruction: Approve");
893 Self::process_approve(program_id, accounts, amount, None)
894 }
895 TokenInstruction::Revoke => {
896 msg!("Instruction: Revoke");
897 Self::process_revoke(program_id, accounts)
898 }
899 TokenInstruction::SetAuthority {
900 authority_type,
901 new_authority,
902 } => {
903 msg!("Instruction: SetAuthority");
904 Self::process_set_authority(program_id, accounts, authority_type, new_authority)
905 }
906 TokenInstruction::MintTo { amount } => {
907 msg!("Instruction: MintTo");
908 Self::process_mint_to(program_id, accounts, amount, None)
909 }
910 TokenInstruction::Burn { amount } => {
911 msg!("Instruction: Burn");
912 Self::process_burn(program_id, accounts, amount, None)
913 }
914 TokenInstruction::CloseAccount => {
915 msg!("Instruction: CloseAccount");
916 Self::process_close_account(program_id, accounts)
917 }
918 TokenInstruction::FreezeAccount => {
919 msg!("Instruction: FreezeAccount");
920 Self::process_toggle_freeze_account(program_id, accounts, true)
921 }
922 TokenInstruction::ThawAccount => {
923 msg!("Instruction: ThawAccount");
924 Self::process_toggle_freeze_account(program_id, accounts, false)
925 }
926 TokenInstruction::TransferChecked { amount, decimals } => {
927 msg!("Instruction: TransferChecked");
928 Self::process_transfer(program_id, accounts, amount, Some(decimals))
929 }
930 TokenInstruction::ApproveChecked { amount, decimals } => {
931 msg!("Instruction: ApproveChecked");
932 Self::process_approve(program_id, accounts, amount, Some(decimals))
933 }
934 TokenInstruction::MintToChecked { amount, decimals } => {
935 msg!("Instruction: MintToChecked");
936 Self::process_mint_to(program_id, accounts, amount, Some(decimals))
937 }
938 TokenInstruction::BurnChecked { amount, decimals } => {
939 msg!("Instruction: BurnChecked");
940 Self::process_burn(program_id, accounts, amount, Some(decimals))
941 }
942 TokenInstruction::SyncNative => {
943 msg!("Instruction: SyncNative");
944 Self::process_sync_native(program_id, accounts)
945 }
946 TokenInstruction::GetAccountDataSize => {
947 msg!("Instruction: GetAccountDataSize");
948 Self::process_get_account_data_size(program_id, accounts)
949 }
950 TokenInstruction::InitializeImmutableOwner => {
951 msg!("Instruction: InitializeImmutableOwner");
952 Self::process_initialize_immutable_owner(accounts)
953 }
954 TokenInstruction::AmountToUiAmount { amount } => {
955 msg!("Instruction: AmountToUiAmount");
956 Self::process_amount_to_ui_amount(program_id, accounts, amount)
957 }
958 TokenInstruction::UiAmountToAmount { ui_amount } => {
959 msg!("Instruction: UiAmountToAmount");
960 Self::process_ui_amount_to_amount(program_id, accounts, ui_amount)
961 }
962 }
963 }
964
965 pub fn check_account_owner(program_id: &Pubkey, account_info: &AccountInfo) -> ProgramResult {
967 if !Self::cmp_pubkeys(program_id, account_info.owner) {
968 Err(ProgramError::IncorrectProgramId)
969 } else {
970 Ok(())
971 }
972 }
973
974 pub fn cmp_pubkeys(a: &Pubkey, b: &Pubkey) -> bool {
977 sol_memcmp(a.as_ref(), b.as_ref(), PUBKEY_BYTES) == 0
978 }
979
980 pub fn validate_owner(
982 program_id: &Pubkey,
983 expected_owner: &Pubkey,
984 owner_account_info: &AccountInfo,
985 signers: &[AccountInfo],
986 ) -> ProgramResult {
987 if !Self::cmp_pubkeys(expected_owner, owner_account_info.key) {
988 return Err(TokenError::OwnerMismatch.into());
989 }
990 if Self::cmp_pubkeys(program_id, owner_account_info.owner)
991 && owner_account_info.data_len() == Multisig::get_packed_len()
992 {
993 let multisig = Multisig::unpack(&owner_account_info.data.borrow())?;
994 let mut num_signers = 0;
995 let mut matched = [false; MAX_SIGNERS];
996 for signer in signers.iter() {
997 for (position, key) in multisig.signers[0..multisig.n as usize].iter().enumerate() {
998 if Self::cmp_pubkeys(key, signer.key) && !matched[position] {
999 if !signer.is_signer {
1000 return Err(ProgramError::MissingRequiredSignature);
1001 }
1002 matched[position] = true;
1003 num_signers += 1;
1004 }
1005 }
1006 }
1007 if num_signers < multisig.m {
1008 return Err(ProgramError::MissingRequiredSignature);
1009 }
1010 return Ok(());
1011 } else if !owner_account_info.is_signer {
1012 return Err(ProgramError::MissingRequiredSignature);
1013 }
1014 Ok(())
1015 }
1016}
1017
1018#[cfg(not(target_os = "solana"))]
1022fn delete_account(account_info: &AccountInfo) -> Result<(), ProgramError> {
1023 account_info.assign(&system_program::id());
1024 let mut account_data = account_info.data.borrow_mut();
1025 let data_len = account_data.len();
1026 miraland_program::program_memory::sol_memset(*account_data, 0, data_len);
1027 Ok(())
1028}
1029
1030#[cfg(target_os = "solana")]
1032fn delete_account(account_info: &AccountInfo) -> Result<(), ProgramError> {
1033 account_info.assign(&system_program::id());
1034 account_info.realloc(0, false)
1035}
1036
1037#[cfg(test)]
1038mod tests {
1039 use {
1040 super::*,
1041 crate::instruction::*,
1042 serial_test::serial,
1043 miraland_program::{
1044 account_info::IntoAccountInfo,
1045 clock::Epoch,
1046 instruction::Instruction,
1047 program_error::{self, PrintProgramError},
1048 sysvar::rent,
1049 },
1050 miraland_sdk::account::{
1051 create_account_for_test, create_is_signer_account_infos, Account as MiralandAccount,
1052 },
1053 std::sync::{Arc, RwLock},
1054 };
1055
1056 lazy_static::lazy_static! {
1057 static ref EXPECTED_DATA: Arc<RwLock<Vec<u8>>> = Arc::new(RwLock::new(Vec::new()));
1058 }
1059
1060 fn set_expected_data(expected_data: Vec<u8>) {
1061 *EXPECTED_DATA.write().unwrap() = expected_data;
1062 }
1063
1064 struct SyscallStubs {}
1065 impl miraland_sdk::program_stubs::SyscallStubs for SyscallStubs {
1066 fn sol_log(&self, _message: &str) {}
1067
1068 fn sol_invoke_signed(
1069 &self,
1070 _instruction: &Instruction,
1071 _account_infos: &[AccountInfo],
1072 _signers_seeds: &[&[&[u8]]],
1073 ) -> ProgramResult {
1074 Err(ProgramError::Custom(42)) }
1076
1077 fn sol_get_clock_sysvar(&self, _var_addr: *mut u8) -> u64 {
1078 program_error::UNSUPPORTED_SYSVAR
1079 }
1080
1081 fn sol_get_epoch_schedule_sysvar(&self, _var_addr: *mut u8) -> u64 {
1082 program_error::UNSUPPORTED_SYSVAR
1083 }
1084
1085 #[allow(deprecated)]
1086 fn sol_get_fees_sysvar(&self, _var_addr: *mut u8) -> u64 {
1087 program_error::UNSUPPORTED_SYSVAR
1088 }
1089
1090 fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 {
1091 unsafe {
1092 *(var_addr as *mut _ as *mut Rent) = Rent::default();
1093 }
1094 miraland_program::entrypoint::SUCCESS
1095 }
1096
1097 fn sol_set_return_data(&self, data: &[u8]) {
1098 assert_eq!(&*EXPECTED_DATA.write().unwrap(), data)
1099 }
1100 }
1101
1102 fn do_process_instruction(
1103 instruction: Instruction,
1104 accounts: Vec<&mut MiralandAccount>,
1105 ) -> ProgramResult {
1106 {
1107 use std::sync::Once;
1108 static ONCE: Once = Once::new();
1109
1110 ONCE.call_once(|| {
1111 miraland_sdk::program_stubs::set_syscall_stubs(Box::new(SyscallStubs {}));
1112 });
1113 }
1114
1115 let mut meta = instruction
1116 .accounts
1117 .iter()
1118 .zip(accounts)
1119 .map(|(account_meta, account)| (&account_meta.pubkey, account_meta.is_signer, account))
1120 .collect::<Vec<_>>();
1121
1122 let account_infos = create_is_signer_account_infos(&mut meta);
1123 Processor::process(&instruction.program_id, &account_infos, &instruction.data)
1124 }
1125
1126 fn do_process_instruction_dups(
1127 instruction: Instruction,
1128 account_infos: Vec<AccountInfo>,
1129 ) -> ProgramResult {
1130 Processor::process(&instruction.program_id, &account_infos, &instruction.data)
1131 }
1132
1133 fn return_token_error_as_program_error() -> ProgramError {
1134 TokenError::MintMismatch.into()
1135 }
1136
1137 fn rent_sysvar() -> MiralandAccount {
1138 create_account_for_test(&Rent::default())
1139 }
1140
1141 fn mint_minimum_balance() -> u64 {
1142 Rent::default().minimum_balance(Mint::get_packed_len())
1143 }
1144
1145 fn account_minimum_balance() -> u64 {
1146 Rent::default().minimum_balance(Account::get_packed_len())
1147 }
1148
1149 fn multisig_minimum_balance() -> u64 {
1150 Rent::default().minimum_balance(Multisig::get_packed_len())
1151 }
1152
1153 #[test]
1154 fn test_print_error() {
1155 let error = return_token_error_as_program_error();
1156 error.print::<TokenError>();
1157 }
1158
1159 #[test]
1160 fn test_error_as_custom() {
1161 assert_eq!(
1162 return_token_error_as_program_error(),
1163 ProgramError::Custom(3)
1164 );
1165 }
1166
1167 #[test]
1168 fn test_unique_account_sizes() {
1169 assert_ne!(Mint::get_packed_len(), 0);
1170 assert_ne!(Mint::get_packed_len(), Account::get_packed_len());
1171 assert_ne!(Mint::get_packed_len(), Multisig::get_packed_len());
1172 assert_ne!(Account::get_packed_len(), 0);
1173 assert_ne!(Account::get_packed_len(), Multisig::get_packed_len());
1174 assert_ne!(Multisig::get_packed_len(), 0);
1175 }
1176
1177 #[test]
1178 fn test_pack_unpack() {
1179 let check = Mint {
1181 mint_authority: COption::Some(Pubkey::new_from_array([1; 32])),
1182 supply: 42,
1183 decimals: 7,
1184 is_initialized: true,
1185 freeze_authority: COption::Some(Pubkey::new_from_array([2; 32])),
1186 };
1187 let mut packed = vec![0; Mint::get_packed_len() + 1];
1188 assert_eq!(
1189 Err(ProgramError::InvalidAccountData),
1190 Mint::pack(check, &mut packed)
1191 );
1192 let mut packed = vec![0; Mint::get_packed_len() - 1];
1193 assert_eq!(
1194 Err(ProgramError::InvalidAccountData),
1195 Mint::pack(check, &mut packed)
1196 );
1197 let mut packed = vec![0; Mint::get_packed_len()];
1198 Mint::pack(check, &mut packed).unwrap();
1199 let expect = vec![
1200 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1201 1, 1, 1, 1, 1, 1, 1, 42, 0, 0, 0, 0, 0, 0, 0, 7, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
1202 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1203 ];
1204 assert_eq!(packed, expect);
1205 let unpacked = Mint::unpack(&packed).unwrap();
1206 assert_eq!(unpacked, check);
1207
1208 let check = Account {
1210 mint: Pubkey::new_from_array([1; 32]),
1211 owner: Pubkey::new_from_array([2; 32]),
1212 amount: 3,
1213 delegate: COption::Some(Pubkey::new_from_array([4; 32])),
1214 state: AccountState::Frozen,
1215 is_native: COption::Some(5),
1216 delegated_amount: 6,
1217 close_authority: COption::Some(Pubkey::new_from_array([7; 32])),
1218 };
1219 let mut packed = vec![0; Account::get_packed_len() + 1];
1220 assert_eq!(
1221 Err(ProgramError::InvalidAccountData),
1222 Account::pack(check, &mut packed)
1223 );
1224 let mut packed = vec![0; Account::get_packed_len() - 1];
1225 assert_eq!(
1226 Err(ProgramError::InvalidAccountData),
1227 Account::pack(check, &mut packed)
1228 );
1229 let mut packed = vec![0; Account::get_packed_len()];
1230 Account::pack(check, &mut packed).unwrap();
1231 let expect = vec![
1232 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1233 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1234 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1235 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 1, 0, 0, 0, 5, 0, 0,
1236 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1237 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1238 ];
1239 assert_eq!(packed, expect);
1240 let unpacked = Account::unpack(&packed).unwrap();
1241 assert_eq!(unpacked, check);
1242
1243 let check = Multisig {
1245 m: 1,
1246 n: 2,
1247 is_initialized: true,
1248 signers: [Pubkey::new_from_array([3; 32]); MAX_SIGNERS],
1249 };
1250 let mut packed = vec![0; Multisig::get_packed_len() + 1];
1251 assert_eq!(
1252 Err(ProgramError::InvalidAccountData),
1253 Multisig::pack(check, &mut packed)
1254 );
1255 let mut packed = vec![0; Multisig::get_packed_len() - 1];
1256 assert_eq!(
1257 Err(ProgramError::InvalidAccountData),
1258 Multisig::pack(check, &mut packed)
1259 );
1260 let mut packed = vec![0; Multisig::get_packed_len()];
1261 Multisig::pack(check, &mut packed).unwrap();
1262 let expect = vec![
1263 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1264 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1265 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1266 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1267 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1268 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1269 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1270 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1271 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1272 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1273 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1274 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1275 3, 3, 3, 3, 3, 3, 3,
1276 ];
1277 assert_eq!(packed, expect);
1278 let unpacked = Multisig::unpack(&packed).unwrap();
1279 assert_eq!(unpacked, check);
1280 }
1281
1282 #[test]
1283 fn test_initialize_mint() {
1284 let program_id = crate::id();
1285 let owner_key = Pubkey::new_unique();
1286 let mint_key = Pubkey::new_unique();
1287 let mut mint_account = MiralandAccount::new(42, Mint::get_packed_len(), &program_id);
1288 let mint2_key = Pubkey::new_unique();
1289 let mut mint2_account =
1290 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1291 let mut rent_sysvar = rent_sysvar();
1292
1293 assert_eq!(
1295 Err(TokenError::NotRentExempt.into()),
1296 do_process_instruction(
1297 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1298 vec![&mut mint_account, &mut rent_sysvar]
1299 )
1300 );
1301
1302 mint_account.lamports = mint_minimum_balance();
1303
1304 do_process_instruction(
1306 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1307 vec![&mut mint_account, &mut rent_sysvar],
1308 )
1309 .unwrap();
1310
1311 assert_eq!(
1313 Err(TokenError::AlreadyInUse.into()),
1314 do_process_instruction(
1315 initialize_mint(&program_id, &mint_key, &owner_key, None, 2,).unwrap(),
1316 vec![&mut mint_account, &mut rent_sysvar]
1317 )
1318 );
1319
1320 do_process_instruction(
1322 initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
1323 vec![&mut mint2_account, &mut rent_sysvar],
1324 )
1325 .unwrap();
1326 let mint = Mint::unpack_unchecked(&mint2_account.data).unwrap();
1327 assert_eq!(mint.freeze_authority, COption::Some(owner_key));
1328 }
1329
1330 #[test]
1331 fn test_initialize_mint2() {
1332 let program_id = crate::id();
1333 let owner_key = Pubkey::new_unique();
1334 let mint_key = Pubkey::new_unique();
1335 let mut mint_account = MiralandAccount::new(42, Mint::get_packed_len(), &program_id);
1336 let mint2_key = Pubkey::new_unique();
1337 let mut mint2_account =
1338 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1339
1340 assert_eq!(
1342 Err(TokenError::NotRentExempt.into()),
1343 do_process_instruction(
1344 initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1345 vec![&mut mint_account]
1346 )
1347 );
1348
1349 mint_account.lamports = mint_minimum_balance();
1350
1351 do_process_instruction(
1353 initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1354 vec![&mut mint_account],
1355 )
1356 .unwrap();
1357
1358 assert_eq!(
1360 Err(TokenError::AlreadyInUse.into()),
1361 do_process_instruction(
1362 initialize_mint2(&program_id, &mint_key, &owner_key, None, 2,).unwrap(),
1363 vec![&mut mint_account]
1364 )
1365 );
1366
1367 do_process_instruction(
1369 initialize_mint2(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
1370 vec![&mut mint2_account],
1371 )
1372 .unwrap();
1373 let mint = Mint::unpack_unchecked(&mint2_account.data).unwrap();
1374 assert_eq!(mint.freeze_authority, COption::Some(owner_key));
1375 }
1376
1377 #[test]
1378 fn test_initialize_mint_account() {
1379 let program_id = crate::id();
1380 let account_key = Pubkey::new_unique();
1381 let mut account_account = MiralandAccount::new(42, Account::get_packed_len(), &program_id);
1382 let owner_key = Pubkey::new_unique();
1383 let mut owner_account = MiralandAccount::default();
1384 let mint_key = Pubkey::new_unique();
1385 let mut mint_account =
1386 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1387 let mut rent_sysvar = rent_sysvar();
1388
1389 assert_eq!(
1391 Err(TokenError::NotRentExempt.into()),
1392 do_process_instruction(
1393 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1394 vec![
1395 &mut account_account,
1396 &mut mint_account,
1397 &mut owner_account,
1398 &mut rent_sysvar
1399 ],
1400 )
1401 );
1402
1403 account_account.lamports = account_minimum_balance();
1404
1405 assert_eq!(
1407 Err(TokenError::InvalidMint.into()),
1408 do_process_instruction(
1409 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1410 vec![
1411 &mut account_account,
1412 &mut mint_account,
1413 &mut owner_account,
1414 &mut rent_sysvar
1415 ],
1416 )
1417 );
1418
1419 do_process_instruction(
1421 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1422 vec![&mut mint_account, &mut rent_sysvar],
1423 )
1424 .unwrap();
1425
1426 let not_program_id = Pubkey::new_unique();
1428 mint_account.owner = not_program_id;
1429 assert_eq!(
1430 Err(ProgramError::IncorrectProgramId),
1431 do_process_instruction(
1432 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1433 vec![
1434 &mut account_account,
1435 &mut mint_account,
1436 &mut owner_account,
1437 &mut rent_sysvar
1438 ],
1439 )
1440 );
1441 mint_account.owner = program_id;
1442
1443 do_process_instruction(
1445 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1446 vec![
1447 &mut account_account,
1448 &mut mint_account,
1449 &mut owner_account,
1450 &mut rent_sysvar,
1451 ],
1452 )
1453 .unwrap();
1454
1455 assert_eq!(
1457 Err(TokenError::AlreadyInUse.into()),
1458 do_process_instruction(
1459 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1460 vec![
1461 &mut account_account,
1462 &mut mint_account,
1463 &mut owner_account,
1464 &mut rent_sysvar
1465 ],
1466 )
1467 );
1468 }
1469
1470 #[test]
1471 fn test_transfer_dups() {
1472 let program_id = crate::id();
1473 let account1_key = Pubkey::new_unique();
1474 let mut account1_account = MiralandAccount::new(
1475 account_minimum_balance(),
1476 Account::get_packed_len(),
1477 &program_id,
1478 );
1479 let mut account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
1480 let account2_key = Pubkey::new_unique();
1481 let mut account2_account = MiralandAccount::new(
1482 account_minimum_balance(),
1483 Account::get_packed_len(),
1484 &program_id,
1485 );
1486 let mut account2_info: AccountInfo = (&account2_key, false, &mut account2_account).into();
1487 let account3_key = Pubkey::new_unique();
1488 let mut account3_account = MiralandAccount::new(
1489 account_minimum_balance(),
1490 Account::get_packed_len(),
1491 &program_id,
1492 );
1493 let account3_info: AccountInfo = (&account3_key, false, &mut account3_account).into();
1494 let account4_key = Pubkey::new_unique();
1495 let mut account4_account = MiralandAccount::new(
1496 account_minimum_balance(),
1497 Account::get_packed_len(),
1498 &program_id,
1499 );
1500 let account4_info: AccountInfo = (&account4_key, true, &mut account4_account).into();
1501 let multisig_key = Pubkey::new_unique();
1502 let mut multisig_account = MiralandAccount::new(
1503 multisig_minimum_balance(),
1504 Multisig::get_packed_len(),
1505 &program_id,
1506 );
1507 let multisig_info: AccountInfo = (&multisig_key, true, &mut multisig_account).into();
1508 let owner_key = Pubkey::new_unique();
1509 let mut owner_account = MiralandAccount::default();
1510 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
1511 let mint_key = Pubkey::new_unique();
1512 let mut mint_account =
1513 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1514 let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
1515 let rent_key = rent::id();
1516 let mut rent_sysvar = rent_sysvar();
1517 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
1518
1519 do_process_instruction_dups(
1521 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1522 vec![mint_info.clone(), rent_info.clone()],
1523 )
1524 .unwrap();
1525
1526 do_process_instruction_dups(
1528 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
1529 vec![
1530 account1_info.clone(),
1531 mint_info.clone(),
1532 account1_info.clone(),
1533 rent_info.clone(),
1534 ],
1535 )
1536 .unwrap();
1537
1538 do_process_instruction_dups(
1540 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
1541 vec![
1542 account2_info.clone(),
1543 mint_info.clone(),
1544 owner_info.clone(),
1545 rent_info.clone(),
1546 ],
1547 )
1548 .unwrap();
1549
1550 do_process_instruction_dups(
1552 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
1553 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
1554 )
1555 .unwrap();
1556
1557 do_process_instruction_dups(
1559 transfer(
1560 &program_id,
1561 &account1_key,
1562 &account2_key,
1563 &account1_key,
1564 &[],
1565 500,
1566 )
1567 .unwrap(),
1568 vec![
1569 account1_info.clone(),
1570 account2_info.clone(),
1571 account1_info.clone(),
1572 ],
1573 )
1574 .unwrap();
1575
1576 do_process_instruction_dups(
1578 transfer_checked(
1579 &program_id,
1580 &account1_key,
1581 &mint_key,
1582 &account2_key,
1583 &account1_key,
1584 &[],
1585 500,
1586 2,
1587 )
1588 .unwrap(),
1589 vec![
1590 account1_info.clone(),
1591 mint_info.clone(),
1592 account2_info.clone(),
1593 account1_info.clone(),
1594 ],
1595 )
1596 .unwrap();
1597
1598 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
1600 account.amount = 1000;
1601 account.delegated_amount = 1000;
1602 account.delegate = COption::Some(account1_key);
1603 account.owner = owner_key;
1604 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
1605
1606 do_process_instruction_dups(
1607 transfer(
1608 &program_id,
1609 &account1_key,
1610 &account2_key,
1611 &account1_key,
1612 &[],
1613 500,
1614 )
1615 .unwrap(),
1616 vec![
1617 account1_info.clone(),
1618 account2_info.clone(),
1619 account1_info.clone(),
1620 ],
1621 )
1622 .unwrap();
1623
1624 do_process_instruction_dups(
1626 transfer_checked(
1627 &program_id,
1628 &account1_key,
1629 &mint_key,
1630 &account2_key,
1631 &account1_key,
1632 &[],
1633 500,
1634 2,
1635 )
1636 .unwrap(),
1637 vec![
1638 account1_info.clone(),
1639 mint_info.clone(),
1640 account2_info.clone(),
1641 account1_info.clone(),
1642 ],
1643 )
1644 .unwrap();
1645
1646 do_process_instruction_dups(
1648 initialize_account(&program_id, &account3_key, &mint_key, &account2_key).unwrap(),
1649 vec![
1650 account3_info.clone(),
1651 mint_info.clone(),
1652 account2_info.clone(),
1653 rent_info.clone(),
1654 ],
1655 )
1656 .unwrap();
1657 do_process_instruction_dups(
1658 mint_to(&program_id, &mint_key, &account3_key, &owner_key, &[], 1000).unwrap(),
1659 vec![mint_info.clone(), account3_info.clone(), owner_info.clone()],
1660 )
1661 .unwrap();
1662
1663 account1_info.is_signer = false;
1664 account2_info.is_signer = true;
1665 do_process_instruction_dups(
1666 transfer(
1667 &program_id,
1668 &account3_key,
1669 &account2_key,
1670 &account2_key,
1671 &[],
1672 500,
1673 )
1674 .unwrap(),
1675 vec![
1676 account3_info.clone(),
1677 account2_info.clone(),
1678 account2_info.clone(),
1679 ],
1680 )
1681 .unwrap();
1682
1683 do_process_instruction_dups(
1685 transfer_checked(
1686 &program_id,
1687 &account3_key,
1688 &mint_key,
1689 &account2_key,
1690 &account2_key,
1691 &[],
1692 500,
1693 2,
1694 )
1695 .unwrap(),
1696 vec![
1697 account3_info.clone(),
1698 mint_info.clone(),
1699 account2_info.clone(),
1700 account2_info.clone(),
1701 ],
1702 )
1703 .unwrap();
1704
1705 do_process_instruction_dups(
1707 initialize_multisig(&program_id, &multisig_key, &[&account4_key], 1).unwrap(),
1708 vec![
1709 multisig_info.clone(),
1710 rent_info.clone(),
1711 account4_info.clone(),
1712 ],
1713 )
1714 .unwrap();
1715
1716 do_process_instruction_dups(
1717 initialize_account(&program_id, &account4_key, &mint_key, &multisig_key).unwrap(),
1718 vec![
1719 account4_info.clone(),
1720 mint_info.clone(),
1721 multisig_info.clone(),
1722 rent_info.clone(),
1723 ],
1724 )
1725 .unwrap();
1726
1727 do_process_instruction_dups(
1728 mint_to(&program_id, &mint_key, &account4_key, &owner_key, &[], 1000).unwrap(),
1729 vec![mint_info.clone(), account4_info.clone(), owner_info.clone()],
1730 )
1731 .unwrap();
1732
1733 do_process_instruction_dups(
1735 transfer(
1736 &program_id,
1737 &account4_key,
1738 &account2_key,
1739 &multisig_key,
1740 &[&account4_key],
1741 500,
1742 )
1743 .unwrap(),
1744 vec![
1745 account4_info.clone(),
1746 account2_info.clone(),
1747 multisig_info.clone(),
1748 account4_info.clone(),
1749 ],
1750 )
1751 .unwrap();
1752
1753 do_process_instruction_dups(
1755 transfer_checked(
1756 &program_id,
1757 &account4_key,
1758 &mint_key,
1759 &account2_key,
1760 &multisig_key,
1761 &[&account4_key],
1762 500,
1763 2,
1764 )
1765 .unwrap(),
1766 vec![
1767 account4_info.clone(),
1768 mint_info.clone(),
1769 account2_info.clone(),
1770 multisig_info.clone(),
1771 account4_info.clone(),
1772 ],
1773 )
1774 .unwrap();
1775 }
1776
1777 #[test]
1778 fn test_transfer() {
1779 let program_id = crate::id();
1780 let account_key = Pubkey::new_unique();
1781 let mut account_account = MiralandAccount::new(
1782 account_minimum_balance(),
1783 Account::get_packed_len(),
1784 &program_id,
1785 );
1786 let account2_key = Pubkey::new_unique();
1787 let mut account2_account = MiralandAccount::new(
1788 account_minimum_balance(),
1789 Account::get_packed_len(),
1790 &program_id,
1791 );
1792 let account3_key = Pubkey::new_unique();
1793 let mut account3_account = MiralandAccount::new(
1794 account_minimum_balance(),
1795 Account::get_packed_len(),
1796 &program_id,
1797 );
1798 let delegate_key = Pubkey::new_unique();
1799 let mut delegate_account = MiralandAccount::default();
1800 let mismatch_key = Pubkey::new_unique();
1801 let mut mismatch_account = MiralandAccount::new(
1802 account_minimum_balance(),
1803 Account::get_packed_len(),
1804 &program_id,
1805 );
1806 let owner_key = Pubkey::new_unique();
1807 let mut owner_account = MiralandAccount::default();
1808 let owner2_key = Pubkey::new_unique();
1809 let mut owner2_account = MiralandAccount::default();
1810 let mint_key = Pubkey::new_unique();
1811 let mut mint_account =
1812 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1813 let mint2_key = Pubkey::new_unique();
1814 let mut rent_sysvar = rent_sysvar();
1815
1816 do_process_instruction(
1818 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1819 vec![&mut mint_account, &mut rent_sysvar],
1820 )
1821 .unwrap();
1822
1823 do_process_instruction(
1825 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1826 vec![
1827 &mut account_account,
1828 &mut mint_account,
1829 &mut owner_account,
1830 &mut rent_sysvar,
1831 ],
1832 )
1833 .unwrap();
1834
1835 do_process_instruction(
1837 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
1838 vec![
1839 &mut account2_account,
1840 &mut mint_account,
1841 &mut owner_account,
1842 &mut rent_sysvar,
1843 ],
1844 )
1845 .unwrap();
1846
1847 do_process_instruction(
1849 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
1850 vec![
1851 &mut account3_account,
1852 &mut mint_account,
1853 &mut owner_account,
1854 &mut rent_sysvar,
1855 ],
1856 )
1857 .unwrap();
1858
1859 do_process_instruction(
1861 initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
1862 vec![
1863 &mut mismatch_account,
1864 &mut mint_account,
1865 &mut owner_account,
1866 &mut rent_sysvar,
1867 ],
1868 )
1869 .unwrap();
1870 let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
1871 account.mint = mint2_key;
1872 Account::pack(account, &mut mismatch_account.data).unwrap();
1873
1874 do_process_instruction(
1876 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
1877 vec![&mut mint_account, &mut account_account, &mut owner_account],
1878 )
1879 .unwrap();
1880
1881 let mut instruction = transfer(
1883 &program_id,
1884 &account_key,
1885 &account2_key,
1886 &owner_key,
1887 &[],
1888 1000,
1889 )
1890 .unwrap();
1891 instruction.accounts[2].is_signer = false;
1892 assert_eq!(
1893 Err(ProgramError::MissingRequiredSignature),
1894 do_process_instruction(
1895 instruction,
1896 vec![
1897 &mut account_account,
1898 &mut account2_account,
1899 &mut owner_account,
1900 ],
1901 )
1902 );
1903
1904 assert_eq!(
1906 Err(TokenError::MintMismatch.into()),
1907 do_process_instruction(
1908 transfer(
1909 &program_id,
1910 &account_key,
1911 &mismatch_key,
1912 &owner_key,
1913 &[],
1914 1000
1915 )
1916 .unwrap(),
1917 vec![
1918 &mut account_account,
1919 &mut mismatch_account,
1920 &mut owner_account,
1921 ],
1922 )
1923 );
1924
1925 assert_eq!(
1927 Err(TokenError::OwnerMismatch.into()),
1928 do_process_instruction(
1929 transfer(
1930 &program_id,
1931 &account_key,
1932 &account2_key,
1933 &owner2_key,
1934 &[],
1935 1000
1936 )
1937 .unwrap(),
1938 vec![
1939 &mut account_account,
1940 &mut account2_account,
1941 &mut owner2_account,
1942 ],
1943 )
1944 );
1945
1946 let not_program_id = Pubkey::new_unique();
1948 account_account.owner = not_program_id;
1949 assert_eq!(
1950 Err(ProgramError::IncorrectProgramId),
1951 do_process_instruction(
1952 transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 0,).unwrap(),
1953 vec![
1954 &mut account_account,
1955 &mut account2_account,
1956 &mut owner2_account,
1957 ],
1958 )
1959 );
1960 account_account.owner = program_id;
1961
1962 let not_program_id = Pubkey::new_unique();
1964 account2_account.owner = not_program_id;
1965 assert_eq!(
1966 Err(ProgramError::IncorrectProgramId),
1967 do_process_instruction(
1968 transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 0,).unwrap(),
1969 vec![
1970 &mut account_account,
1971 &mut account2_account,
1972 &mut owner2_account,
1973 ],
1974 )
1975 );
1976 account2_account.owner = program_id;
1977
1978 do_process_instruction(
1980 transfer(
1981 &program_id,
1982 &account_key,
1983 &account2_key,
1984 &owner_key,
1985 &[],
1986 1000,
1987 )
1988 .unwrap(),
1989 vec![
1990 &mut account_account,
1991 &mut account2_account,
1992 &mut owner_account,
1993 ],
1994 )
1995 .unwrap();
1996
1997 assert_eq!(
1999 Err(TokenError::InsufficientFunds.into()),
2000 do_process_instruction(
2001 transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 1).unwrap(),
2002 vec![
2003 &mut account_account,
2004 &mut account2_account,
2005 &mut owner_account,
2006 ],
2007 )
2008 );
2009
2010 do_process_instruction(
2012 transfer(
2013 &program_id,
2014 &account2_key,
2015 &account_key,
2016 &owner_key,
2017 &[],
2018 500,
2019 )
2020 .unwrap(),
2021 vec![
2022 &mut account2_account,
2023 &mut account_account,
2024 &mut owner_account,
2025 ],
2026 )
2027 .unwrap();
2028
2029 assert_eq!(
2031 Err(TokenError::MintDecimalsMismatch.into()),
2032 do_process_instruction(
2033 transfer_checked(
2034 &program_id,
2035 &account2_key,
2036 &mint_key,
2037 &account_key,
2038 &owner_key,
2039 &[],
2040 1,
2041 10 )
2043 .unwrap(),
2044 vec![
2045 &mut account2_account,
2046 &mut mint_account,
2047 &mut account_account,
2048 &mut owner_account,
2049 ],
2050 )
2051 );
2052
2053 assert_eq!(
2055 Err(TokenError::MintMismatch.into()),
2056 do_process_instruction(
2057 transfer_checked(
2058 &program_id,
2059 &account2_key,
2060 &account3_key, &account_key,
2062 &owner_key,
2063 &[],
2064 1,
2065 2
2066 )
2067 .unwrap(),
2068 vec![
2069 &mut account2_account,
2070 &mut account3_account, &mut account_account,
2072 &mut owner_account,
2073 ],
2074 )
2075 );
2076 do_process_instruction(
2078 transfer_checked(
2079 &program_id,
2080 &account2_key,
2081 &mint_key,
2082 &account_key,
2083 &owner_key,
2084 &[],
2085 500,
2086 2,
2087 )
2088 .unwrap(),
2089 vec![
2090 &mut account2_account,
2091 &mut mint_account,
2092 &mut account_account,
2093 &mut owner_account,
2094 ],
2095 )
2096 .unwrap();
2097
2098 assert_eq!(
2100 Err(TokenError::InsufficientFunds.into()),
2101 do_process_instruction(
2102 transfer(&program_id, &account2_key, &account_key, &owner_key, &[], 1).unwrap(),
2103 vec![
2104 &mut account2_account,
2105 &mut account_account,
2106 &mut owner_account,
2107 ],
2108 )
2109 );
2110
2111 do_process_instruction(
2113 approve(
2114 &program_id,
2115 &account_key,
2116 &delegate_key,
2117 &owner_key,
2118 &[],
2119 100,
2120 )
2121 .unwrap(),
2122 vec![
2123 &mut account_account,
2124 &mut delegate_account,
2125 &mut owner_account,
2126 ],
2127 )
2128 .unwrap();
2129
2130 assert_eq!(
2132 Err(TokenError::OwnerMismatch.into()),
2133 do_process_instruction(
2134 transfer(
2135 &program_id,
2136 &account_key,
2137 &account2_key,
2138 &owner2_key, &[],
2140 1,
2141 )
2142 .unwrap(),
2143 vec![
2144 &mut account_account,
2145 &mut account2_account,
2146 &mut owner2_account,
2147 ],
2148 )
2149 );
2150
2151 assert_eq!(
2153 Err(TokenError::InsufficientFunds.into()),
2154 do_process_instruction(
2155 transfer(
2156 &program_id,
2157 &account_key,
2158 &account2_key,
2159 &delegate_key,
2160 &[],
2161 101
2162 )
2163 .unwrap(),
2164 vec![
2165 &mut account_account,
2166 &mut account2_account,
2167 &mut delegate_account,
2168 ],
2169 )
2170 );
2171
2172 do_process_instruction(
2174 transfer(
2175 &program_id,
2176 &account_key,
2177 &account2_key,
2178 &delegate_key,
2179 &[],
2180 100,
2181 )
2182 .unwrap(),
2183 vec![
2184 &mut account_account,
2185 &mut account2_account,
2186 &mut delegate_account,
2187 ],
2188 )
2189 .unwrap();
2190
2191 assert_eq!(
2193 Err(TokenError::OwnerMismatch.into()),
2194 do_process_instruction(
2195 transfer(
2196 &program_id,
2197 &account_key,
2198 &account2_key,
2199 &delegate_key,
2200 &[],
2201 1
2202 )
2203 .unwrap(),
2204 vec![
2205 &mut account_account,
2206 &mut account2_account,
2207 &mut delegate_account,
2208 ],
2209 )
2210 );
2211
2212 do_process_instruction(
2214 transfer(
2215 &program_id,
2216 &account_key,
2217 &account2_key,
2218 &owner_key,
2219 &[],
2220 900,
2221 )
2222 .unwrap(),
2223 vec![
2224 &mut account_account,
2225 &mut account2_account,
2226 &mut owner_account,
2227 ],
2228 )
2229 .unwrap();
2230
2231 do_process_instruction(
2233 approve(
2234 &program_id,
2235 &account_key,
2236 &delegate_key,
2237 &owner_key,
2238 &[],
2239 100,
2240 )
2241 .unwrap(),
2242 vec![
2243 &mut account_account,
2244 &mut delegate_account,
2245 &mut owner_account,
2246 ],
2247 )
2248 .unwrap();
2249
2250 assert_eq!(
2252 Err(TokenError::InsufficientFunds.into()),
2253 do_process_instruction(
2254 transfer(
2255 &program_id,
2256 &account_key,
2257 &account2_key,
2258 &delegate_key,
2259 &[],
2260 100
2261 )
2262 .unwrap(),
2263 vec![
2264 &mut account_account,
2265 &mut account2_account,
2266 &mut delegate_account,
2267 ],
2268 )
2269 );
2270 }
2271
2272 #[test]
2273 fn test_self_transfer() {
2274 let program_id = crate::id();
2275 let account_key = Pubkey::new_unique();
2276 let mut account_account = MiralandAccount::new(
2277 account_minimum_balance(),
2278 Account::get_packed_len(),
2279 &program_id,
2280 );
2281 let account2_key = Pubkey::new_unique();
2282 let mut account2_account = MiralandAccount::new(
2283 account_minimum_balance(),
2284 Account::get_packed_len(),
2285 &program_id,
2286 );
2287 let account3_key = Pubkey::new_unique();
2288 let mut account3_account = MiralandAccount::new(
2289 account_minimum_balance(),
2290 Account::get_packed_len(),
2291 &program_id,
2292 );
2293 let delegate_key = Pubkey::new_unique();
2294 let mut delegate_account = MiralandAccount::default();
2295 let owner_key = Pubkey::new_unique();
2296 let mut owner_account = MiralandAccount::default();
2297 let owner2_key = Pubkey::new_unique();
2298 let mut owner2_account = MiralandAccount::default();
2299 let mint_key = Pubkey::new_unique();
2300 let mut mint_account =
2301 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
2302 let mut rent_sysvar = rent_sysvar();
2303
2304 do_process_instruction(
2306 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
2307 vec![&mut mint_account, &mut rent_sysvar],
2308 )
2309 .unwrap();
2310
2311 do_process_instruction(
2313 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
2314 vec![
2315 &mut account_account,
2316 &mut mint_account,
2317 &mut owner_account,
2318 &mut rent_sysvar,
2319 ],
2320 )
2321 .unwrap();
2322
2323 do_process_instruction(
2325 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
2326 vec![
2327 &mut account2_account,
2328 &mut mint_account,
2329 &mut owner_account,
2330 &mut rent_sysvar,
2331 ],
2332 )
2333 .unwrap();
2334
2335 do_process_instruction(
2337 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
2338 vec![
2339 &mut account3_account,
2340 &mut mint_account,
2341 &mut owner_account,
2342 &mut rent_sysvar,
2343 ],
2344 )
2345 .unwrap();
2346
2347 do_process_instruction(
2349 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
2350 vec![&mut mint_account, &mut account_account, &mut owner_account],
2351 )
2352 .unwrap();
2353
2354 let account_info = (&account_key, false, &mut account_account).into_account_info();
2355 let account3_info = (&account3_key, false, &mut account3_account).into_account_info();
2356 let delegate_info = (&delegate_key, true, &mut delegate_account).into_account_info();
2357 let owner_info = (&owner_key, true, &mut owner_account).into_account_info();
2358 let owner2_info = (&owner2_key, true, &mut owner2_account).into_account_info();
2359 let mint_info = (&mint_key, false, &mut mint_account).into_account_info();
2360
2361 let instruction = transfer(
2363 &program_id,
2364 account_info.key,
2365 account_info.key,
2366 owner_info.key,
2367 &[],
2368 1000,
2369 )
2370 .unwrap();
2371 assert_eq!(
2372 Ok(()),
2373 Processor::process(
2374 &instruction.program_id,
2375 &[
2376 account_info.clone(),
2377 account_info.clone(),
2378 owner_info.clone(),
2379 ],
2380 &instruction.data,
2381 )
2382 );
2383 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2385 assert_eq!(account.amount, 1000);
2386
2387 let instruction = transfer_checked(
2389 &program_id,
2390 account_info.key,
2391 mint_info.key,
2392 account_info.key,
2393 owner_info.key,
2394 &[],
2395 1000,
2396 2,
2397 )
2398 .unwrap();
2399 assert_eq!(
2400 Ok(()),
2401 Processor::process(
2402 &instruction.program_id,
2403 &[
2404 account_info.clone(),
2405 mint_info.clone(),
2406 account_info.clone(),
2407 owner_info.clone(),
2408 ],
2409 &instruction.data,
2410 )
2411 );
2412 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2414 assert_eq!(account.amount, 1000);
2415
2416 let mut owner_no_sign_info = owner_info.clone();
2418 let mut instruction = transfer(
2419 &program_id,
2420 account_info.key,
2421 account_info.key,
2422 owner_no_sign_info.key,
2423 &[],
2424 1000,
2425 )
2426 .unwrap();
2427 instruction.accounts[2].is_signer = false;
2428 owner_no_sign_info.is_signer = false;
2429 assert_eq!(
2430 Err(ProgramError::MissingRequiredSignature),
2431 Processor::process(
2432 &instruction.program_id,
2433 &[
2434 account_info.clone(),
2435 account_info.clone(),
2436 owner_no_sign_info.clone(),
2437 ],
2438 &instruction.data,
2439 )
2440 );
2441
2442 let mut instruction = transfer_checked(
2444 &program_id,
2445 account_info.key,
2446 mint_info.key,
2447 account_info.key,
2448 owner_no_sign_info.key,
2449 &[],
2450 1000,
2451 2,
2452 )
2453 .unwrap();
2454 instruction.accounts[3].is_signer = false;
2455 assert_eq!(
2456 Err(ProgramError::MissingRequiredSignature),
2457 Processor::process(
2458 &instruction.program_id,
2459 &[
2460 account_info.clone(),
2461 mint_info.clone(),
2462 account_info.clone(),
2463 owner_no_sign_info,
2464 ],
2465 &instruction.data,
2466 )
2467 );
2468
2469 let instruction = transfer(
2471 &program_id,
2472 account_info.key,
2473 account_info.key,
2474 owner2_info.key,
2475 &[],
2476 1000,
2477 )
2478 .unwrap();
2479 assert_eq!(
2480 Err(TokenError::OwnerMismatch.into()),
2481 Processor::process(
2482 &instruction.program_id,
2483 &[
2484 account_info.clone(),
2485 account_info.clone(),
2486 owner2_info.clone(),
2487 ],
2488 &instruction.data,
2489 )
2490 );
2491
2492 let instruction = transfer_checked(
2494 &program_id,
2495 account_info.key,
2496 mint_info.key,
2497 account_info.key,
2498 owner2_info.key,
2499 &[],
2500 1000,
2501 2,
2502 )
2503 .unwrap();
2504 assert_eq!(
2505 Err(TokenError::OwnerMismatch.into()),
2506 Processor::process(
2507 &instruction.program_id,
2508 &[
2509 account_info.clone(),
2510 mint_info.clone(),
2511 account_info.clone(),
2512 owner2_info.clone(),
2513 ],
2514 &instruction.data,
2515 )
2516 );
2517
2518 let instruction = transfer(
2520 &program_id,
2521 account_info.key,
2522 account_info.key,
2523 owner_info.key,
2524 &[],
2525 1001,
2526 )
2527 .unwrap();
2528 assert_eq!(
2529 Err(TokenError::InsufficientFunds.into()),
2530 Processor::process(
2531 &instruction.program_id,
2532 &[
2533 account_info.clone(),
2534 account_info.clone(),
2535 owner_info.clone(),
2536 ],
2537 &instruction.data,
2538 )
2539 );
2540
2541 let instruction = transfer_checked(
2543 &program_id,
2544 account_info.key,
2545 mint_info.key,
2546 account_info.key,
2547 owner_info.key,
2548 &[],
2549 1001,
2550 2,
2551 )
2552 .unwrap();
2553 assert_eq!(
2554 Err(TokenError::InsufficientFunds.into()),
2555 Processor::process(
2556 &instruction.program_id,
2557 &[
2558 account_info.clone(),
2559 mint_info.clone(),
2560 account_info.clone(),
2561 owner_info.clone(),
2562 ],
2563 &instruction.data,
2564 )
2565 );
2566
2567 let instruction = transfer_checked(
2569 &program_id,
2570 account_info.key,
2571 mint_info.key,
2572 account_info.key,
2573 owner_info.key,
2574 &[],
2575 1,
2576 10, )
2578 .unwrap();
2579 assert_eq!(
2580 Err(TokenError::MintDecimalsMismatch.into()),
2581 Processor::process(
2582 &instruction.program_id,
2583 &[
2584 account_info.clone(),
2585 mint_info.clone(),
2586 account_info.clone(),
2587 owner_info.clone(),
2588 ],
2589 &instruction.data,
2590 )
2591 );
2592
2593 let instruction = transfer_checked(
2595 &program_id,
2596 account_info.key,
2597 account3_info.key, account_info.key,
2599 owner_info.key,
2600 &[],
2601 1,
2602 2,
2603 )
2604 .unwrap();
2605 assert_eq!(
2606 Err(TokenError::MintMismatch.into()),
2607 Processor::process(
2608 &instruction.program_id,
2609 &[
2610 account_info.clone(),
2611 account3_info.clone(), account_info.clone(),
2613 owner_info.clone(),
2614 ],
2615 &instruction.data,
2616 )
2617 );
2618
2619 let instruction = approve(
2621 &program_id,
2622 account_info.key,
2623 delegate_info.key,
2624 owner_info.key,
2625 &[],
2626 100,
2627 )
2628 .unwrap();
2629 Processor::process(
2630 &instruction.program_id,
2631 &[
2632 account_info.clone(),
2633 delegate_info.clone(),
2634 owner_info.clone(),
2635 ],
2636 &instruction.data,
2637 )
2638 .unwrap();
2639
2640 let instruction = transfer(
2642 &program_id,
2643 account_info.key,
2644 account_info.key,
2645 delegate_info.key,
2646 &[],
2647 100,
2648 )
2649 .unwrap();
2650 assert_eq!(
2651 Ok(()),
2652 Processor::process(
2653 &instruction.program_id,
2654 &[
2655 account_info.clone(),
2656 account_info.clone(),
2657 delegate_info.clone(),
2658 ],
2659 &instruction.data,
2660 )
2661 );
2662 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2664 assert_eq!(account.amount, 1000);
2665 assert_eq!(account.delegated_amount, 100);
2666
2667 let instruction = transfer_checked(
2669 &program_id,
2670 account_info.key,
2671 mint_info.key,
2672 account_info.key,
2673 delegate_info.key,
2674 &[],
2675 100,
2676 2,
2677 )
2678 .unwrap();
2679 assert_eq!(
2680 Ok(()),
2681 Processor::process(
2682 &instruction.program_id,
2683 &[
2684 account_info.clone(),
2685 mint_info.clone(),
2686 account_info.clone(),
2687 delegate_info.clone(),
2688 ],
2689 &instruction.data,
2690 )
2691 );
2692 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2694 assert_eq!(account.amount, 1000);
2695 assert_eq!(account.delegated_amount, 100);
2696
2697 let instruction = transfer(
2699 &program_id,
2700 account_info.key,
2701 account_info.key,
2702 delegate_info.key,
2703 &[],
2704 101,
2705 )
2706 .unwrap();
2707 assert_eq!(
2708 Err(TokenError::InsufficientFunds.into()),
2709 Processor::process(
2710 &instruction.program_id,
2711 &[
2712 account_info.clone(),
2713 account_info.clone(),
2714 delegate_info.clone(),
2715 ],
2716 &instruction.data,
2717 )
2718 );
2719
2720 let instruction = transfer_checked(
2722 &program_id,
2723 account_info.key,
2724 mint_info.key,
2725 account_info.key,
2726 delegate_info.key,
2727 &[],
2728 101,
2729 2,
2730 )
2731 .unwrap();
2732 assert_eq!(
2733 Err(TokenError::InsufficientFunds.into()),
2734 Processor::process(
2735 &instruction.program_id,
2736 &[
2737 account_info.clone(),
2738 mint_info.clone(),
2739 account_info.clone(),
2740 delegate_info.clone(),
2741 ],
2742 &instruction.data,
2743 )
2744 );
2745
2746 let instruction = transfer(
2748 &program_id,
2749 account_info.key,
2750 account_info.key,
2751 owner_info.key,
2752 &[],
2753 1000,
2754 )
2755 .unwrap();
2756 assert_eq!(
2757 Ok(()),
2758 Processor::process(
2759 &instruction.program_id,
2760 &[
2761 account_info.clone(),
2762 account_info.clone(),
2763 owner_info.clone(),
2764 ],
2765 &instruction.data,
2766 )
2767 );
2768 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2770 assert_eq!(account.amount, 1000);
2771
2772 let instruction = transfer_checked(
2774 &program_id,
2775 account_info.key,
2776 mint_info.key,
2777 account_info.key,
2778 owner_info.key,
2779 &[],
2780 1000,
2781 2,
2782 )
2783 .unwrap();
2784 assert_eq!(
2785 Ok(()),
2786 Processor::process(
2787 &instruction.program_id,
2788 &[
2789 account_info.clone(),
2790 mint_info.clone(),
2791 account_info.clone(),
2792 owner_info.clone(),
2793 ],
2794 &instruction.data,
2795 )
2796 );
2797 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2799 assert_eq!(account.amount, 1000);
2800 }
2801
2802 #[test]
2803 fn test_mintable_token_with_zero_supply() {
2804 let program_id = crate::id();
2805 let account_key = Pubkey::new_unique();
2806 let mut account_account = MiralandAccount::new(
2807 account_minimum_balance(),
2808 Account::get_packed_len(),
2809 &program_id,
2810 );
2811 let owner_key = Pubkey::new_unique();
2812 let mut owner_account = MiralandAccount::default();
2813 let mint_key = Pubkey::new_unique();
2814 let mut mint_account =
2815 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
2816 let mut rent_sysvar = rent_sysvar();
2817
2818 let decimals = 2;
2820 do_process_instruction(
2821 initialize_mint(&program_id, &mint_key, &owner_key, None, decimals).unwrap(),
2822 vec![&mut mint_account, &mut rent_sysvar],
2823 )
2824 .unwrap();
2825 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
2826 assert_eq!(
2827 mint,
2828 Mint {
2829 mint_authority: COption::Some(owner_key),
2830 supply: 0,
2831 decimals,
2832 is_initialized: true,
2833 freeze_authority: COption::None,
2834 }
2835 );
2836
2837 do_process_instruction(
2839 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
2840 vec![
2841 &mut account_account,
2842 &mut mint_account,
2843 &mut owner_account,
2844 &mut rent_sysvar,
2845 ],
2846 )
2847 .unwrap();
2848
2849 do_process_instruction(
2851 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
2852 vec![&mut mint_account, &mut account_account, &mut owner_account],
2853 )
2854 .unwrap();
2855 let _ = Mint::unpack(&mint_account.data).unwrap();
2856 let account = Account::unpack_unchecked(&account_account.data).unwrap();
2857 assert_eq!(account.amount, 42);
2858
2859 assert_eq!(
2861 Err(TokenError::MintDecimalsMismatch.into()),
2862 do_process_instruction(
2863 mint_to_checked(
2864 &program_id,
2865 &mint_key,
2866 &account_key,
2867 &owner_key,
2868 &[],
2869 42,
2870 decimals + 1
2871 )
2872 .unwrap(),
2873 vec![&mut mint_account, &mut account_account, &mut owner_account],
2874 )
2875 );
2876
2877 let _ = Mint::unpack(&mint_account.data).unwrap();
2878 let account = Account::unpack_unchecked(&account_account.data).unwrap();
2879 assert_eq!(account.amount, 42);
2880
2881 do_process_instruction(
2883 mint_to_checked(
2884 &program_id,
2885 &mint_key,
2886 &account_key,
2887 &owner_key,
2888 &[],
2889 42,
2890 decimals,
2891 )
2892 .unwrap(),
2893 vec![&mut mint_account, &mut account_account, &mut owner_account],
2894 )
2895 .unwrap();
2896 let _ = Mint::unpack(&mint_account.data).unwrap();
2897 let account = Account::unpack_unchecked(&account_account.data).unwrap();
2898 assert_eq!(account.amount, 84);
2899 }
2900
2901 #[test]
2902 fn test_approve_dups() {
2903 let program_id = crate::id();
2904 let account1_key = Pubkey::new_unique();
2905 let mut account1_account = MiralandAccount::new(
2906 account_minimum_balance(),
2907 Account::get_packed_len(),
2908 &program_id,
2909 );
2910 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
2911 let account2_key = Pubkey::new_unique();
2912 let mut account2_account = MiralandAccount::new(
2913 account_minimum_balance(),
2914 Account::get_packed_len(),
2915 &program_id,
2916 );
2917 let account2_info: AccountInfo = (&account2_key, false, &mut account2_account).into();
2918 let account3_key = Pubkey::new_unique();
2919 let mut account3_account = MiralandAccount::new(
2920 account_minimum_balance(),
2921 Account::get_packed_len(),
2922 &program_id,
2923 );
2924 let account3_info: AccountInfo = (&account3_key, true, &mut account3_account).into();
2925 let multisig_key = Pubkey::new_unique();
2926 let mut multisig_account = MiralandAccount::new(
2927 multisig_minimum_balance(),
2928 Multisig::get_packed_len(),
2929 &program_id,
2930 );
2931 let multisig_info: AccountInfo = (&multisig_key, true, &mut multisig_account).into();
2932 let owner_key = Pubkey::new_unique();
2933 let mut owner_account = MiralandAccount::default();
2934 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
2935 let mint_key = Pubkey::new_unique();
2936 let mut mint_account =
2937 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
2938 let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
2939 let rent_key = rent::id();
2940 let mut rent_sysvar = rent_sysvar();
2941 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
2942
2943 do_process_instruction_dups(
2945 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
2946 vec![mint_info.clone(), rent_info.clone()],
2947 )
2948 .unwrap();
2949
2950 do_process_instruction_dups(
2952 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
2953 vec![
2954 account1_info.clone(),
2955 mint_info.clone(),
2956 account1_info.clone(),
2957 rent_info.clone(),
2958 ],
2959 )
2960 .unwrap();
2961
2962 do_process_instruction_dups(
2964 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
2965 vec![
2966 account2_info.clone(),
2967 mint_info.clone(),
2968 owner_info.clone(),
2969 rent_info.clone(),
2970 ],
2971 )
2972 .unwrap();
2973
2974 do_process_instruction_dups(
2976 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
2977 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
2978 )
2979 .unwrap();
2980
2981 do_process_instruction_dups(
2983 approve(
2984 &program_id,
2985 &account1_key,
2986 &account2_key,
2987 &account1_key,
2988 &[],
2989 500,
2990 )
2991 .unwrap(),
2992 vec![
2993 account1_info.clone(),
2994 account2_info.clone(),
2995 account1_info.clone(),
2996 ],
2997 )
2998 .unwrap();
2999
3000 do_process_instruction_dups(
3002 approve_checked(
3003 &program_id,
3004 &account1_key,
3005 &mint_key,
3006 &account2_key,
3007 &account1_key,
3008 &[],
3009 500,
3010 2,
3011 )
3012 .unwrap(),
3013 vec![
3014 account1_info.clone(),
3015 mint_info.clone(),
3016 account2_info.clone(),
3017 account1_info.clone(),
3018 ],
3019 )
3020 .unwrap();
3021
3022 do_process_instruction_dups(
3024 revoke(&program_id, &account1_key, &account1_key, &[]).unwrap(),
3025 vec![account1_info.clone(), account1_info.clone()],
3026 )
3027 .unwrap();
3028
3029 do_process_instruction_dups(
3031 initialize_multisig(&program_id, &multisig_key, &[&account3_key], 1).unwrap(),
3032 vec![
3033 multisig_info.clone(),
3034 rent_info.clone(),
3035 account3_info.clone(),
3036 ],
3037 )
3038 .unwrap();
3039
3040 do_process_instruction_dups(
3041 initialize_account(&program_id, &account3_key, &mint_key, &multisig_key).unwrap(),
3042 vec![
3043 account3_info.clone(),
3044 mint_info.clone(),
3045 multisig_info.clone(),
3046 rent_info.clone(),
3047 ],
3048 )
3049 .unwrap();
3050
3051 do_process_instruction_dups(
3052 mint_to(&program_id, &mint_key, &account3_key, &owner_key, &[], 1000).unwrap(),
3053 vec![mint_info.clone(), account3_info.clone(), owner_info.clone()],
3054 )
3055 .unwrap();
3056
3057 do_process_instruction_dups(
3059 approve(
3060 &program_id,
3061 &account3_key,
3062 &account2_key,
3063 &multisig_key,
3064 &[&account3_key],
3065 500,
3066 )
3067 .unwrap(),
3068 vec![
3069 account3_info.clone(),
3070 account2_info.clone(),
3071 multisig_info.clone(),
3072 account3_info.clone(),
3073 ],
3074 )
3075 .unwrap();
3076
3077 do_process_instruction_dups(
3079 approve_checked(
3080 &program_id,
3081 &account3_key,
3082 &mint_key,
3083 &account2_key,
3084 &multisig_key,
3085 &[&account3_key],
3086 500,
3087 2,
3088 )
3089 .unwrap(),
3090 vec![
3091 account3_info.clone(),
3092 mint_info.clone(),
3093 account2_info.clone(),
3094 multisig_info.clone(),
3095 account3_info.clone(),
3096 ],
3097 )
3098 .unwrap();
3099
3100 do_process_instruction_dups(
3102 revoke(&program_id, &account3_key, &multisig_key, &[&account3_key]).unwrap(),
3103 vec![
3104 account3_info.clone(),
3105 multisig_info.clone(),
3106 account3_info.clone(),
3107 ],
3108 )
3109 .unwrap();
3110 }
3111
3112 #[test]
3113 fn test_approve() {
3114 let program_id = crate::id();
3115 let account_key = Pubkey::new_unique();
3116 let mut account_account = MiralandAccount::new(
3117 account_minimum_balance(),
3118 Account::get_packed_len(),
3119 &program_id,
3120 );
3121 let account2_key = Pubkey::new_unique();
3122 let mut account2_account = MiralandAccount::new(
3123 account_minimum_balance(),
3124 Account::get_packed_len(),
3125 &program_id,
3126 );
3127 let delegate_key = Pubkey::new_unique();
3128 let mut delegate_account = MiralandAccount::default();
3129 let owner_key = Pubkey::new_unique();
3130 let mut owner_account = MiralandAccount::default();
3131 let owner2_key = Pubkey::new_unique();
3132 let mut owner2_account = MiralandAccount::default();
3133 let mint_key = Pubkey::new_unique();
3134 let mut mint_account =
3135 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3136 let mut rent_sysvar = rent_sysvar();
3137
3138 do_process_instruction(
3140 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
3141 vec![&mut mint_account, &mut rent_sysvar],
3142 )
3143 .unwrap();
3144
3145 do_process_instruction(
3147 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
3148 vec![
3149 &mut account_account,
3150 &mut mint_account,
3151 &mut owner_account,
3152 &mut rent_sysvar,
3153 ],
3154 )
3155 .unwrap();
3156
3157 do_process_instruction(
3159 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
3160 vec![
3161 &mut account2_account,
3162 &mut mint_account,
3163 &mut owner_account,
3164 &mut rent_sysvar,
3165 ],
3166 )
3167 .unwrap();
3168
3169 do_process_instruction(
3171 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
3172 vec![&mut mint_account, &mut account_account, &mut owner_account],
3173 )
3174 .unwrap();
3175
3176 let mut instruction = approve(
3178 &program_id,
3179 &account_key,
3180 &delegate_key,
3181 &owner_key,
3182 &[],
3183 100,
3184 )
3185 .unwrap();
3186 instruction.accounts[2].is_signer = false;
3187 assert_eq!(
3188 Err(ProgramError::MissingRequiredSignature),
3189 do_process_instruction(
3190 instruction,
3191 vec![
3192 &mut account_account,
3193 &mut delegate_account,
3194 &mut owner_account,
3195 ],
3196 )
3197 );
3198
3199 assert_eq!(
3201 Err(TokenError::OwnerMismatch.into()),
3202 do_process_instruction(
3203 approve(
3204 &program_id,
3205 &account_key,
3206 &delegate_key,
3207 &owner2_key,
3208 &[],
3209 100
3210 )
3211 .unwrap(),
3212 vec![
3213 &mut account_account,
3214 &mut delegate_account,
3215 &mut owner2_account,
3216 ],
3217 )
3218 );
3219
3220 do_process_instruction(
3222 approve(
3223 &program_id,
3224 &account_key,
3225 &delegate_key,
3226 &owner_key,
3227 &[],
3228 100,
3229 )
3230 .unwrap(),
3231 vec![
3232 &mut account_account,
3233 &mut delegate_account,
3234 &mut owner_account,
3235 ],
3236 )
3237 .unwrap();
3238
3239 assert_eq!(
3241 Err(TokenError::MintDecimalsMismatch.into()),
3242 do_process_instruction(
3243 approve_checked(
3244 &program_id,
3245 &account_key,
3246 &mint_key,
3247 &delegate_key,
3248 &owner_key,
3249 &[],
3250 100,
3251 0 )
3253 .unwrap(),
3254 vec![
3255 &mut account_account,
3256 &mut mint_account,
3257 &mut delegate_account,
3258 &mut owner_account,
3259 ],
3260 )
3261 );
3262
3263 assert_eq!(
3265 Err(TokenError::MintMismatch.into()),
3266 do_process_instruction(
3267 approve_checked(
3268 &program_id,
3269 &account_key,
3270 &account2_key, &delegate_key,
3272 &owner_key,
3273 &[],
3274 100,
3275 0
3276 )
3277 .unwrap(),
3278 vec![
3279 &mut account_account,
3280 &mut account2_account, &mut delegate_account,
3282 &mut owner_account,
3283 ],
3284 )
3285 );
3286
3287 do_process_instruction(
3289 approve_checked(
3290 &program_id,
3291 &account_key,
3292 &mint_key,
3293 &delegate_key,
3294 &owner_key,
3295 &[],
3296 100,
3297 2,
3298 )
3299 .unwrap(),
3300 vec![
3301 &mut account_account,
3302 &mut mint_account,
3303 &mut delegate_account,
3304 &mut owner_account,
3305 ],
3306 )
3307 .unwrap();
3308
3309 do_process_instruction(
3311 revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
3312 vec![&mut account_account, &mut owner_account],
3313 )
3314 .unwrap();
3315 }
3316
3317 #[test]
3318 fn test_set_authority_dups() {
3319 let program_id = crate::id();
3320 let account1_key = Pubkey::new_unique();
3321 let mut account1_account = MiralandAccount::new(
3322 account_minimum_balance(),
3323 Account::get_packed_len(),
3324 &program_id,
3325 );
3326 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
3327 let owner_key = Pubkey::new_unique();
3328 let mint_key = Pubkey::new_unique();
3329 let mut mint_account =
3330 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3331 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
3332 let rent_key = rent::id();
3333 let mut rent_sysvar = rent_sysvar();
3334 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
3335
3336 do_process_instruction_dups(
3338 initialize_mint(&program_id, &mint_key, &mint_key, Some(&mint_key), 2).unwrap(),
3339 vec![mint_info.clone(), rent_info.clone()],
3340 )
3341 .unwrap();
3342
3343 do_process_instruction_dups(
3345 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
3346 vec![
3347 account1_info.clone(),
3348 mint_info.clone(),
3349 account1_info.clone(),
3350 rent_info.clone(),
3351 ],
3352 )
3353 .unwrap();
3354
3355 do_process_instruction_dups(
3357 set_authority(
3358 &program_id,
3359 &mint_key,
3360 Some(&owner_key),
3361 AuthorityType::MintTokens,
3362 &mint_key,
3363 &[],
3364 )
3365 .unwrap(),
3366 vec![mint_info.clone(), mint_info.clone()],
3367 )
3368 .unwrap();
3369
3370 do_process_instruction_dups(
3372 set_authority(
3373 &program_id,
3374 &mint_key,
3375 Some(&owner_key),
3376 AuthorityType::FreezeAccount,
3377 &mint_key,
3378 &[],
3379 )
3380 .unwrap(),
3381 vec![mint_info.clone(), mint_info.clone()],
3382 )
3383 .unwrap();
3384
3385 do_process_instruction_dups(
3387 set_authority(
3388 &program_id,
3389 &account1_key,
3390 Some(&owner_key),
3391 AuthorityType::AccountOwner,
3392 &account1_key,
3393 &[],
3394 )
3395 .unwrap(),
3396 vec![account1_info.clone(), account1_info.clone()],
3397 )
3398 .unwrap();
3399
3400 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
3402 account.close_authority = COption::Some(account1_key);
3403 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
3404
3405 do_process_instruction_dups(
3406 set_authority(
3407 &program_id,
3408 &account1_key,
3409 Some(&owner_key),
3410 AuthorityType::CloseAccount,
3411 &account1_key,
3412 &[],
3413 )
3414 .unwrap(),
3415 vec![account1_info.clone(), account1_info.clone()],
3416 )
3417 .unwrap();
3418 }
3419
3420 #[test]
3421 fn test_set_authority() {
3422 let program_id = crate::id();
3423 let account_key = Pubkey::new_unique();
3424 let mut account_account = MiralandAccount::new(
3425 account_minimum_balance(),
3426 Account::get_packed_len(),
3427 &program_id,
3428 );
3429 let account2_key = Pubkey::new_unique();
3430 let mut account2_account = MiralandAccount::new(
3431 account_minimum_balance(),
3432 Account::get_packed_len(),
3433 &program_id,
3434 );
3435 let owner_key = Pubkey::new_unique();
3436 let mut owner_account = MiralandAccount::default();
3437 let owner2_key = Pubkey::new_unique();
3438 let mut owner2_account = MiralandAccount::default();
3439 let owner3_key = Pubkey::new_unique();
3440 let mut owner3_account = MiralandAccount::default();
3441 let mint_key = Pubkey::new_unique();
3442 let mut mint_account =
3443 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3444 let mint2_key = Pubkey::new_unique();
3445 let mut mint2_account =
3446 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3447 let mut rent_sysvar = rent_sysvar();
3448
3449 do_process_instruction(
3451 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
3452 vec![&mut mint_account, &mut rent_sysvar],
3453 )
3454 .unwrap();
3455
3456 do_process_instruction(
3458 initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
3459 vec![&mut mint2_account, &mut rent_sysvar],
3460 )
3461 .unwrap();
3462
3463 assert_eq!(
3465 Err(ProgramError::UninitializedAccount),
3466 do_process_instruction(
3467 set_authority(
3468 &program_id,
3469 &account_key,
3470 Some(&owner2_key),
3471 AuthorityType::AccountOwner,
3472 &owner_key,
3473 &[]
3474 )
3475 .unwrap(),
3476 vec![&mut account_account, &mut owner_account],
3477 )
3478 );
3479
3480 do_process_instruction(
3482 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
3483 vec![
3484 &mut account_account,
3485 &mut mint_account,
3486 &mut owner_account,
3487 &mut rent_sysvar,
3488 ],
3489 )
3490 .unwrap();
3491
3492 do_process_instruction(
3494 initialize_account(&program_id, &account2_key, &mint2_key, &owner_key).unwrap(),
3495 vec![
3496 &mut account2_account,
3497 &mut mint2_account,
3498 &mut owner_account,
3499 &mut rent_sysvar,
3500 ],
3501 )
3502 .unwrap();
3503
3504 assert_eq!(
3506 Err(TokenError::OwnerMismatch.into()),
3507 do_process_instruction(
3508 set_authority(
3509 &program_id,
3510 &account_key,
3511 Some(&owner_key),
3512 AuthorityType::AccountOwner,
3513 &owner2_key,
3514 &[]
3515 )
3516 .unwrap(),
3517 vec![&mut account_account, &mut owner2_account],
3518 )
3519 );
3520
3521 let mut instruction = set_authority(
3523 &program_id,
3524 &account_key,
3525 Some(&owner2_key),
3526 AuthorityType::AccountOwner,
3527 &owner_key,
3528 &[],
3529 )
3530 .unwrap();
3531 instruction.accounts[1].is_signer = false;
3532 assert_eq!(
3533 Err(ProgramError::MissingRequiredSignature),
3534 do_process_instruction(instruction, vec![&mut account_account, &mut owner_account,],)
3535 );
3536
3537 assert_eq!(
3539 Err(TokenError::AuthorityTypeNotSupported.into()),
3540 do_process_instruction(
3541 set_authority(
3542 &program_id,
3543 &account_key,
3544 Some(&owner2_key),
3545 AuthorityType::FreezeAccount,
3546 &owner_key,
3547 &[],
3548 )
3549 .unwrap(),
3550 vec![&mut account_account, &mut owner_account],
3551 )
3552 );
3553
3554 assert_eq!(
3556 Err(TokenError::InvalidInstruction.into()),
3557 do_process_instruction(
3558 set_authority(
3559 &program_id,
3560 &account_key,
3561 None,
3562 AuthorityType::AccountOwner,
3563 &owner_key,
3564 &[],
3565 )
3566 .unwrap(),
3567 vec![&mut account_account, &mut owner_account],
3568 )
3569 );
3570
3571 do_process_instruction(
3573 approve(
3574 &program_id,
3575 &account_key,
3576 &owner2_key,
3577 &owner_key,
3578 &[],
3579 u64::MAX,
3580 )
3581 .unwrap(),
3582 vec![
3583 &mut account_account,
3584 &mut owner2_account,
3585 &mut owner_account,
3586 ],
3587 )
3588 .unwrap();
3589 let account = Account::unpack_unchecked(&account_account.data).unwrap();
3590 assert_eq!(account.delegate, COption::Some(owner2_key));
3591 assert_eq!(account.delegated_amount, u64::MAX);
3592
3593 do_process_instruction(
3595 set_authority(
3596 &program_id,
3597 &account_key,
3598 Some(&owner3_key),
3599 AuthorityType::AccountOwner,
3600 &owner_key,
3601 &[],
3602 )
3603 .unwrap(),
3604 vec![&mut account_account, &mut owner_account],
3605 )
3606 .unwrap();
3607
3608 let account = Account::unpack_unchecked(&account_account.data).unwrap();
3610 assert_eq!(account.delegate, COption::None);
3611 assert_eq!(account.delegated_amount, 0);
3612
3613 do_process_instruction(
3615 set_authority(
3616 &program_id,
3617 &account_key,
3618 Some(&owner2_key),
3619 AuthorityType::AccountOwner,
3620 &owner3_key,
3621 &[],
3622 )
3623 .unwrap(),
3624 vec![&mut account_account, &mut owner3_account],
3625 )
3626 .unwrap();
3627
3628 do_process_instruction(
3630 set_authority(
3631 &program_id,
3632 &account_key,
3633 Some(&owner2_key),
3634 AuthorityType::CloseAccount,
3635 &owner2_key,
3636 &[],
3637 )
3638 .unwrap(),
3639 vec![&mut account_account, &mut owner2_account],
3640 )
3641 .unwrap();
3642
3643 do_process_instruction(
3645 set_authority(
3646 &program_id,
3647 &account_key,
3648 None,
3649 AuthorityType::CloseAccount,
3650 &owner2_key,
3651 &[],
3652 )
3653 .unwrap(),
3654 vec![&mut account_account, &mut owner2_account],
3655 )
3656 .unwrap();
3657
3658 assert_eq!(
3660 Err(TokenError::OwnerMismatch.into()),
3661 do_process_instruction(
3662 set_authority(
3663 &program_id,
3664 &mint_key,
3665 Some(&owner3_key),
3666 AuthorityType::MintTokens,
3667 &owner2_key,
3668 &[]
3669 )
3670 .unwrap(),
3671 vec![&mut mint_account, &mut owner2_account],
3672 )
3673 );
3674
3675 let mut instruction = set_authority(
3677 &program_id,
3678 &mint_key,
3679 Some(&owner2_key),
3680 AuthorityType::MintTokens,
3681 &owner_key,
3682 &[],
3683 )
3684 .unwrap();
3685 instruction.accounts[1].is_signer = false;
3686 assert_eq!(
3687 Err(ProgramError::MissingRequiredSignature),
3688 do_process_instruction(instruction, vec![&mut mint_account, &mut owner_account],)
3689 );
3690
3691 assert_eq!(
3693 Err(TokenError::MintCannotFreeze.into()),
3694 do_process_instruction(
3695 set_authority(
3696 &program_id,
3697 &mint_key,
3698 Some(&owner2_key),
3699 AuthorityType::FreezeAccount,
3700 &owner_key,
3701 &[],
3702 )
3703 .unwrap(),
3704 vec![&mut mint_account, &mut owner_account],
3705 )
3706 );
3707
3708 do_process_instruction(
3710 set_authority(
3711 &program_id,
3712 &mint_key,
3713 Some(&owner2_key),
3714 AuthorityType::MintTokens,
3715 &owner_key,
3716 &[],
3717 )
3718 .unwrap(),
3719 vec![&mut mint_account, &mut owner_account],
3720 )
3721 .unwrap();
3722
3723 do_process_instruction(
3725 set_authority(
3726 &program_id,
3727 &mint_key,
3728 None,
3729 AuthorityType::MintTokens,
3730 &owner2_key,
3731 &[],
3732 )
3733 .unwrap(),
3734 vec![&mut mint_account, &mut owner2_account],
3735 )
3736 .unwrap();
3737
3738 assert_eq!(
3740 Err(TokenError::FixedSupply.into()),
3741 do_process_instruction(
3742 set_authority(
3743 &program_id,
3744 &mint2_key,
3745 Some(&owner2_key),
3746 AuthorityType::MintTokens,
3747 &owner_key,
3748 &[]
3749 )
3750 .unwrap(),
3751 vec![&mut mint_account, &mut owner_account],
3752 )
3753 );
3754
3755 do_process_instruction(
3757 set_authority(
3758 &program_id,
3759 &mint2_key,
3760 Some(&owner2_key),
3761 AuthorityType::FreezeAccount,
3762 &owner_key,
3763 &[],
3764 )
3765 .unwrap(),
3766 vec![&mut mint2_account, &mut owner_account],
3767 )
3768 .unwrap();
3769
3770 do_process_instruction(
3772 set_authority(
3773 &program_id,
3774 &mint2_key,
3775 None,
3776 AuthorityType::FreezeAccount,
3777 &owner2_key,
3778 &[],
3779 )
3780 .unwrap(),
3781 vec![&mut mint2_account, &mut owner2_account],
3782 )
3783 .unwrap();
3784
3785 assert_eq!(
3786 Err(TokenError::MintCannotFreeze.into()),
3787 do_process_instruction(
3788 set_authority(
3789 &program_id,
3790 &mint2_key,
3791 Some(&owner2_key),
3792 AuthorityType::FreezeAccount,
3793 &owner_key,
3794 &[],
3795 )
3796 .unwrap(),
3797 vec![&mut mint2_account, &mut owner2_account],
3798 )
3799 );
3800 }
3801
3802 #[test]
3803 fn test_mint_to_dups() {
3804 let program_id = crate::id();
3805 let account1_key = Pubkey::new_unique();
3806 let mut account1_account = MiralandAccount::new(
3807 account_minimum_balance(),
3808 Account::get_packed_len(),
3809 &program_id,
3810 );
3811 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
3812 let owner_key = Pubkey::new_unique();
3813 let mut owner_account = MiralandAccount::default();
3814 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
3815 let mint_key = Pubkey::new_unique();
3816 let mut mint_account =
3817 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3818 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
3819 let rent_key = rent::id();
3820 let mut rent_sysvar = rent_sysvar();
3821 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
3822
3823 do_process_instruction_dups(
3825 initialize_mint(&program_id, &mint_key, &mint_key, None, 2).unwrap(),
3826 vec![mint_info.clone(), rent_info.clone()],
3827 )
3828 .unwrap();
3829
3830 do_process_instruction_dups(
3832 initialize_account(&program_id, &account1_key, &mint_key, &owner_key).unwrap(),
3833 vec![
3834 account1_info.clone(),
3835 mint_info.clone(),
3836 owner_info.clone(),
3837 rent_info.clone(),
3838 ],
3839 )
3840 .unwrap();
3841
3842 do_process_instruction_dups(
3844 mint_to(&program_id, &mint_key, &account1_key, &mint_key, &[], 42).unwrap(),
3845 vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
3846 )
3847 .unwrap();
3848
3849 do_process_instruction_dups(
3851 mint_to_checked(&program_id, &mint_key, &account1_key, &mint_key, &[], 42, 2).unwrap(),
3852 vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
3853 )
3854 .unwrap();
3855
3856 let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow()).unwrap();
3858 mint.mint_authority = COption::Some(account1_key);
3859 Mint::pack(mint, &mut mint_info.data.borrow_mut()).unwrap();
3860 do_process_instruction_dups(
3861 mint_to(
3862 &program_id,
3863 &mint_key,
3864 &account1_key,
3865 &account1_key,
3866 &[],
3867 42,
3868 )
3869 .unwrap(),
3870 vec![
3871 mint_info.clone(),
3872 account1_info.clone(),
3873 account1_info.clone(),
3874 ],
3875 )
3876 .unwrap();
3877
3878 do_process_instruction_dups(
3880 mint_to(
3881 &program_id,
3882 &mint_key,
3883 &account1_key,
3884 &account1_key,
3885 &[],
3886 42,
3887 )
3888 .unwrap(),
3889 vec![
3890 mint_info.clone(),
3891 account1_info.clone(),
3892 account1_info.clone(),
3893 ],
3894 )
3895 .unwrap();
3896 }
3897
3898 #[test]
3899 fn test_mint_to() {
3900 let program_id = crate::id();
3901 let account_key = Pubkey::new_unique();
3902 let mut account_account = MiralandAccount::new(
3903 account_minimum_balance(),
3904 Account::get_packed_len(),
3905 &program_id,
3906 );
3907 let account2_key = Pubkey::new_unique();
3908 let mut account2_account = MiralandAccount::new(
3909 account_minimum_balance(),
3910 Account::get_packed_len(),
3911 &program_id,
3912 );
3913 let account3_key = Pubkey::new_unique();
3914 let mut account3_account = MiralandAccount::new(
3915 account_minimum_balance(),
3916 Account::get_packed_len(),
3917 &program_id,
3918 );
3919 let mismatch_key = Pubkey::new_unique();
3920 let mut mismatch_account = MiralandAccount::new(
3921 account_minimum_balance(),
3922 Account::get_packed_len(),
3923 &program_id,
3924 );
3925 let owner_key = Pubkey::new_unique();
3926 let mut owner_account = MiralandAccount::default();
3927 let owner2_key = Pubkey::new_unique();
3928 let mut owner2_account = MiralandAccount::default();
3929 let mint_key = Pubkey::new_unique();
3930 let mut mint_account =
3931 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3932 let mint2_key = Pubkey::new_unique();
3933 let uninitialized_key = Pubkey::new_unique();
3934 let mut uninitialized_account = MiralandAccount::new(
3935 account_minimum_balance(),
3936 Account::get_packed_len(),
3937 &program_id,
3938 );
3939 let mut rent_sysvar = rent_sysvar();
3940
3941 do_process_instruction(
3943 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
3944 vec![&mut mint_account, &mut rent_sysvar],
3945 )
3946 .unwrap();
3947
3948 do_process_instruction(
3950 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
3951 vec![
3952 &mut account_account,
3953 &mut mint_account,
3954 &mut owner_account,
3955 &mut rent_sysvar,
3956 ],
3957 )
3958 .unwrap();
3959
3960 do_process_instruction(
3962 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
3963 vec![
3964 &mut account2_account,
3965 &mut mint_account,
3966 &mut owner_account,
3967 &mut rent_sysvar,
3968 ],
3969 )
3970 .unwrap();
3971
3972 do_process_instruction(
3974 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
3975 vec![
3976 &mut account3_account,
3977 &mut mint_account,
3978 &mut owner_account,
3979 &mut rent_sysvar,
3980 ],
3981 )
3982 .unwrap();
3983
3984 do_process_instruction(
3986 initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
3987 vec![
3988 &mut mismatch_account,
3989 &mut mint_account,
3990 &mut owner_account,
3991 &mut rent_sysvar,
3992 ],
3993 )
3994 .unwrap();
3995 let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
3996 account.mint = mint2_key;
3997 Account::pack(account, &mut mismatch_account.data).unwrap();
3998
3999 do_process_instruction(
4001 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
4002 vec![&mut mint_account, &mut account_account, &mut owner_account],
4003 )
4004 .unwrap();
4005
4006 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
4007 assert_eq!(mint.supply, 42);
4008 let account = Account::unpack_unchecked(&account_account.data).unwrap();
4009 assert_eq!(account.amount, 42);
4010
4011 do_process_instruction(
4013 mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
4014 vec![&mut mint_account, &mut account2_account, &mut owner_account],
4015 )
4016 .unwrap();
4017
4018 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
4019 assert_eq!(mint.supply, 84);
4020 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
4021 assert_eq!(account.amount, 42);
4022
4023 let mut instruction =
4025 mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap();
4026 instruction.accounts[2].is_signer = false;
4027 assert_eq!(
4028 Err(ProgramError::MissingRequiredSignature),
4029 do_process_instruction(
4030 instruction,
4031 vec![&mut mint_account, &mut account2_account, &mut owner_account],
4032 )
4033 );
4034
4035 assert_eq!(
4037 Err(TokenError::MintMismatch.into()),
4038 do_process_instruction(
4039 mint_to(&program_id, &mint_key, &mismatch_key, &owner_key, &[], 42).unwrap(),
4040 vec![&mut mint_account, &mut mismatch_account, &mut owner_account],
4041 )
4042 );
4043
4044 assert_eq!(
4046 Err(TokenError::OwnerMismatch.into()),
4047 do_process_instruction(
4048 mint_to(&program_id, &mint_key, &account2_key, &owner2_key, &[], 42).unwrap(),
4049 vec![
4050 &mut mint_account,
4051 &mut account2_account,
4052 &mut owner2_account,
4053 ],
4054 )
4055 );
4056
4057 let not_program_id = Pubkey::new_unique();
4059 mint_account.owner = not_program_id;
4060 assert_eq!(
4061 Err(ProgramError::IncorrectProgramId),
4062 do_process_instruction(
4063 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 0).unwrap(),
4064 vec![&mut mint_account, &mut account_account, &mut owner_account],
4065 )
4066 );
4067 mint_account.owner = program_id;
4068
4069 let not_program_id = Pubkey::new_unique();
4071 account_account.owner = not_program_id;
4072 assert_eq!(
4073 Err(ProgramError::IncorrectProgramId),
4074 do_process_instruction(
4075 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 0).unwrap(),
4076 vec![&mut mint_account, &mut account_account, &mut owner_account],
4077 )
4078 );
4079 account_account.owner = program_id;
4080
4081 assert_eq!(
4083 Err(ProgramError::UninitializedAccount),
4084 do_process_instruction(
4085 mint_to(
4086 &program_id,
4087 &mint_key,
4088 &uninitialized_key,
4089 &owner_key,
4090 &[],
4091 42
4092 )
4093 .unwrap(),
4094 vec![
4095 &mut mint_account,
4096 &mut uninitialized_account,
4097 &mut owner_account,
4098 ],
4099 )
4100 );
4101
4102 do_process_instruction(
4104 set_authority(
4105 &program_id,
4106 &mint_key,
4107 None,
4108 AuthorityType::MintTokens,
4109 &owner_key,
4110 &[],
4111 )
4112 .unwrap(),
4113 vec![&mut mint_account, &mut owner_account],
4114 )
4115 .unwrap();
4116 assert_eq!(
4117 Err(TokenError::FixedSupply.into()),
4118 do_process_instruction(
4119 mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
4120 vec![&mut mint_account, &mut account2_account, &mut owner_account],
4121 )
4122 );
4123 }
4124
4125 #[test]
4126 fn test_burn_dups() {
4127 let program_id = crate::id();
4128 let account1_key = Pubkey::new_unique();
4129 let mut account1_account = MiralandAccount::new(
4130 account_minimum_balance(),
4131 Account::get_packed_len(),
4132 &program_id,
4133 );
4134 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
4135 let owner_key = Pubkey::new_unique();
4136 let mut owner_account = MiralandAccount::default();
4137 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
4138 let mint_key = Pubkey::new_unique();
4139 let mut mint_account =
4140 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4141 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
4142 let rent_key = rent::id();
4143 let mut rent_sysvar = rent_sysvar();
4144 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
4145
4146 do_process_instruction_dups(
4148 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
4149 vec![mint_info.clone(), rent_info.clone()],
4150 )
4151 .unwrap();
4152
4153 do_process_instruction_dups(
4155 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
4156 vec![
4157 account1_info.clone(),
4158 mint_info.clone(),
4159 account1_info.clone(),
4160 rent_info.clone(),
4161 ],
4162 )
4163 .unwrap();
4164
4165 do_process_instruction_dups(
4167 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
4168 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
4169 )
4170 .unwrap();
4171
4172 do_process_instruction_dups(
4174 burn(
4175 &program_id,
4176 &mint_key,
4177 &account1_key,
4178 &account1_key,
4179 &[],
4180 500,
4181 )
4182 .unwrap(),
4183 vec![
4184 account1_info.clone(),
4185 mint_info.clone(),
4186 account1_info.clone(),
4187 ],
4188 )
4189 .unwrap();
4190
4191 do_process_instruction_dups(
4193 burn_checked(
4194 &program_id,
4195 &account1_key,
4196 &mint_key,
4197 &account1_key,
4198 &[],
4199 500,
4200 2,
4201 )
4202 .unwrap(),
4203 vec![
4204 account1_info.clone(),
4205 mint_info.clone(),
4206 account1_info.clone(),
4207 ],
4208 )
4209 .unwrap();
4210
4211 do_process_instruction_dups(
4213 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
4214 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
4215 )
4216 .unwrap();
4217 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
4218 account.owner = mint_key;
4219 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
4220 do_process_instruction_dups(
4221 burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
4222 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
4223 )
4224 .unwrap();
4225
4226 do_process_instruction_dups(
4228 burn_checked(
4229 &program_id,
4230 &account1_key,
4231 &mint_key,
4232 &mint_key,
4233 &[],
4234 500,
4235 2,
4236 )
4237 .unwrap(),
4238 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
4239 )
4240 .unwrap();
4241
4242 do_process_instruction_dups(
4244 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
4245 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
4246 )
4247 .unwrap();
4248 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
4249 account.delegated_amount = 1000;
4250 account.delegate = COption::Some(account1_key);
4251 account.owner = owner_key;
4252 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
4253 do_process_instruction_dups(
4254 burn(
4255 &program_id,
4256 &account1_key,
4257 &mint_key,
4258 &account1_key,
4259 &[],
4260 500,
4261 )
4262 .unwrap(),
4263 vec![
4264 account1_info.clone(),
4265 mint_info.clone(),
4266 account1_info.clone(),
4267 ],
4268 )
4269 .unwrap();
4270
4271 do_process_instruction_dups(
4273 burn_checked(
4274 &program_id,
4275 &account1_key,
4276 &mint_key,
4277 &account1_key,
4278 &[],
4279 500,
4280 2,
4281 )
4282 .unwrap(),
4283 vec![
4284 account1_info.clone(),
4285 mint_info.clone(),
4286 account1_info.clone(),
4287 ],
4288 )
4289 .unwrap();
4290
4291 do_process_instruction_dups(
4293 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
4294 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
4295 )
4296 .unwrap();
4297 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
4298 account.delegated_amount = 1000;
4299 account.delegate = COption::Some(mint_key);
4300 account.owner = owner_key;
4301 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
4302 do_process_instruction_dups(
4303 burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
4304 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
4305 )
4306 .unwrap();
4307
4308 do_process_instruction_dups(
4310 burn_checked(
4311 &program_id,
4312 &account1_key,
4313 &mint_key,
4314 &mint_key,
4315 &[],
4316 500,
4317 2,
4318 )
4319 .unwrap(),
4320 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
4321 )
4322 .unwrap();
4323 }
4324
4325 #[test]
4326 fn test_burn() {
4327 let program_id = crate::id();
4328 let account_key = Pubkey::new_unique();
4329 let mut account_account = MiralandAccount::new(
4330 account_minimum_balance(),
4331 Account::get_packed_len(),
4332 &program_id,
4333 );
4334 let account2_key = Pubkey::new_unique();
4335 let mut account2_account = MiralandAccount::new(
4336 account_minimum_balance(),
4337 Account::get_packed_len(),
4338 &program_id,
4339 );
4340 let account3_key = Pubkey::new_unique();
4341 let mut account3_account = MiralandAccount::new(
4342 account_minimum_balance(),
4343 Account::get_packed_len(),
4344 &program_id,
4345 );
4346 let delegate_key = Pubkey::new_unique();
4347 let mut delegate_account = MiralandAccount::default();
4348 let mismatch_key = Pubkey::new_unique();
4349 let mut mismatch_account = MiralandAccount::new(
4350 account_minimum_balance(),
4351 Account::get_packed_len(),
4352 &program_id,
4353 );
4354 let owner_key = Pubkey::new_unique();
4355 let mut owner_account = MiralandAccount::default();
4356 let owner2_key = Pubkey::new_unique();
4357 let mut owner2_account = MiralandAccount::default();
4358 let mint_key = Pubkey::new_unique();
4359 let mut mint_account =
4360 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4361 let mint2_key = Pubkey::new_unique();
4362 let mut rent_sysvar = rent_sysvar();
4363
4364 do_process_instruction(
4366 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
4367 vec![&mut mint_account, &mut rent_sysvar],
4368 )
4369 .unwrap();
4370
4371 do_process_instruction(
4373 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
4374 vec![
4375 &mut account_account,
4376 &mut mint_account,
4377 &mut owner_account,
4378 &mut rent_sysvar,
4379 ],
4380 )
4381 .unwrap();
4382
4383 do_process_instruction(
4385 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
4386 vec![
4387 &mut account2_account,
4388 &mut mint_account,
4389 &mut owner_account,
4390 &mut rent_sysvar,
4391 ],
4392 )
4393 .unwrap();
4394
4395 do_process_instruction(
4397 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
4398 vec![
4399 &mut account3_account,
4400 &mut mint_account,
4401 &mut owner_account,
4402 &mut rent_sysvar,
4403 ],
4404 )
4405 .unwrap();
4406
4407 do_process_instruction(
4409 initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
4410 vec![
4411 &mut mismatch_account,
4412 &mut mint_account,
4413 &mut owner_account,
4414 &mut rent_sysvar,
4415 ],
4416 )
4417 .unwrap();
4418
4419 do_process_instruction(
4421 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
4422 vec![&mut mint_account, &mut account_account, &mut owner_account],
4423 )
4424 .unwrap();
4425
4426 do_process_instruction(
4428 mint_to(&program_id, &mint_key, &mismatch_key, &owner_key, &[], 1000).unwrap(),
4429 vec![&mut mint_account, &mut mismatch_account, &mut owner_account],
4430 )
4431 .unwrap();
4432 let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
4433 account.mint = mint2_key;
4434 Account::pack(account, &mut mismatch_account.data).unwrap();
4435
4436 let mut instruction =
4438 burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 42).unwrap();
4439 instruction.accounts[1].is_signer = false;
4440 assert_eq!(
4441 Err(TokenError::OwnerMismatch.into()),
4442 do_process_instruction(
4443 instruction,
4444 vec![
4445 &mut account_account,
4446 &mut mint_account,
4447 &mut delegate_account
4448 ],
4449 )
4450 );
4451
4452 assert_eq!(
4454 Err(TokenError::OwnerMismatch.into()),
4455 do_process_instruction(
4456 burn(&program_id, &account_key, &mint_key, &owner2_key, &[], 42).unwrap(),
4457 vec![&mut account_account, &mut mint_account, &mut owner2_account],
4458 )
4459 );
4460
4461 let not_program_id = Pubkey::new_unique();
4463 account_account.owner = not_program_id;
4464 assert_eq!(
4465 Err(ProgramError::IncorrectProgramId),
4466 do_process_instruction(
4467 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 0).unwrap(),
4468 vec![&mut account_account, &mut mint_account, &mut owner_account],
4469 )
4470 );
4471 account_account.owner = program_id;
4472
4473 let not_program_id = Pubkey::new_unique();
4475 mint_account.owner = not_program_id;
4476 assert_eq!(
4477 Err(ProgramError::IncorrectProgramId),
4478 do_process_instruction(
4479 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 0).unwrap(),
4480 vec![&mut account_account, &mut mint_account, &mut owner_account],
4481 )
4482 );
4483 mint_account.owner = program_id;
4484
4485 assert_eq!(
4487 Err(TokenError::MintMismatch.into()),
4488 do_process_instruction(
4489 burn(&program_id, &mismatch_key, &mint_key, &owner_key, &[], 42).unwrap(),
4490 vec![&mut mismatch_account, &mut mint_account, &mut owner_account],
4491 )
4492 );
4493
4494 do_process_instruction(
4496 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 21).unwrap(),
4497 vec![&mut account_account, &mut mint_account, &mut owner_account],
4498 )
4499 .unwrap();
4500
4501 assert_eq!(
4503 Err(TokenError::MintDecimalsMismatch.into()),
4504 do_process_instruction(
4505 burn_checked(&program_id, &account_key, &mint_key, &owner_key, &[], 21, 3).unwrap(),
4506 vec![&mut account_account, &mut mint_account, &mut owner_account],
4507 )
4508 );
4509
4510 do_process_instruction(
4512 burn_checked(&program_id, &account_key, &mint_key, &owner_key, &[], 21, 2).unwrap(),
4513 vec![&mut account_account, &mut mint_account, &mut owner_account],
4514 )
4515 .unwrap();
4516
4517 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
4518 assert_eq!(mint.supply, 2000 - 42);
4519 let account = Account::unpack_unchecked(&account_account.data).unwrap();
4520 assert_eq!(account.amount, 1000 - 42);
4521
4522 assert_eq!(
4524 Err(TokenError::InsufficientFunds.into()),
4525 do_process_instruction(
4526 burn(
4527 &program_id,
4528 &account_key,
4529 &mint_key,
4530 &owner_key,
4531 &[],
4532 100_000_000
4533 )
4534 .unwrap(),
4535 vec![&mut account_account, &mut mint_account, &mut owner_account],
4536 )
4537 );
4538
4539 do_process_instruction(
4541 approve(
4542 &program_id,
4543 &account_key,
4544 &delegate_key,
4545 &owner_key,
4546 &[],
4547 84,
4548 )
4549 .unwrap(),
4550 vec![
4551 &mut account_account,
4552 &mut delegate_account,
4553 &mut owner_account,
4554 ],
4555 )
4556 .unwrap();
4557
4558 assert_eq!(
4560 Err(TokenError::OwnerMismatch.into()),
4561 do_process_instruction(
4562 burn(
4563 &program_id,
4564 &account_key,
4565 &mint_key,
4566 &owner2_key, &[],
4568 1,
4569 )
4570 .unwrap(),
4571 vec![&mut account_account, &mut mint_account, &mut owner2_account],
4572 )
4573 );
4574
4575 assert_eq!(
4577 Err(TokenError::InsufficientFunds.into()),
4578 do_process_instruction(
4579 burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 85).unwrap(),
4580 vec![
4581 &mut account_account,
4582 &mut mint_account,
4583 &mut delegate_account
4584 ],
4585 )
4586 );
4587
4588 do_process_instruction(
4590 burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 84).unwrap(),
4591 vec![
4592 &mut account_account,
4593 &mut mint_account,
4594 &mut delegate_account,
4595 ],
4596 )
4597 .unwrap();
4598
4599 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
4601 assert_eq!(mint.supply, 2000 - 42 - 84);
4602 let account = Account::unpack_unchecked(&account_account.data).unwrap();
4603 assert_eq!(account.amount, 1000 - 42 - 84);
4604
4605 assert_eq!(
4607 Err(TokenError::OwnerMismatch.into()),
4608 do_process_instruction(
4609 burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 1).unwrap(),
4610 vec![
4611 &mut account_account,
4612 &mut mint_account,
4613 &mut delegate_account
4614 ],
4615 )
4616 );
4617 }
4618
4619 #[test]
4620 fn test_burn_and_close_system_and_incinerator_tokens() {
4621 let program_id = crate::id();
4622 let account_key = Pubkey::new_unique();
4623 let mut account_account = MiralandAccount::new(
4624 account_minimum_balance(),
4625 Account::get_packed_len(),
4626 &program_id,
4627 );
4628 let incinerator_account_key = Pubkey::new_unique();
4629 let mut incinerator_account = MiralandAccount::new(
4630 account_minimum_balance(),
4631 Account::get_packed_len(),
4632 &program_id,
4633 );
4634 let system_account_key = Pubkey::new_unique();
4635 let mut system_account = MiralandAccount::new(
4636 account_minimum_balance(),
4637 Account::get_packed_len(),
4638 &program_id,
4639 );
4640 let owner_key = Pubkey::new_unique();
4641 let mut owner_account = MiralandAccount::default();
4642 let recipient_key = Pubkey::new_unique();
4643 let mut recipient_account = MiralandAccount::default();
4644 let mut mock_incinerator_account = MiralandAccount::default();
4645 let mint_key = Pubkey::new_unique();
4646 let mut mint_account =
4647 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4648
4649 do_process_instruction(
4651 initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
4652 vec![&mut mint_account],
4653 )
4654 .unwrap();
4655
4656 do_process_instruction(
4658 initialize_account3(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
4659 vec![&mut account_account, &mut mint_account],
4660 )
4661 .unwrap();
4662
4663 do_process_instruction(
4665 initialize_account3(
4666 &program_id,
4667 &incinerator_account_key,
4668 &mint_key,
4669 &miraland_program::incinerator::id(),
4670 )
4671 .unwrap(),
4672 vec![&mut incinerator_account, &mut mint_account],
4673 )
4674 .unwrap();
4675 do_process_instruction(
4676 initialize_account3(
4677 &program_id,
4678 &system_account_key,
4679 &mint_key,
4680 &miraland_program::system_program::id(),
4681 )
4682 .unwrap(),
4683 vec![&mut system_account, &mut mint_account],
4684 )
4685 .unwrap();
4686
4687 do_process_instruction(
4689 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
4690 vec![&mut mint_account, &mut account_account, &mut owner_account],
4691 )
4692 .unwrap();
4693
4694 do_process_instruction(
4696 transfer(
4697 &program_id,
4698 &account_key,
4699 &incinerator_account_key,
4700 &owner_key,
4701 &[],
4702 500,
4703 )
4704 .unwrap(),
4705 vec![
4706 &mut account_account,
4707 &mut incinerator_account,
4708 &mut owner_account,
4709 ],
4710 )
4711 .unwrap();
4712 do_process_instruction(
4713 transfer(
4714 &program_id,
4715 &account_key,
4716 &system_account_key,
4717 &owner_key,
4718 &[],
4719 500,
4720 )
4721 .unwrap(),
4722 vec![
4723 &mut account_account,
4724 &mut system_account,
4725 &mut owner_account,
4726 ],
4727 )
4728 .unwrap();
4729
4730 assert_eq!(
4732 Err(TokenError::NonNativeHasBalance.into()),
4733 do_process_instruction(
4734 close_account(
4735 &program_id,
4736 &incinerator_account_key,
4737 &miraland_program::incinerator::id(),
4738 &owner_key,
4739 &[]
4740 )
4741 .unwrap(),
4742 vec![
4743 &mut incinerator_account,
4744 &mut mock_incinerator_account,
4745 &mut owner_account,
4746 ],
4747 )
4748 );
4749 assert_eq!(
4750 Err(TokenError::NonNativeHasBalance.into()),
4751 do_process_instruction(
4752 close_account(
4753 &program_id,
4754 &system_account_key,
4755 &miraland_program::incinerator::id(),
4756 &owner_key,
4757 &[]
4758 )
4759 .unwrap(),
4760 vec![
4761 &mut system_account,
4762 &mut mock_incinerator_account,
4763 &mut owner_account,
4764 ],
4765 )
4766 );
4767
4768 do_process_instruction(
4770 burn(
4771 &program_id,
4772 &incinerator_account_key,
4773 &mint_key,
4774 &recipient_key,
4775 &[],
4776 500,
4777 )
4778 .unwrap(),
4779 vec![
4780 &mut incinerator_account,
4781 &mut mint_account,
4782 &mut recipient_account,
4783 ],
4784 )
4785 .unwrap();
4786 do_process_instruction(
4787 burn(
4788 &program_id,
4789 &system_account_key,
4790 &mint_key,
4791 &recipient_key,
4792 &[],
4793 500,
4794 )
4795 .unwrap(),
4796 vec![
4797 &mut system_account,
4798 &mut mint_account,
4799 &mut recipient_account,
4800 ],
4801 )
4802 .unwrap();
4803
4804 assert_eq!(
4806 Err(ProgramError::InvalidAccountData),
4807 do_process_instruction(
4808 close_account(
4809 &program_id,
4810 &incinerator_account_key,
4811 &recipient_key,
4812 &owner_key,
4813 &[]
4814 )
4815 .unwrap(),
4816 vec![
4817 &mut incinerator_account,
4818 &mut recipient_account,
4819 &mut owner_account,
4820 ],
4821 )
4822 );
4823 assert_eq!(
4824 Err(ProgramError::InvalidAccountData),
4825 do_process_instruction(
4826 close_account(
4827 &program_id,
4828 &system_account_key,
4829 &recipient_key,
4830 &owner_key,
4831 &[]
4832 )
4833 .unwrap(),
4834 vec![
4835 &mut system_account,
4836 &mut recipient_account,
4837 &mut owner_account,
4838 ],
4839 )
4840 );
4841
4842 do_process_instruction(
4844 close_account(
4845 &program_id,
4846 &incinerator_account_key,
4847 &miraland_program::incinerator::id(),
4848 &owner_key,
4849 &[],
4850 )
4851 .unwrap(),
4852 vec![
4853 &mut incinerator_account,
4854 &mut mock_incinerator_account,
4855 &mut owner_account,
4856 ],
4857 )
4858 .unwrap();
4859
4860 do_process_instruction(
4861 close_account(
4862 &program_id,
4863 &system_account_key,
4864 &miraland_program::incinerator::id(),
4865 &owner_key,
4866 &[],
4867 )
4868 .unwrap(),
4869 vec![
4870 &mut system_account,
4871 &mut mock_incinerator_account,
4872 &mut owner_account,
4873 ],
4874 )
4875 .unwrap();
4876 }
4877
4878 #[test]
4879 fn test_multisig() {
4880 let program_id = crate::id();
4881 let mint_key = Pubkey::new_unique();
4882 let mut mint_account =
4883 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4884 let account_key = Pubkey::new_unique();
4885 let mut account = MiralandAccount::new(
4886 account_minimum_balance(),
4887 Account::get_packed_len(),
4888 &program_id,
4889 );
4890 let account2_key = Pubkey::new_unique();
4891 let mut account2_account = MiralandAccount::new(
4892 account_minimum_balance(),
4893 Account::get_packed_len(),
4894 &program_id,
4895 );
4896 let owner_key = Pubkey::new_unique();
4897 let mut owner_account = MiralandAccount::default();
4898 let multisig_key = Pubkey::new_unique();
4899 let mut multisig_account = MiralandAccount::new(42, Multisig::get_packed_len(), &program_id);
4900 let multisig_delegate_key = Pubkey::new_unique();
4901 let mut multisig_delegate_account = MiralandAccount::new(
4902 multisig_minimum_balance(),
4903 Multisig::get_packed_len(),
4904 &program_id,
4905 );
4906 let signer_keys = vec![Pubkey::new_unique(); MAX_SIGNERS];
4907 let signer_key_refs: Vec<&Pubkey> = signer_keys.iter().collect();
4908 let mut signer_accounts = vec![MiralandAccount::new(0, 0, &program_id); MAX_SIGNERS];
4909 let mut rent_sysvar = rent_sysvar();
4910
4911 let account_info_iter = &mut signer_accounts.iter_mut();
4913 assert_eq!(
4914 Err(TokenError::NotRentExempt.into()),
4915 do_process_instruction(
4916 initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
4917 vec![
4918 &mut multisig_account,
4919 &mut rent_sysvar,
4920 account_info_iter.next().unwrap(),
4921 ],
4922 )
4923 );
4924
4925 multisig_account.lamports = multisig_minimum_balance();
4926 let mut multisig_account2 = multisig_account.clone();
4927
4928 let account_info_iter = &mut signer_accounts.iter_mut();
4930 do_process_instruction(
4931 initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
4932 vec![
4933 &mut multisig_account,
4934 &mut rent_sysvar,
4935 account_info_iter.next().unwrap(),
4936 ],
4937 )
4938 .unwrap();
4939
4940 let account_info_iter = &mut signer_accounts.iter_mut();
4942 do_process_instruction(
4943 initialize_multisig2(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
4944 vec![&mut multisig_account2, account_info_iter.next().unwrap()],
4945 )
4946 .unwrap();
4947
4948 let account_info_iter = &mut signer_accounts.iter_mut();
4950 do_process_instruction(
4951 initialize_multisig(
4952 &program_id,
4953 &multisig_delegate_key,
4954 &signer_key_refs,
4955 MAX_SIGNERS as u8,
4956 )
4957 .unwrap(),
4958 vec![
4959 &mut multisig_delegate_account,
4960 &mut rent_sysvar,
4961 account_info_iter.next().unwrap(),
4962 account_info_iter.next().unwrap(),
4963 account_info_iter.next().unwrap(),
4964 account_info_iter.next().unwrap(),
4965 account_info_iter.next().unwrap(),
4966 account_info_iter.next().unwrap(),
4967 account_info_iter.next().unwrap(),
4968 account_info_iter.next().unwrap(),
4969 account_info_iter.next().unwrap(),
4970 account_info_iter.next().unwrap(),
4971 account_info_iter.next().unwrap(),
4972 ],
4973 )
4974 .unwrap();
4975
4976 do_process_instruction(
4978 initialize_mint(&program_id, &mint_key, &multisig_key, None, 2).unwrap(),
4979 vec![&mut mint_account, &mut rent_sysvar],
4980 )
4981 .unwrap();
4982
4983 do_process_instruction(
4985 initialize_account(&program_id, &account_key, &mint_key, &multisig_key).unwrap(),
4986 vec![
4987 &mut account,
4988 &mut mint_account,
4989 &mut multisig_account,
4990 &mut rent_sysvar,
4991 ],
4992 )
4993 .unwrap();
4994
4995 do_process_instruction(
4997 initialize_account(
4998 &program_id,
4999 &account2_key,
5000 &mint_key,
5001 &multisig_delegate_key,
5002 )
5003 .unwrap(),
5004 vec![
5005 &mut account2_account,
5006 &mut mint_account,
5007 &mut multisig_account,
5008 &mut rent_sysvar,
5009 ],
5010 )
5011 .unwrap();
5012
5013 let account_info_iter = &mut signer_accounts.iter_mut();
5015 do_process_instruction(
5016 mint_to(
5017 &program_id,
5018 &mint_key,
5019 &account_key,
5020 &multisig_key,
5021 &[&signer_keys[0]],
5022 1000,
5023 )
5024 .unwrap(),
5025 vec![
5026 &mut mint_account,
5027 &mut account,
5028 &mut multisig_account,
5029 account_info_iter.next().unwrap(),
5030 ],
5031 )
5032 .unwrap();
5033
5034 let account_info_iter = &mut signer_accounts.iter_mut();
5036 do_process_instruction(
5037 approve(
5038 &program_id,
5039 &account_key,
5040 &multisig_delegate_key,
5041 &multisig_key,
5042 &[&signer_keys[0]],
5043 100,
5044 )
5045 .unwrap(),
5046 vec![
5047 &mut account,
5048 &mut multisig_delegate_account,
5049 &mut multisig_account,
5050 account_info_iter.next().unwrap(),
5051 ],
5052 )
5053 .unwrap();
5054
5055 let account_info_iter = &mut signer_accounts.iter_mut();
5057 do_process_instruction(
5058 transfer(
5059 &program_id,
5060 &account_key,
5061 &account2_key,
5062 &multisig_key,
5063 &[&signer_keys[0]],
5064 42,
5065 )
5066 .unwrap(),
5067 vec![
5068 &mut account,
5069 &mut account2_account,
5070 &mut multisig_account,
5071 account_info_iter.next().unwrap(),
5072 ],
5073 )
5074 .unwrap();
5075
5076 let account_info_iter = &mut signer_accounts.iter_mut();
5078 do_process_instruction(
5079 transfer(
5080 &program_id,
5081 &account_key,
5082 &account2_key,
5083 &multisig_delegate_key,
5084 &signer_key_refs,
5085 42,
5086 )
5087 .unwrap(),
5088 vec![
5089 &mut account,
5090 &mut account2_account,
5091 &mut multisig_delegate_account,
5092 account_info_iter.next().unwrap(),
5093 account_info_iter.next().unwrap(),
5094 account_info_iter.next().unwrap(),
5095 account_info_iter.next().unwrap(),
5096 account_info_iter.next().unwrap(),
5097 account_info_iter.next().unwrap(),
5098 account_info_iter.next().unwrap(),
5099 account_info_iter.next().unwrap(),
5100 account_info_iter.next().unwrap(),
5101 account_info_iter.next().unwrap(),
5102 account_info_iter.next().unwrap(),
5103 ],
5104 )
5105 .unwrap();
5106
5107 let account_info_iter = &mut signer_accounts.iter_mut();
5109 do_process_instruction(
5110 mint_to(
5111 &program_id,
5112 &mint_key,
5113 &account2_key,
5114 &multisig_key,
5115 &[&signer_keys[0]],
5116 42,
5117 )
5118 .unwrap(),
5119 vec![
5120 &mut mint_account,
5121 &mut account2_account,
5122 &mut multisig_account,
5123 account_info_iter.next().unwrap(),
5124 ],
5125 )
5126 .unwrap();
5127
5128 let account_info_iter = &mut signer_accounts.iter_mut();
5130 do_process_instruction(
5131 burn(
5132 &program_id,
5133 &account_key,
5134 &mint_key,
5135 &multisig_key,
5136 &[&signer_keys[0]],
5137 42,
5138 )
5139 .unwrap(),
5140 vec![
5141 &mut account,
5142 &mut mint_account,
5143 &mut multisig_account,
5144 account_info_iter.next().unwrap(),
5145 ],
5146 )
5147 .unwrap();
5148
5149 let account_info_iter = &mut signer_accounts.iter_mut();
5151 do_process_instruction(
5152 burn(
5153 &program_id,
5154 &account_key,
5155 &mint_key,
5156 &multisig_delegate_key,
5157 &signer_key_refs,
5158 42,
5159 )
5160 .unwrap(),
5161 vec![
5162 &mut account,
5163 &mut mint_account,
5164 &mut multisig_delegate_account,
5165 account_info_iter.next().unwrap(),
5166 account_info_iter.next().unwrap(),
5167 account_info_iter.next().unwrap(),
5168 account_info_iter.next().unwrap(),
5169 account_info_iter.next().unwrap(),
5170 account_info_iter.next().unwrap(),
5171 account_info_iter.next().unwrap(),
5172 account_info_iter.next().unwrap(),
5173 account_info_iter.next().unwrap(),
5174 account_info_iter.next().unwrap(),
5175 account_info_iter.next().unwrap(),
5176 ],
5177 )
5178 .unwrap();
5179
5180 let account3_key = Pubkey::new_unique();
5182 let mut account3_account = MiralandAccount::new(
5183 account_minimum_balance(),
5184 Account::get_packed_len(),
5185 &program_id,
5186 );
5187 let mint2_key = Pubkey::new_unique();
5188 let mut mint2_account =
5189 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5190 do_process_instruction(
5191 initialize_mint(
5192 &program_id,
5193 &mint2_key,
5194 &multisig_key,
5195 Some(&multisig_key),
5196 2,
5197 )
5198 .unwrap(),
5199 vec![&mut mint2_account, &mut rent_sysvar],
5200 )
5201 .unwrap();
5202 do_process_instruction(
5203 initialize_account(&program_id, &account3_key, &mint2_key, &owner_key).unwrap(),
5204 vec![
5205 &mut account3_account,
5206 &mut mint2_account,
5207 &mut owner_account,
5208 &mut rent_sysvar,
5209 ],
5210 )
5211 .unwrap();
5212 let account_info_iter = &mut signer_accounts.iter_mut();
5213 do_process_instruction(
5214 mint_to(
5215 &program_id,
5216 &mint2_key,
5217 &account3_key,
5218 &multisig_key,
5219 &[&signer_keys[0]],
5220 1000,
5221 )
5222 .unwrap(),
5223 vec![
5224 &mut mint2_account,
5225 &mut account3_account,
5226 &mut multisig_account,
5227 account_info_iter.next().unwrap(),
5228 ],
5229 )
5230 .unwrap();
5231 let account_info_iter = &mut signer_accounts.iter_mut();
5232 do_process_instruction(
5233 freeze_account(
5234 &program_id,
5235 &account3_key,
5236 &mint2_key,
5237 &multisig_key,
5238 &[&signer_keys[0]],
5239 )
5240 .unwrap(),
5241 vec![
5242 &mut account3_account,
5243 &mut mint2_account,
5244 &mut multisig_account,
5245 account_info_iter.next().unwrap(),
5246 ],
5247 )
5248 .unwrap();
5249
5250 let account_info_iter = &mut signer_accounts.iter_mut();
5252 do_process_instruction(
5253 set_authority(
5254 &program_id,
5255 &mint_key,
5256 Some(&owner_key),
5257 AuthorityType::MintTokens,
5258 &multisig_key,
5259 &[&signer_keys[0]],
5260 )
5261 .unwrap(),
5262 vec![
5263 &mut mint_account,
5264 &mut multisig_account,
5265 account_info_iter.next().unwrap(),
5266 ],
5267 )
5268 .unwrap();
5269
5270 let account_info_iter = &mut signer_accounts.iter_mut();
5272 do_process_instruction(
5273 set_authority(
5274 &program_id,
5275 &account_key,
5276 Some(&owner_key),
5277 AuthorityType::AccountOwner,
5278 &multisig_key,
5279 &[&signer_keys[0]],
5280 )
5281 .unwrap(),
5282 vec![
5283 &mut account,
5284 &mut multisig_account,
5285 account_info_iter.next().unwrap(),
5286 ],
5287 )
5288 .unwrap();
5289 }
5290
5291 #[test]
5292 fn test_validate_owner() {
5293 let program_id = crate::id();
5294 let owner_key = Pubkey::new_unique();
5295 let mut signer_keys = [Pubkey::default(); MAX_SIGNERS];
5296 for signer_key in signer_keys.iter_mut().take(MAX_SIGNERS) {
5297 *signer_key = Pubkey::new_unique();
5298 }
5299 let mut signer_lamports = 0;
5300 let mut signer_data = vec![];
5301 let mut signers = vec![
5302 AccountInfo::new(
5303 &owner_key,
5304 true,
5305 false,
5306 &mut signer_lamports,
5307 &mut signer_data,
5308 &program_id,
5309 false,
5310 Epoch::default(),
5311 );
5312 MAX_SIGNERS + 1
5313 ];
5314 for (signer, key) in signers.iter_mut().zip(&signer_keys) {
5315 signer.key = key;
5316 }
5317 let mut lamports = 0;
5318 let mut data = vec![0; Multisig::get_packed_len()];
5319 let mut multisig = Multisig::unpack_unchecked(&data).unwrap();
5320 multisig.m = MAX_SIGNERS as u8;
5321 multisig.n = MAX_SIGNERS as u8;
5322 multisig.signers = signer_keys;
5323 multisig.is_initialized = true;
5324 Multisig::pack(multisig, &mut data).unwrap();
5325 let owner_account_info = AccountInfo::new(
5326 &owner_key,
5327 false,
5328 false,
5329 &mut lamports,
5330 &mut data,
5331 &program_id,
5332 false,
5333 Epoch::default(),
5334 );
5335
5336 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
5338
5339 {
5341 let mut multisig =
5342 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5343 multisig.m = 1;
5344 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5345 }
5346 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
5347
5348 {
5350 let mut multisig =
5351 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5352 multisig.m = 2;
5353 multisig.n = 1;
5354 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5355 }
5356 assert_eq!(
5357 Err(ProgramError::MissingRequiredSignature),
5358 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
5359 );
5360
5361 {
5363 let mut multisig =
5364 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5365 multisig.m = 0;
5366 multisig.n = 11;
5367 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5368 }
5369 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
5370
5371 {
5373 let mut multisig =
5374 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5375 multisig.m = 2;
5376 multisig.n = 11;
5377 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5378 }
5379 assert_eq!(
5380 Err(ProgramError::MissingRequiredSignature),
5381 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &[])
5382 );
5383 {
5385 let mut multisig =
5386 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5387 multisig.m = 2;
5388 multisig.n = 11;
5389 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5390 }
5391 assert_eq!(
5392 Err(ProgramError::MissingRequiredSignature),
5393 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[0..1])
5394 );
5395
5396 {
5398 let mut multisig =
5399 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5400 multisig.m = 2;
5401 multisig.n = 11;
5402 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5403 }
5404 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[5..7])
5405 .unwrap();
5406
5407 {
5409 let mut multisig =
5410 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5411 multisig.m = 11;
5412 multisig.n = 11;
5413 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5414 }
5415 signers[5].is_signer = false;
5416 assert_eq!(
5417 Err(ProgramError::MissingRequiredSignature),
5418 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
5419 );
5420 signers[5].is_signer = true;
5421
5422 {
5424 let mut signer_lamports = 0;
5425 let mut signer_data = vec![];
5426 let signers = vec![
5427 AccountInfo::new(
5428 &signer_keys[5],
5429 true,
5430 false,
5431 &mut signer_lamports,
5432 &mut signer_data,
5433 &program_id,
5434 false,
5435 Epoch::default(),
5436 );
5437 MAX_SIGNERS + 1
5438 ];
5439 let mut multisig =
5440 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
5441 multisig.m = 11;
5442 multisig.n = 11;
5443 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
5444 assert_eq!(
5445 Err(ProgramError::MissingRequiredSignature),
5446 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
5447 );
5448 }
5449 }
5450
5451 #[test]
5452 fn test_owner_close_account_dups() {
5453 let program_id = crate::id();
5454 let owner_key = Pubkey::new_unique();
5455 let mint_key = Pubkey::new_unique();
5456 let mut mint_account =
5457 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5458 let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
5459 let rent_key = rent::id();
5460 let mut rent_sysvar = rent_sysvar();
5461 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
5462
5463 do_process_instruction_dups(
5465 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
5466 vec![mint_info.clone(), rent_info.clone()],
5467 )
5468 .unwrap();
5469
5470 let to_close_key = Pubkey::new_unique();
5471 let mut to_close_account = MiralandAccount::new(
5472 account_minimum_balance(),
5473 Account::get_packed_len(),
5474 &program_id,
5475 );
5476 let to_close_account_info: AccountInfo =
5477 (&to_close_key, true, &mut to_close_account).into();
5478 let destination_account_key = Pubkey::new_unique();
5479 let mut destination_account = MiralandAccount::new(
5480 account_minimum_balance(),
5481 Account::get_packed_len(),
5482 &program_id,
5483 );
5484 let destination_account_info: AccountInfo =
5485 (&destination_account_key, true, &mut destination_account).into();
5486 do_process_instruction_dups(
5488 initialize_account(&program_id, &to_close_key, &mint_key, &to_close_key).unwrap(),
5489 vec![
5490 to_close_account_info.clone(),
5491 mint_info.clone(),
5492 to_close_account_info.clone(),
5493 rent_info.clone(),
5494 ],
5495 )
5496 .unwrap();
5497
5498 do_process_instruction_dups(
5500 close_account(
5501 &program_id,
5502 &to_close_key,
5503 &destination_account_key,
5504 &to_close_key,
5505 &[],
5506 )
5507 .unwrap(),
5508 vec![
5509 to_close_account_info.clone(),
5510 destination_account_info.clone(),
5511 to_close_account_info.clone(),
5512 ],
5513 )
5514 .unwrap();
5515 assert_eq!(*to_close_account_info.data.borrow(), &[0u8; Account::LEN]);
5516 }
5517
5518 #[test]
5519 fn test_close_authority_close_account_dups() {
5520 let program_id = crate::id();
5521 let owner_key = Pubkey::new_unique();
5522 let mint_key = Pubkey::new_unique();
5523 let mut mint_account =
5524 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5525 let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
5526 let rent_key = rent::id();
5527 let mut rent_sysvar = rent_sysvar();
5528 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
5529
5530 do_process_instruction_dups(
5532 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
5533 vec![mint_info.clone(), rent_info.clone()],
5534 )
5535 .unwrap();
5536
5537 let to_close_key = Pubkey::new_unique();
5538 let mut to_close_account = MiralandAccount::new(
5539 account_minimum_balance(),
5540 Account::get_packed_len(),
5541 &program_id,
5542 );
5543 let to_close_account_info: AccountInfo =
5544 (&to_close_key, true, &mut to_close_account).into();
5545 let destination_account_key = Pubkey::new_unique();
5546 let mut destination_account = MiralandAccount::new(
5547 account_minimum_balance(),
5548 Account::get_packed_len(),
5549 &program_id,
5550 );
5551 let destination_account_info: AccountInfo =
5552 (&destination_account_key, true, &mut destination_account).into();
5553 do_process_instruction_dups(
5555 initialize_account(&program_id, &to_close_key, &mint_key, &to_close_key).unwrap(),
5556 vec![
5557 to_close_account_info.clone(),
5558 mint_info.clone(),
5559 to_close_account_info.clone(),
5560 rent_info.clone(),
5561 ],
5562 )
5563 .unwrap();
5564 let mut account = Account::unpack_unchecked(&to_close_account_info.data.borrow()).unwrap();
5565 account.close_authority = COption::Some(to_close_key);
5566 account.owner = owner_key;
5567 Account::pack(account, &mut to_close_account_info.data.borrow_mut()).unwrap();
5568 do_process_instruction_dups(
5569 close_account(
5570 &program_id,
5571 &to_close_key,
5572 &destination_account_key,
5573 &to_close_key,
5574 &[],
5575 )
5576 .unwrap(),
5577 vec![
5578 to_close_account_info.clone(),
5579 destination_account_info.clone(),
5580 to_close_account_info.clone(),
5581 ],
5582 )
5583 .unwrap();
5584 assert_eq!(*to_close_account_info.data.borrow(), &[0u8; Account::LEN]);
5585 }
5586
5587 #[test]
5588 fn test_close_account() {
5589 let program_id = crate::id();
5590 let mint_key = Pubkey::new_unique();
5591 let mut mint_account =
5592 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5593 let account_key = Pubkey::new_unique();
5594 let mut account_account = MiralandAccount::new(
5595 account_minimum_balance(),
5596 Account::get_packed_len(),
5597 &program_id,
5598 );
5599 let account2_key = Pubkey::new_unique();
5600 let mut account2_account = MiralandAccount::new(
5601 account_minimum_balance() + 42,
5602 Account::get_packed_len(),
5603 &program_id,
5604 );
5605 let account3_key = Pubkey::new_unique();
5606 let mut account3_account = MiralandAccount::new(
5607 account_minimum_balance(),
5608 Account::get_packed_len(),
5609 &program_id,
5610 );
5611 let owner_key = Pubkey::new_unique();
5612 let mut owner_account = MiralandAccount::default();
5613 let owner2_key = Pubkey::new_unique();
5614 let mut owner2_account = MiralandAccount::default();
5615 let mut rent_sysvar = rent_sysvar();
5616
5617 assert_eq!(
5619 Err(ProgramError::UninitializedAccount),
5620 do_process_instruction(
5621 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
5622 vec![
5623 &mut account_account,
5624 &mut account3_account,
5625 &mut owner2_account,
5626 ],
5627 )
5628 );
5629
5630 do_process_instruction(
5632 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
5633 vec![&mut mint_account, &mut rent_sysvar],
5634 )
5635 .unwrap();
5636 do_process_instruction(
5637 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
5638 vec![
5639 &mut account_account,
5640 &mut mint_account,
5641 &mut owner_account,
5642 &mut rent_sysvar,
5643 ],
5644 )
5645 .unwrap();
5646 do_process_instruction(
5647 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
5648 vec![
5649 &mut mint_account,
5650 &mut account_account,
5651 &mut owner_account,
5652 &mut rent_sysvar,
5653 ],
5654 )
5655 .unwrap();
5656 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5657 assert_eq!(account.amount, 42);
5658
5659 do_process_instruction(
5661 initialize_account(
5662 &program_id,
5663 &account2_key,
5664 &crate::native_mint::id(),
5665 &owner_key,
5666 )
5667 .unwrap(),
5668 vec![
5669 &mut account2_account,
5670 &mut mint_account,
5671 &mut owner_account,
5672 &mut rent_sysvar,
5673 ],
5674 )
5675 .unwrap();
5676 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
5677 assert!(account.is_native());
5678 assert_eq!(account.amount, 42);
5679
5680 assert_eq!(
5682 Err(TokenError::NonNativeHasBalance.into()),
5683 do_process_instruction(
5684 close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
5685 vec![
5686 &mut account_account,
5687 &mut account3_account,
5688 &mut owner_account,
5689 ],
5690 )
5691 );
5692 assert_eq!(account_account.lamports, account_minimum_balance());
5693
5694 do_process_instruction(
5696 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 42).unwrap(),
5697 vec![&mut account_account, &mut mint_account, &mut owner_account],
5698 )
5699 .unwrap();
5700
5701 assert_eq!(
5703 Err(TokenError::OwnerMismatch.into()),
5704 do_process_instruction(
5705 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
5706 vec![
5707 &mut account_account,
5708 &mut account3_account,
5709 &mut owner2_account,
5710 ],
5711 )
5712 );
5713
5714 do_process_instruction(
5716 close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
5717 vec![
5718 &mut account_account,
5719 &mut account3_account,
5720 &mut owner_account,
5721 ],
5722 )
5723 .unwrap();
5724 assert_eq!(account_account.lamports, 0);
5725 assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
5726 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5727 assert_eq!(account.amount, 0);
5728
5729 let account_key = Pubkey::new_unique();
5731 let mut account_account = MiralandAccount::new(
5732 account_minimum_balance(),
5733 Account::get_packed_len(),
5734 &program_id,
5735 );
5736 let owner2_key = Pubkey::new_unique();
5737 let mut owner2_account = MiralandAccount::new(
5738 account_minimum_balance(),
5739 Account::get_packed_len(),
5740 &program_id,
5741 );
5742 do_process_instruction(
5743 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
5744 vec![
5745 &mut account_account,
5746 &mut mint_account,
5747 &mut owner_account,
5748 &mut rent_sysvar,
5749 ],
5750 )
5751 .unwrap();
5752 account_account.lamports = 2;
5753
5754 do_process_instruction(
5755 set_authority(
5756 &program_id,
5757 &account_key,
5758 Some(&owner2_key),
5759 AuthorityType::CloseAccount,
5760 &owner_key,
5761 &[],
5762 )
5763 .unwrap(),
5764 vec![&mut account_account, &mut owner_account],
5765 )
5766 .unwrap();
5767
5768 assert_eq!(
5770 Err(TokenError::OwnerMismatch.into()),
5771 do_process_instruction(
5772 close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
5773 vec![
5774 &mut account_account,
5775 &mut account3_account,
5776 &mut owner_account,
5777 ],
5778 )
5779 );
5780
5781 do_process_instruction(
5783 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
5784 vec![
5785 &mut account_account,
5786 &mut account3_account,
5787 &mut owner2_account,
5788 ],
5789 )
5790 .unwrap();
5791 assert_eq!(account_account.lamports, 0);
5792 assert_eq!(account3_account.lamports, 2 * account_minimum_balance() + 2);
5793 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5794 assert_eq!(account.amount, 0);
5795
5796 do_process_instruction(
5798 close_account(&program_id, &account2_key, &account3_key, &owner_key, &[]).unwrap(),
5799 vec![
5800 &mut account2_account,
5801 &mut account3_account,
5802 &mut owner_account,
5803 ],
5804 )
5805 .unwrap();
5806 assert_eq!(account2_account.data, [0u8; Account::LEN]);
5807 assert_eq!(
5808 account3_account.lamports,
5809 3 * account_minimum_balance() + 2 + 42
5810 );
5811 }
5812
5813 #[test]
5814 fn test_native_token() {
5815 let program_id = crate::id();
5816 let mut mint_account =
5817 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5818 let account_key = Pubkey::new_unique();
5819 let mut account_account = MiralandAccount::new(
5820 account_minimum_balance() + 40,
5821 Account::get_packed_len(),
5822 &program_id,
5823 );
5824 let account2_key = Pubkey::new_unique();
5825 let mut account2_account = MiralandAccount::new(
5826 account_minimum_balance(),
5827 Account::get_packed_len(),
5828 &program_id,
5829 );
5830 let account3_key = Pubkey::new_unique();
5831 let mut account3_account = MiralandAccount::new(account_minimum_balance(), 0, &program_id);
5832 let owner_key = Pubkey::new_unique();
5833 let mut owner_account = MiralandAccount::default();
5834 let owner2_key = Pubkey::new_unique();
5835 let mut owner2_account = MiralandAccount::default();
5836 let owner3_key = Pubkey::new_unique();
5837 let mut rent_sysvar = rent_sysvar();
5838
5839 do_process_instruction(
5841 initialize_account(
5842 &program_id,
5843 &account_key,
5844 &crate::native_mint::id(),
5845 &owner_key,
5846 )
5847 .unwrap(),
5848 vec![
5849 &mut account_account,
5850 &mut mint_account,
5851 &mut owner_account,
5852 &mut rent_sysvar,
5853 ],
5854 )
5855 .unwrap();
5856 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5857 assert!(account.is_native());
5858 assert_eq!(account.amount, 40);
5859
5860 do_process_instruction(
5862 initialize_account(
5863 &program_id,
5864 &account2_key,
5865 &crate::native_mint::id(),
5866 &owner_key,
5867 )
5868 .unwrap(),
5869 vec![
5870 &mut account2_account,
5871 &mut mint_account,
5872 &mut owner_account,
5873 &mut rent_sysvar,
5874 ],
5875 )
5876 .unwrap();
5877 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
5878 assert!(account.is_native());
5879 assert_eq!(account.amount, 0);
5880
5881 assert_eq!(
5883 Err(TokenError::NativeNotSupported.into()),
5884 do_process_instruction(
5885 mint_to(
5886 &program_id,
5887 &crate::native_mint::id(),
5888 &account_key,
5889 &owner_key,
5890 &[],
5891 42
5892 )
5893 .unwrap(),
5894 vec![&mut mint_account, &mut account_account, &mut owner_account],
5895 )
5896 );
5897
5898 let bogus_mint_key = Pubkey::new_unique();
5900 let mut bogus_mint_account =
5901 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5902 do_process_instruction(
5903 initialize_mint(&program_id, &bogus_mint_key, &owner_key, None, 2).unwrap(),
5904 vec![&mut bogus_mint_account, &mut rent_sysvar],
5905 )
5906 .unwrap();
5907
5908 assert_eq!(
5909 Err(TokenError::NativeNotSupported.into()),
5910 do_process_instruction(
5911 burn(
5912 &program_id,
5913 &account_key,
5914 &bogus_mint_key,
5915 &owner_key,
5916 &[],
5917 42
5918 )
5919 .unwrap(),
5920 vec![
5921 &mut account_account,
5922 &mut bogus_mint_account,
5923 &mut owner_account
5924 ],
5925 )
5926 );
5927
5928 assert_eq!(
5930 Err(TokenError::InsufficientFunds.into()),
5931 do_process_instruction(
5932 transfer(
5933 &program_id,
5934 &account_key,
5935 &account2_key,
5936 &owner_key,
5937 &[],
5938 50,
5939 )
5940 .unwrap(),
5941 vec![
5942 &mut account_account,
5943 &mut account2_account,
5944 &mut owner_account,
5945 ],
5946 )
5947 );
5948
5949 do_process_instruction(
5951 transfer(
5952 &program_id,
5953 &account_key,
5954 &account2_key,
5955 &owner_key,
5956 &[],
5957 40,
5958 )
5959 .unwrap(),
5960 vec![
5961 &mut account_account,
5962 &mut account2_account,
5963 &mut owner_account,
5964 ],
5965 )
5966 .unwrap();
5967 assert_eq!(account_account.lamports, account_minimum_balance());
5968 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5969 assert!(account.is_native());
5970 assert_eq!(account.amount, 0);
5971 assert_eq!(account2_account.lamports, account_minimum_balance() + 40);
5972 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
5973 assert!(account.is_native());
5974 assert_eq!(account.amount, 40);
5975
5976 do_process_instruction(
5978 set_authority(
5979 &program_id,
5980 &account_key,
5981 Some(&owner3_key),
5982 AuthorityType::CloseAccount,
5983 &owner_key,
5984 &[],
5985 )
5986 .unwrap(),
5987 vec![&mut account_account, &mut owner_account],
5988 )
5989 .unwrap();
5990 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5991 assert_eq!(account.close_authority, COption::Some(owner3_key));
5992
5993 do_process_instruction(
5995 set_authority(
5996 &program_id,
5997 &account_key,
5998 Some(&owner2_key),
5999 AuthorityType::AccountOwner,
6000 &owner_key,
6001 &[],
6002 )
6003 .unwrap(),
6004 vec![&mut account_account, &mut owner_account],
6005 )
6006 .unwrap();
6007
6008 let account = Account::unpack_unchecked(&account_account.data).unwrap();
6010 assert_eq!(account.close_authority, COption::None);
6011
6012 do_process_instruction(
6014 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
6015 vec![
6016 &mut account_account,
6017 &mut account3_account,
6018 &mut owner2_account,
6019 ],
6020 )
6021 .unwrap();
6022 assert_eq!(account_account.lamports, 0);
6023 assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
6024 assert_eq!(account_account.data, [0u8; Account::LEN]);
6025 }
6026
6027 #[test]
6028 fn test_overflow() {
6029 let program_id = crate::id();
6030 let account_key = Pubkey::new_unique();
6031 let mut account_account = MiralandAccount::new(
6032 account_minimum_balance(),
6033 Account::get_packed_len(),
6034 &program_id,
6035 );
6036 let account2_key = Pubkey::new_unique();
6037 let mut account2_account = MiralandAccount::new(
6038 account_minimum_balance(),
6039 Account::get_packed_len(),
6040 &program_id,
6041 );
6042 let owner_key = Pubkey::new_unique();
6043 let mut owner_account = MiralandAccount::default();
6044 let owner2_key = Pubkey::new_unique();
6045 let mut owner2_account = MiralandAccount::default();
6046 let mint_owner_key = Pubkey::new_unique();
6047 let mut mint_owner_account = MiralandAccount::default();
6048 let mint_key = Pubkey::new_unique();
6049 let mut mint_account =
6050 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6051 let mut rent_sysvar = rent_sysvar();
6052
6053 do_process_instruction(
6055 initialize_mint(&program_id, &mint_key, &mint_owner_key, None, 2).unwrap(),
6056 vec![&mut mint_account, &mut rent_sysvar],
6057 )
6058 .unwrap();
6059
6060 do_process_instruction(
6062 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6063 vec![
6064 &mut account_account,
6065 &mut mint_account,
6066 &mut owner_account,
6067 &mut rent_sysvar,
6068 ],
6069 )
6070 .unwrap();
6071
6072 do_process_instruction(
6074 initialize_account(&program_id, &account2_key, &mint_key, &owner2_key).unwrap(),
6075 vec![
6076 &mut account2_account,
6077 &mut mint_account,
6078 &mut owner2_account,
6079 &mut rent_sysvar,
6080 ],
6081 )
6082 .unwrap();
6083
6084 do_process_instruction(
6086 mint_to(
6087 &program_id,
6088 &mint_key,
6089 &account_key,
6090 &mint_owner_key,
6091 &[],
6092 u64::MAX,
6093 )
6094 .unwrap(),
6095 vec![
6096 &mut mint_account,
6097 &mut account_account,
6098 &mut mint_owner_account,
6099 ],
6100 )
6101 .unwrap();
6102 let account = Account::unpack_unchecked(&account_account.data).unwrap();
6103 assert_eq!(account.amount, u64::MAX);
6104
6105 assert_eq!(
6107 Err(TokenError::Overflow.into()),
6108 do_process_instruction(
6109 mint_to(
6110 &program_id,
6111 &mint_key,
6112 &account_key,
6113 &mint_owner_key,
6114 &[],
6115 1,
6116 )
6117 .unwrap(),
6118 vec![
6119 &mut mint_account,
6120 &mut account_account,
6121 &mut mint_owner_account,
6122 ],
6123 )
6124 );
6125 let account = Account::unpack_unchecked(&account_account.data).unwrap();
6126 assert_eq!(account.amount, u64::MAX);
6127
6128 assert_eq!(
6130 Err(TokenError::Overflow.into()),
6131 do_process_instruction(
6132 mint_to(
6133 &program_id,
6134 &mint_key,
6135 &account2_key,
6136 &mint_owner_key,
6137 &[],
6138 1,
6139 )
6140 .unwrap(),
6141 vec![
6142 &mut mint_account,
6143 &mut account2_account,
6144 &mut mint_owner_account,
6145 ],
6146 )
6147 );
6148
6149 do_process_instruction(
6151 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
6152 vec![&mut account_account, &mut mint_account, &mut owner_account],
6153 )
6154 .unwrap();
6155 let account = Account::unpack_unchecked(&account_account.data).unwrap();
6156 assert_eq!(account.amount, u64::MAX - 100);
6157
6158 do_process_instruction(
6159 mint_to(
6160 &program_id,
6161 &mint_key,
6162 &account_key,
6163 &mint_owner_key,
6164 &[],
6165 100,
6166 )
6167 .unwrap(),
6168 vec![
6169 &mut mint_account,
6170 &mut account_account,
6171 &mut mint_owner_account,
6172 ],
6173 )
6174 .unwrap();
6175 let account = Account::unpack_unchecked(&account_account.data).unwrap();
6176 assert_eq!(account.amount, u64::MAX);
6177
6178 let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
6180 account.amount = 1;
6181 Account::pack(account, &mut account2_account.data).unwrap();
6182
6183 assert_eq!(
6184 Err(TokenError::Overflow.into()),
6185 do_process_instruction(
6186 transfer(
6187 &program_id,
6188 &account2_key,
6189 &account_key,
6190 &owner2_key,
6191 &[],
6192 1,
6193 )
6194 .unwrap(),
6195 vec![
6196 &mut account2_account,
6197 &mut account_account,
6198 &mut owner2_account,
6199 ],
6200 )
6201 );
6202 }
6203
6204 #[test]
6205 fn test_frozen() {
6206 let program_id = crate::id();
6207 let account_key = Pubkey::new_unique();
6208 let mut account_account = MiralandAccount::new(
6209 account_minimum_balance(),
6210 Account::get_packed_len(),
6211 &program_id,
6212 );
6213 let account2_key = Pubkey::new_unique();
6214 let mut account2_account = MiralandAccount::new(
6215 account_minimum_balance(),
6216 Account::get_packed_len(),
6217 &program_id,
6218 );
6219 let owner_key = Pubkey::new_unique();
6220 let mut owner_account = MiralandAccount::default();
6221 let mint_key = Pubkey::new_unique();
6222 let mut mint_account =
6223 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6224 let mut rent_sysvar = rent_sysvar();
6225
6226 do_process_instruction(
6228 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6229 vec![&mut mint_account, &mut rent_sysvar],
6230 )
6231 .unwrap();
6232
6233 do_process_instruction(
6235 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6236 vec![
6237 &mut account_account,
6238 &mut mint_account,
6239 &mut owner_account,
6240 &mut rent_sysvar,
6241 ],
6242 )
6243 .unwrap();
6244
6245 do_process_instruction(
6247 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
6248 vec![
6249 &mut account2_account,
6250 &mut mint_account,
6251 &mut owner_account,
6252 &mut rent_sysvar,
6253 ],
6254 )
6255 .unwrap();
6256
6257 do_process_instruction(
6259 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
6260 vec![&mut mint_account, &mut account_account, &mut owner_account],
6261 )
6262 .unwrap();
6263
6264 let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
6266 account.state = AccountState::Frozen;
6267 Account::pack(account, &mut account2_account.data).unwrap();
6268 assert_eq!(
6269 Err(TokenError::AccountFrozen.into()),
6270 do_process_instruction(
6271 transfer(
6272 &program_id,
6273 &account_key,
6274 &account2_key,
6275 &owner_key,
6276 &[],
6277 500,
6278 )
6279 .unwrap(),
6280 vec![
6281 &mut account_account,
6282 &mut account2_account,
6283 &mut owner_account,
6284 ],
6285 )
6286 );
6287
6288 let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
6289 account.state = AccountState::Initialized;
6290 Account::pack(account, &mut account_account.data).unwrap();
6291 let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
6292 account.state = AccountState::Frozen;
6293 Account::pack(account, &mut account2_account.data).unwrap();
6294 assert_eq!(
6295 Err(TokenError::AccountFrozen.into()),
6296 do_process_instruction(
6297 transfer(
6298 &program_id,
6299 &account_key,
6300 &account2_key,
6301 &owner_key,
6302 &[],
6303 500,
6304 )
6305 .unwrap(),
6306 vec![
6307 &mut account_account,
6308 &mut account2_account,
6309 &mut owner_account,
6310 ],
6311 )
6312 );
6313
6314 let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
6316 account.state = AccountState::Frozen;
6317 Account::pack(account, &mut account_account.data).unwrap();
6318 let delegate_key = Pubkey::new_unique();
6319 let mut delegate_account = MiralandAccount::default();
6320 assert_eq!(
6321 Err(TokenError::AccountFrozen.into()),
6322 do_process_instruction(
6323 approve(
6324 &program_id,
6325 &account_key,
6326 &delegate_key,
6327 &owner_key,
6328 &[],
6329 100
6330 )
6331 .unwrap(),
6332 vec![
6333 &mut account_account,
6334 &mut delegate_account,
6335 &mut owner_account,
6336 ],
6337 )
6338 );
6339
6340 let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
6342 account.delegate = COption::Some(delegate_key);
6343 account.delegated_amount = 100;
6344 Account::pack(account, &mut account_account.data).unwrap();
6345 assert_eq!(
6346 Err(TokenError::AccountFrozen.into()),
6347 do_process_instruction(
6348 revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
6349 vec![&mut account_account, &mut owner_account],
6350 )
6351 );
6352
6353 let new_owner_key = Pubkey::new_unique();
6355 assert_eq!(
6356 Err(TokenError::AccountFrozen.into()),
6357 do_process_instruction(
6358 set_authority(
6359 &program_id,
6360 &account_key,
6361 Some(&new_owner_key),
6362 AuthorityType::AccountOwner,
6363 &owner_key,
6364 &[]
6365 )
6366 .unwrap(),
6367 vec![&mut account_account, &mut owner_account,],
6368 )
6369 );
6370
6371 assert_eq!(
6373 Err(TokenError::AccountFrozen.into()),
6374 do_process_instruction(
6375 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 100).unwrap(),
6376 vec![&mut mint_account, &mut account_account, &mut owner_account,],
6377 )
6378 );
6379
6380 assert_eq!(
6382 Err(TokenError::AccountFrozen.into()),
6383 do_process_instruction(
6384 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
6385 vec![&mut account_account, &mut mint_account, &mut owner_account],
6386 )
6387 );
6388 }
6389
6390 #[test]
6391 fn test_freeze_thaw_dups() {
6392 let program_id = crate::id();
6393 let account1_key = Pubkey::new_unique();
6394 let mut account1_account = MiralandAccount::new(
6395 account_minimum_balance(),
6396 Account::get_packed_len(),
6397 &program_id,
6398 );
6399 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
6400 let owner_key = Pubkey::new_unique();
6401 let mint_key = Pubkey::new_unique();
6402 let mut mint_account =
6403 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6404 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
6405 let rent_key = rent::id();
6406 let mut rent_sysvar = rent_sysvar();
6407 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
6408
6409 do_process_instruction_dups(
6411 initialize_mint(&program_id, &mint_key, &owner_key, Some(&account1_key), 2).unwrap(),
6412 vec![mint_info.clone(), rent_info.clone()],
6413 )
6414 .unwrap();
6415
6416 do_process_instruction_dups(
6418 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
6419 vec![
6420 account1_info.clone(),
6421 mint_info.clone(),
6422 account1_info.clone(),
6423 rent_info.clone(),
6424 ],
6425 )
6426 .unwrap();
6427
6428 do_process_instruction_dups(
6430 freeze_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
6431 vec![
6432 account1_info.clone(),
6433 mint_info.clone(),
6434 account1_info.clone(),
6435 ],
6436 )
6437 .unwrap();
6438
6439 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
6441 account.state = AccountState::Frozen;
6442 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
6443 do_process_instruction_dups(
6444 thaw_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
6445 vec![
6446 account1_info.clone(),
6447 mint_info.clone(),
6448 account1_info.clone(),
6449 ],
6450 )
6451 .unwrap();
6452 }
6453
6454 #[test]
6455 fn test_freeze_account() {
6456 let program_id = crate::id();
6457 let account_key = Pubkey::new_unique();
6458 let mut account_account = MiralandAccount::new(
6459 account_minimum_balance(),
6460 Account::get_packed_len(),
6461 &program_id,
6462 );
6463 let account_owner_key = Pubkey::new_unique();
6464 let mut account_owner_account = MiralandAccount::default();
6465 let owner_key = Pubkey::new_unique();
6466 let mut owner_account = MiralandAccount::default();
6467 let owner2_key = Pubkey::new_unique();
6468 let mut owner2_account = MiralandAccount::default();
6469 let mint_key = Pubkey::new_unique();
6470 let mut mint_account =
6471 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6472 let mut rent_sysvar = rent_sysvar();
6473
6474 do_process_instruction(
6476 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6477 vec![&mut mint_account, &mut rent_sysvar],
6478 )
6479 .unwrap();
6480
6481 do_process_instruction(
6483 initialize_account(&program_id, &account_key, &mint_key, &account_owner_key).unwrap(),
6484 vec![
6485 &mut account_account,
6486 &mut mint_account,
6487 &mut account_owner_account,
6488 &mut rent_sysvar,
6489 ],
6490 )
6491 .unwrap();
6492
6493 do_process_instruction(
6495 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
6496 vec![&mut mint_account, &mut account_account, &mut owner_account],
6497 )
6498 .unwrap();
6499
6500 assert_eq!(
6502 Err(TokenError::MintCannotFreeze.into()),
6503 do_process_instruction(
6504 freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
6505 vec![&mut account_account, &mut mint_account, &mut owner_account],
6506 )
6507 );
6508
6509 let mut mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
6511 mint.freeze_authority = COption::Some(owner_key);
6512 Mint::pack(mint, &mut mint_account.data).unwrap();
6513 assert_eq!(
6514 Err(TokenError::OwnerMismatch.into()),
6515 do_process_instruction(
6516 freeze_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
6517 vec![&mut account_account, &mut mint_account, &mut owner2_account],
6518 )
6519 );
6520
6521 assert_eq!(
6523 Err(TokenError::InvalidState.into()),
6524 do_process_instruction(
6525 thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
6526 vec![&mut account_account, &mut mint_account, &mut owner2_account],
6527 )
6528 );
6529
6530 do_process_instruction(
6532 freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
6533 vec![&mut account_account, &mut mint_account, &mut owner_account],
6534 )
6535 .unwrap();
6536 let account = Account::unpack_unchecked(&account_account.data).unwrap();
6537 assert_eq!(account.state, AccountState::Frozen);
6538
6539 assert_eq!(
6541 Err(TokenError::InvalidState.into()),
6542 do_process_instruction(
6543 freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
6544 vec![&mut account_account, &mut mint_account, &mut owner_account],
6545 )
6546 );
6547
6548 assert_eq!(
6550 Err(TokenError::OwnerMismatch.into()),
6551 do_process_instruction(
6552 thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
6553 vec![&mut account_account, &mut mint_account, &mut owner2_account],
6554 )
6555 );
6556
6557 do_process_instruction(
6559 thaw_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
6560 vec![&mut account_account, &mut mint_account, &mut owner_account],
6561 )
6562 .unwrap();
6563 let account = Account::unpack_unchecked(&account_account.data).unwrap();
6564 assert_eq!(account.state, AccountState::Initialized);
6565 }
6566
6567 #[test]
6568 fn test_initialize_account2_and_3() {
6569 let program_id = crate::id();
6570 let account_key = Pubkey::new_unique();
6571 let mut account_account = MiralandAccount::new(
6572 account_minimum_balance(),
6573 Account::get_packed_len(),
6574 &program_id,
6575 );
6576 let mut account2_account = MiralandAccount::new(
6577 account_minimum_balance(),
6578 Account::get_packed_len(),
6579 &program_id,
6580 );
6581 let mut account3_account = MiralandAccount::new(
6582 account_minimum_balance(),
6583 Account::get_packed_len(),
6584 &program_id,
6585 );
6586 let owner_key = Pubkey::new_unique();
6587 let mut owner_account = MiralandAccount::default();
6588 let mint_key = Pubkey::new_unique();
6589 let mut mint_account =
6590 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6591 let mut rent_sysvar = rent_sysvar();
6592
6593 do_process_instruction(
6595 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6596 vec![&mut mint_account, &mut rent_sysvar],
6597 )
6598 .unwrap();
6599
6600 do_process_instruction(
6601 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6602 vec![
6603 &mut account_account,
6604 &mut mint_account,
6605 &mut owner_account,
6606 &mut rent_sysvar,
6607 ],
6608 )
6609 .unwrap();
6610
6611 do_process_instruction(
6612 initialize_account2(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6613 vec![&mut account2_account, &mut mint_account, &mut rent_sysvar],
6614 )
6615 .unwrap();
6616
6617 assert_eq!(account_account, account2_account);
6618
6619 do_process_instruction(
6620 initialize_account3(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6621 vec![&mut account3_account, &mut mint_account],
6622 )
6623 .unwrap();
6624
6625 assert_eq!(account_account, account3_account);
6626 }
6627
6628 #[test]
6629 fn test_sync_native() {
6630 let program_id = crate::id();
6631 let mint_key = Pubkey::new_unique();
6632 let mut mint_account =
6633 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6634 let native_account_key = Pubkey::new_unique();
6635 let lamports = 40;
6636 let mut native_account = MiralandAccount::new(
6637 account_minimum_balance() + lamports,
6638 Account::get_packed_len(),
6639 &program_id,
6640 );
6641 let non_native_account_key = Pubkey::new_unique();
6642 let mut non_native_account = MiralandAccount::new(
6643 account_minimum_balance() + 50,
6644 Account::get_packed_len(),
6645 &program_id,
6646 );
6647
6648 let owner_key = Pubkey::new_unique();
6649 let mut owner_account = MiralandAccount::default();
6650 let mut rent_sysvar = rent_sysvar();
6651
6652 do_process_instruction(
6654 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6655 vec![&mut mint_account, &mut rent_sysvar],
6656 )
6657 .unwrap();
6658
6659 do_process_instruction(
6661 initialize_account(&program_id, &non_native_account_key, &mint_key, &owner_key)
6662 .unwrap(),
6663 vec![
6664 &mut non_native_account,
6665 &mut mint_account,
6666 &mut owner_account,
6667 &mut rent_sysvar,
6668 ],
6669 )
6670 .unwrap();
6671
6672 let account = Account::unpack_unchecked(&non_native_account.data).unwrap();
6673 assert!(!account.is_native());
6674 assert_eq!(account.amount, 0);
6675
6676 assert_eq!(
6678 Err(TokenError::NonNativeNotSupported.into()),
6679 do_process_instruction(
6680 sync_native(&program_id, &non_native_account_key,).unwrap(),
6681 vec![&mut non_native_account],
6682 )
6683 );
6684
6685 assert_eq!(
6687 Err(ProgramError::UninitializedAccount),
6688 do_process_instruction(
6689 sync_native(&program_id, &native_account_key,).unwrap(),
6690 vec![&mut native_account],
6691 )
6692 );
6693
6694 do_process_instruction(
6696 initialize_account(
6697 &program_id,
6698 &native_account_key,
6699 &crate::native_mint::id(),
6700 &owner_key,
6701 )
6702 .unwrap(),
6703 vec![
6704 &mut native_account,
6705 &mut mint_account,
6706 &mut owner_account,
6707 &mut rent_sysvar,
6708 ],
6709 )
6710 .unwrap();
6711
6712 let not_program_id = Pubkey::new_unique();
6714 native_account.owner = not_program_id;
6715 assert_eq!(
6716 Err(ProgramError::IncorrectProgramId),
6717 do_process_instruction(
6718 sync_native(&program_id, &native_account_key,).unwrap(),
6719 vec![&mut native_account],
6720 )
6721 );
6722 native_account.owner = program_id;
6723
6724 let account = Account::unpack_unchecked(&native_account.data).unwrap();
6725 assert!(account.is_native());
6726 assert_eq!(account.amount, lamports);
6727
6728 do_process_instruction(
6730 sync_native(&program_id, &native_account_key).unwrap(),
6731 vec![&mut native_account],
6732 )
6733 .unwrap();
6734 let account = Account::unpack_unchecked(&native_account.data).unwrap();
6735 assert_eq!(account.amount, lamports);
6736
6737 let new_lamports = lamports + 50;
6739 native_account.lamports = account_minimum_balance() + new_lamports;
6740
6741 do_process_instruction(
6743 sync_native(&program_id, &native_account_key).unwrap(),
6744 vec![&mut native_account],
6745 )
6746 .unwrap();
6747 let account = Account::unpack_unchecked(&native_account.data).unwrap();
6748 assert_eq!(account.amount, new_lamports);
6749
6750 native_account.lamports -= 1;
6752
6753 assert_eq!(
6755 Err(TokenError::InvalidState.into()),
6756 do_process_instruction(
6757 sync_native(&program_id, &native_account_key,).unwrap(),
6758 vec![&mut native_account],
6759 )
6760 );
6761 }
6762
6763 #[test]
6764 #[serial]
6765 fn test_get_account_data_size() {
6766 let program_id = crate::id();
6768 let owner_key = Pubkey::new_unique();
6769 let mut rent_sysvar = rent_sysvar();
6770 let mut mint_account =
6771 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6772 let mint_key = Pubkey::new_unique();
6773 assert_eq!(
6775 Err(TokenError::InvalidMint.into()),
6776 do_process_instruction(
6777 get_account_data_size(&program_id, &mint_key).unwrap(),
6778 vec![&mut mint_account],
6779 )
6780 );
6781
6782 do_process_instruction(
6783 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6784 vec![&mut mint_account, &mut rent_sysvar],
6785 )
6786 .unwrap();
6787
6788 set_expected_data(Account::LEN.to_le_bytes().to_vec());
6789 do_process_instruction(
6790 get_account_data_size(&program_id, &mint_key).unwrap(),
6791 vec![&mut mint_account],
6792 )
6793 .unwrap();
6794 }
6795
6796 #[test]
6797 fn test_initialize_immutable_owner() {
6798 let program_id = crate::id();
6799 let account_key = Pubkey::new_unique();
6800 let mut account_account = MiralandAccount::new(
6801 account_minimum_balance(),
6802 Account::get_packed_len(),
6803 &program_id,
6804 );
6805 let owner_key = Pubkey::new_unique();
6806 let mut owner_account = MiralandAccount::default();
6807 let mint_key = Pubkey::new_unique();
6808 let mut mint_account =
6809 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6810 let mut rent_sysvar = rent_sysvar();
6811
6812 do_process_instruction(
6814 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6815 vec![&mut mint_account, &mut rent_sysvar],
6816 )
6817 .unwrap();
6818
6819 do_process_instruction(
6821 initialize_immutable_owner(&program_id, &account_key).unwrap(),
6822 vec![&mut account_account],
6823 )
6824 .unwrap();
6825
6826 do_process_instruction(
6828 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6829 vec![
6830 &mut account_account,
6831 &mut mint_account,
6832 &mut owner_account,
6833 &mut rent_sysvar,
6834 ],
6835 )
6836 .unwrap();
6837
6838 assert_eq!(
6840 Err(TokenError::AlreadyInUse.into()),
6841 do_process_instruction(
6842 initialize_immutable_owner(&program_id, &account_key).unwrap(),
6843 vec![&mut account_account],
6844 )
6845 );
6846 }
6847
6848 #[test]
6849 #[serial]
6850 fn test_amount_to_ui_amount() {
6851 let program_id = crate::id();
6852 let owner_key = Pubkey::new_unique();
6853 let mint_key = Pubkey::new_unique();
6854 let mut mint_account =
6855 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6856 let mut rent_sysvar = rent_sysvar();
6857
6858 assert_eq!(
6860 Err(TokenError::InvalidMint.into()),
6861 do_process_instruction(
6862 amount_to_ui_amount(&program_id, &mint_key, 110).unwrap(),
6863 vec![&mut mint_account],
6864 )
6865 );
6866
6867 do_process_instruction(
6869 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6870 vec![&mut mint_account, &mut rent_sysvar],
6871 )
6872 .unwrap();
6873
6874 set_expected_data("0.23".as_bytes().to_vec());
6875 do_process_instruction(
6876 amount_to_ui_amount(&program_id, &mint_key, 23).unwrap(),
6877 vec![&mut mint_account],
6878 )
6879 .unwrap();
6880
6881 set_expected_data("1.1".as_bytes().to_vec());
6882 do_process_instruction(
6883 amount_to_ui_amount(&program_id, &mint_key, 110).unwrap(),
6884 vec![&mut mint_account],
6885 )
6886 .unwrap();
6887
6888 set_expected_data("42".as_bytes().to_vec());
6889 do_process_instruction(
6890 amount_to_ui_amount(&program_id, &mint_key, 4200).unwrap(),
6891 vec![&mut mint_account],
6892 )
6893 .unwrap();
6894
6895 set_expected_data("0".as_bytes().to_vec());
6896 do_process_instruction(
6897 amount_to_ui_amount(&program_id, &mint_key, 0).unwrap(),
6898 vec![&mut mint_account],
6899 )
6900 .unwrap();
6901 }
6902
6903 #[test]
6904 #[serial]
6905 fn test_ui_amount_to_amount() {
6906 let program_id = crate::id();
6907 let owner_key = Pubkey::new_unique();
6908 let mint_key = Pubkey::new_unique();
6909 let mut mint_account =
6910 MiralandAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6911 let mut rent_sysvar = rent_sysvar();
6912
6913 assert_eq!(
6915 Err(TokenError::InvalidMint.into()),
6916 do_process_instruction(
6917 ui_amount_to_amount(&program_id, &mint_key, "1.1").unwrap(),
6918 vec![&mut mint_account],
6919 )
6920 );
6921
6922 do_process_instruction(
6924 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6925 vec![&mut mint_account, &mut rent_sysvar],
6926 )
6927 .unwrap();
6928
6929 set_expected_data(23u64.to_le_bytes().to_vec());
6930 do_process_instruction(
6931 ui_amount_to_amount(&program_id, &mint_key, "0.23").unwrap(),
6932 vec![&mut mint_account],
6933 )
6934 .unwrap();
6935
6936 set_expected_data(20u64.to_le_bytes().to_vec());
6937 do_process_instruction(
6938 ui_amount_to_amount(&program_id, &mint_key, "0.20").unwrap(),
6939 vec![&mut mint_account],
6940 )
6941 .unwrap();
6942
6943 set_expected_data(20u64.to_le_bytes().to_vec());
6944 do_process_instruction(
6945 ui_amount_to_amount(&program_id, &mint_key, "0.2000").unwrap(),
6946 vec![&mut mint_account],
6947 )
6948 .unwrap();
6949
6950 set_expected_data(20u64.to_le_bytes().to_vec());
6951 do_process_instruction(
6952 ui_amount_to_amount(&program_id, &mint_key, ".20").unwrap(),
6953 vec![&mut mint_account],
6954 )
6955 .unwrap();
6956
6957 set_expected_data(110u64.to_le_bytes().to_vec());
6958 do_process_instruction(
6959 ui_amount_to_amount(&program_id, &mint_key, "1.1").unwrap(),
6960 vec![&mut mint_account],
6961 )
6962 .unwrap();
6963
6964 set_expected_data(110u64.to_le_bytes().to_vec());
6965 do_process_instruction(
6966 ui_amount_to_amount(&program_id, &mint_key, "1.10").unwrap(),
6967 vec![&mut mint_account],
6968 )
6969 .unwrap();
6970
6971 set_expected_data(4200u64.to_le_bytes().to_vec());
6972 do_process_instruction(
6973 ui_amount_to_amount(&program_id, &mint_key, "42").unwrap(),
6974 vec![&mut mint_account],
6975 )
6976 .unwrap();
6977
6978 set_expected_data(4200u64.to_le_bytes().to_vec());
6979 do_process_instruction(
6980 ui_amount_to_amount(&program_id, &mint_key, "42.").unwrap(),
6981 vec![&mut mint_account],
6982 )
6983 .unwrap();
6984
6985 set_expected_data(0u64.to_le_bytes().to_vec());
6986 do_process_instruction(
6987 ui_amount_to_amount(&program_id, &mint_key, "0").unwrap(),
6988 vec![&mut mint_account],
6989 )
6990 .unwrap();
6991
6992 assert_eq!(
6994 Err(ProgramError::InvalidArgument),
6995 do_process_instruction(
6996 ui_amount_to_amount(&program_id, &mint_key, "").unwrap(),
6997 vec![&mut mint_account],
6998 )
6999 );
7000 assert_eq!(
7001 Err(ProgramError::InvalidArgument),
7002 do_process_instruction(
7003 ui_amount_to_amount(&program_id, &mint_key, ".").unwrap(),
7004 vec![&mut mint_account],
7005 )
7006 );
7007 assert_eq!(
7008 Err(ProgramError::InvalidArgument),
7009 do_process_instruction(
7010 ui_amount_to_amount(&program_id, &mint_key, "0.111").unwrap(),
7011 vec![&mut mint_account],
7012 )
7013 );
7014 assert_eq!(
7015 Err(ProgramError::InvalidArgument),
7016 do_process_instruction(
7017 ui_amount_to_amount(&program_id, &mint_key, "0.t").unwrap(),
7018 vec![&mut mint_account],
7019 )
7020 );
7021 }
7022}