1use crate::{
4 error::TokenError,
5 instruction::{is_valid_signer_index, AuthorityType, TokenInstruction, MAX_SIGNERS},
6 state::{Account, AccountState, Mint, Multisig},
7};
8use num_traits::FromPrimitive;
9use gemachain_program::{
10 account_info::{next_account_info, AccountInfo},
11 decode_error::DecodeError,
12 entrypoint::ProgramResult,
13 msg,
14 program_error::{PrintProgramError, ProgramError},
15 program_option::COption,
16 program_pack::{IsInitialized, Pack},
17 pubkey::Pubkey,
18 sysvar::{rent::Rent, Sysvar},
19};
20
21pub struct Processor {}
23impl Processor {
24 fn _process_initialize_mint(
25 accounts: &[AccountInfo],
26 decimals: u8,
27 mint_authority: Pubkey,
28 freeze_authority: COption<Pubkey>,
29 rent_sysvar_account: bool,
30 ) -> ProgramResult {
31 let account_info_iter = &mut accounts.iter();
32 let mint_info = next_account_info(account_info_iter)?;
33 let mint_data_len = mint_info.data_len();
34 let rent = if rent_sysvar_account {
35 Rent::from_account_info(next_account_info(account_info_iter)?)?
36 } else {
37 Rent::get()?
38 };
39
40 let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow())?;
41 if mint.is_initialized {
42 return Err(TokenError::AlreadyInUse.into());
43 }
44
45 if !rent.is_exempt(mint_info.carats(), mint_data_len) {
46 return Err(TokenError::NotRentExempt.into());
47 }
48
49 mint.mint_authority = COption::Some(mint_authority);
50 mint.decimals = decimals;
51 mint.is_initialized = true;
52 mint.freeze_authority = freeze_authority;
53
54 Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
55
56 Ok(())
57 }
58
59 pub fn process_initialize_mint(
61 accounts: &[AccountInfo],
62 decimals: u8,
63 mint_authority: Pubkey,
64 freeze_authority: COption<Pubkey>,
65 ) -> ProgramResult {
66 Self::_process_initialize_mint(accounts, decimals, mint_authority, freeze_authority, true)
67 }
68
69 pub fn process_initialize_mint2(
71 accounts: &[AccountInfo],
72 decimals: u8,
73 mint_authority: Pubkey,
74 freeze_authority: COption<Pubkey>,
75 ) -> ProgramResult {
76 Self::_process_initialize_mint(accounts, decimals, mint_authority, freeze_authority, false)
77 }
78
79 fn _process_initialize_account(
80 accounts: &[AccountInfo],
81 owner: Option<&Pubkey>,
82 rent_sysvar_account: bool,
83 ) -> ProgramResult {
84 let account_info_iter = &mut accounts.iter();
85 let new_account_info = next_account_info(account_info_iter)?;
86 let mint_info = next_account_info(account_info_iter)?;
87 let owner = if let Some(owner) = owner {
88 owner
89 } else {
90 next_account_info(account_info_iter)?.key
91 };
92 let new_account_info_data_len = new_account_info.data_len();
93 let rent = if rent_sysvar_account {
94 Rent::from_account_info(next_account_info(account_info_iter)?)?
95 } else {
96 Rent::get()?
97 };
98
99 let mut account = Account::unpack_unchecked(&new_account_info.data.borrow())?;
100 if account.is_initialized() {
101 return Err(TokenError::AlreadyInUse.into());
102 }
103
104 if !rent.is_exempt(new_account_info.carats(), new_account_info_data_len) {
105 return Err(TokenError::NotRentExempt.into());
106 }
107
108 if *mint_info.key != crate::native_mint::id() {
109 let _ = Mint::unpack(&mint_info.data.borrow_mut())
110 .map_err(|_| Into::<ProgramError>::into(TokenError::InvalidMint))?;
111 }
112
113 account.mint = *mint_info.key;
114 account.owner = *owner;
115 account.delegate = COption::None;
116 account.delegated_amount = 0;
117 account.state = AccountState::Initialized;
118 if *mint_info.key == crate::native_mint::id() {
119 let rent_exempt_reserve = rent.minimum_balance(new_account_info_data_len);
120 account.is_native = COption::Some(rent_exempt_reserve);
121 account.amount = new_account_info
122 .carats()
123 .checked_sub(rent_exempt_reserve)
124 .ok_or(TokenError::Overflow)?;
125 } else {
126 account.is_native = COption::None;
127 account.amount = 0;
128 };
129
130 Account::pack(account, &mut new_account_info.data.borrow_mut())?;
131
132 Ok(())
133 }
134
135 pub fn process_initialize_account(accounts: &[AccountInfo]) -> ProgramResult {
137 Self::_process_initialize_account(accounts, None, true)
138 }
139
140 pub fn process_initialize_account2(accounts: &[AccountInfo], owner: Pubkey) -> ProgramResult {
142 Self::_process_initialize_account(accounts, Some(&owner), true)
143 }
144
145 pub fn process_initialize_account3(accounts: &[AccountInfo], owner: Pubkey) -> ProgramResult {
147 Self::_process_initialize_account(accounts, Some(&owner), false)
148 }
149
150 fn _process_initialize_multisig(
151 accounts: &[AccountInfo],
152 m: u8,
153 rent_sysvar_account: bool,
154 ) -> ProgramResult {
155 let account_info_iter = &mut accounts.iter();
156 let multisig_info = next_account_info(account_info_iter)?;
157 let multisig_info_data_len = multisig_info.data_len();
158 let rent = if rent_sysvar_account {
159 Rent::from_account_info(next_account_info(account_info_iter)?)?
160 } else {
161 Rent::get()?
162 };
163
164 let mut multisig = Multisig::unpack_unchecked(&multisig_info.data.borrow())?;
165 if multisig.is_initialized {
166 return Err(TokenError::AlreadyInUse.into());
167 }
168
169 if !rent.is_exempt(multisig_info.carats(), multisig_info_data_len) {
170 return Err(TokenError::NotRentExempt.into());
171 }
172
173 let signer_infos = account_info_iter.as_slice();
174 multisig.m = m;
175 multisig.n = signer_infos.len() as u8;
176 if !is_valid_signer_index(multisig.n as usize) {
177 return Err(TokenError::InvalidNumberOfProvidedSigners.into());
178 }
179 if !is_valid_signer_index(multisig.m as usize) {
180 return Err(TokenError::InvalidNumberOfRequiredSigners.into());
181 }
182 for (i, signer_info) in signer_infos.iter().enumerate() {
183 multisig.signers[i] = *signer_info.key;
184 }
185 multisig.is_initialized = true;
186
187 Multisig::pack(multisig, &mut multisig_info.data.borrow_mut())?;
188
189 Ok(())
190 }
191
192 pub fn process_initialize_multisig(accounts: &[AccountInfo], m: u8) -> ProgramResult {
194 Self::_process_initialize_multisig(accounts, m, true)
195 }
196
197 pub fn process_initialize_multisig2(accounts: &[AccountInfo], m: u8) -> ProgramResult {
199 Self::_process_initialize_multisig(accounts, m, false)
200 }
201
202 pub fn process_transfer(
204 program_id: &Pubkey,
205 accounts: &[AccountInfo],
206 amount: u64,
207 expected_decimals: Option<u8>,
208 ) -> ProgramResult {
209 let account_info_iter = &mut accounts.iter();
210
211 let source_account_info = next_account_info(account_info_iter)?;
212
213 let expected_mint_info = if let Some(expected_decimals) = expected_decimals {
214 Some((next_account_info(account_info_iter)?, expected_decimals))
215 } else {
216 None
217 };
218
219 let dest_account_info = next_account_info(account_info_iter)?;
220 let authority_info = next_account_info(account_info_iter)?;
221
222 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
223 let mut dest_account = Account::unpack(&dest_account_info.data.borrow())?;
224
225 if source_account.is_frozen() || dest_account.is_frozen() {
226 return Err(TokenError::AccountFrozen.into());
227 }
228 if source_account.amount < amount {
229 return Err(TokenError::InsufficientFunds.into());
230 }
231 if source_account.mint != dest_account.mint {
232 return Err(TokenError::MintMismatch.into());
233 }
234
235 if let Some((mint_info, expected_decimals)) = expected_mint_info {
236 if source_account.mint != *mint_info.key {
237 return Err(TokenError::MintMismatch.into());
238 }
239
240 let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
241 if expected_decimals != mint.decimals {
242 return Err(TokenError::MintDecimalsMismatch.into());
243 }
244 }
245
246 let self_transfer = source_account_info.key == dest_account_info.key;
247
248 match source_account.delegate {
249 COption::Some(ref delegate) if authority_info.key == delegate => {
250 Self::validate_owner(
251 program_id,
252 delegate,
253 authority_info,
254 account_info_iter.as_slice(),
255 )?;
256 if source_account.delegated_amount < amount {
257 return Err(TokenError::InsufficientFunds.into());
258 }
259 if !self_transfer {
260 source_account.delegated_amount = source_account
261 .delegated_amount
262 .checked_sub(amount)
263 .ok_or(TokenError::Overflow)?;
264 if source_account.delegated_amount == 0 {
265 source_account.delegate = COption::None;
266 }
267 }
268 }
269 _ => Self::validate_owner(
270 program_id,
271 &source_account.owner,
272 authority_info,
273 account_info_iter.as_slice(),
274 )?,
275 };
276
277 if self_transfer {
280 return Ok(());
281 }
282
283 source_account.amount = source_account
284 .amount
285 .checked_sub(amount)
286 .ok_or(TokenError::Overflow)?;
287 dest_account.amount = dest_account
288 .amount
289 .checked_add(amount)
290 .ok_or(TokenError::Overflow)?;
291
292 if source_account.is_native() {
293 let source_starting_carats = source_account_info.carats();
294 **source_account_info.carats.borrow_mut() = source_starting_carats
295 .checked_sub(amount)
296 .ok_or(TokenError::Overflow)?;
297
298 let dest_starting_carats = dest_account_info.carats();
299 **dest_account_info.carats.borrow_mut() = dest_starting_carats
300 .checked_add(amount)
301 .ok_or(TokenError::Overflow)?;
302 }
303
304 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
305 Account::pack(dest_account, &mut dest_account_info.data.borrow_mut())?;
306
307 Ok(())
308 }
309
310 pub fn process_approve(
312 program_id: &Pubkey,
313 accounts: &[AccountInfo],
314 amount: u64,
315 expected_decimals: Option<u8>,
316 ) -> ProgramResult {
317 let account_info_iter = &mut accounts.iter();
318
319 let source_account_info = next_account_info(account_info_iter)?;
320
321 let expected_mint_info = if let Some(expected_decimals) = expected_decimals {
322 Some((next_account_info(account_info_iter)?, expected_decimals))
323 } else {
324 None
325 };
326 let delegate_info = next_account_info(account_info_iter)?;
327 let owner_info = next_account_info(account_info_iter)?;
328
329 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
330
331 if source_account.is_frozen() {
332 return Err(TokenError::AccountFrozen.into());
333 }
334
335 if let Some((mint_info, expected_decimals)) = expected_mint_info {
336 if source_account.mint != *mint_info.key {
337 return Err(TokenError::MintMismatch.into());
338 }
339
340 let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
341 if expected_decimals != mint.decimals {
342 return Err(TokenError::MintDecimalsMismatch.into());
343 }
344 }
345
346 Self::validate_owner(
347 program_id,
348 &source_account.owner,
349 owner_info,
350 account_info_iter.as_slice(),
351 )?;
352
353 source_account.delegate = COption::Some(*delegate_info.key);
354 source_account.delegated_amount = amount;
355
356 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
357
358 Ok(())
359 }
360
361 pub fn process_revoke(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
363 let account_info_iter = &mut accounts.iter();
364 let source_account_info = next_account_info(account_info_iter)?;
365
366 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
367
368 let owner_info = next_account_info(account_info_iter)?;
369
370 if source_account.is_frozen() {
371 return Err(TokenError::AccountFrozen.into());
372 }
373
374 Self::validate_owner(
375 program_id,
376 &source_account.owner,
377 owner_info,
378 account_info_iter.as_slice(),
379 )?;
380
381 source_account.delegate = COption::None;
382 source_account.delegated_amount = 0;
383
384 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
385
386 Ok(())
387 }
388
389 pub fn process_set_authority(
391 program_id: &Pubkey,
392 accounts: &[AccountInfo],
393 authority_type: AuthorityType,
394 new_authority: COption<Pubkey>,
395 ) -> ProgramResult {
396 let account_info_iter = &mut accounts.iter();
397 let account_info = next_account_info(account_info_iter)?;
398 let authority_info = next_account_info(account_info_iter)?;
399
400 if account_info.data_len() == Account::get_packed_len() {
401 let mut account = Account::unpack(&account_info.data.borrow())?;
402
403 if account.is_frozen() {
404 return Err(TokenError::AccountFrozen.into());
405 }
406
407 match authority_type {
408 AuthorityType::AccountOwner => {
409 Self::validate_owner(
410 program_id,
411 &account.owner,
412 authority_info,
413 account_info_iter.as_slice(),
414 )?;
415
416 if let COption::Some(authority) = new_authority {
417 account.owner = authority;
418 } else {
419 return Err(TokenError::InvalidInstruction.into());
420 }
421
422 account.delegate = COption::None;
423 account.delegated_amount = 0;
424
425 if account.is_native() {
426 account.close_authority = COption::None;
427 }
428 }
429 AuthorityType::CloseAccount => {
430 let authority = account.close_authority.unwrap_or(account.owner);
431 Self::validate_owner(
432 program_id,
433 &authority,
434 authority_info,
435 account_info_iter.as_slice(),
436 )?;
437 account.close_authority = new_authority;
438 }
439 _ => {
440 return Err(TokenError::AuthorityTypeNotSupported.into());
441 }
442 }
443 Account::pack(account, &mut account_info.data.borrow_mut())?;
444 } else if account_info.data_len() == Mint::get_packed_len() {
445 let mut mint = Mint::unpack(&account_info.data.borrow())?;
446 match authority_type {
447 AuthorityType::MintTokens => {
448 let mint_authority = mint
451 .mint_authority
452 .ok_or(Into::<ProgramError>::into(TokenError::FixedSupply))?;
453 Self::validate_owner(
454 program_id,
455 &mint_authority,
456 authority_info,
457 account_info_iter.as_slice(),
458 )?;
459 mint.mint_authority = new_authority;
460 }
461 AuthorityType::FreezeAccount => {
462 let freeze_authority = mint
465 .freeze_authority
466 .ok_or(Into::<ProgramError>::into(TokenError::MintCannotFreeze))?;
467 Self::validate_owner(
468 program_id,
469 &freeze_authority,
470 authority_info,
471 account_info_iter.as_slice(),
472 )?;
473 mint.freeze_authority = new_authority;
474 }
475 _ => {
476 return Err(TokenError::AuthorityTypeNotSupported.into());
477 }
478 }
479 Mint::pack(mint, &mut account_info.data.borrow_mut())?;
480 } else {
481 return Err(ProgramError::InvalidArgument);
482 }
483
484 Ok(())
485 }
486
487 pub fn process_mint_to(
489 program_id: &Pubkey,
490 accounts: &[AccountInfo],
491 amount: u64,
492 expected_decimals: Option<u8>,
493 ) -> ProgramResult {
494 let account_info_iter = &mut accounts.iter();
495 let mint_info = next_account_info(account_info_iter)?;
496 let dest_account_info = next_account_info(account_info_iter)?;
497 let owner_info = next_account_info(account_info_iter)?;
498
499 let mut dest_account = Account::unpack(&dest_account_info.data.borrow())?;
500 if dest_account.is_frozen() {
501 return Err(TokenError::AccountFrozen.into());
502 }
503
504 if dest_account.is_native() {
505 return Err(TokenError::NativeNotSupported.into());
506 }
507 if mint_info.key != &dest_account.mint {
508 return Err(TokenError::MintMismatch.into());
509 }
510
511 let mut mint = Mint::unpack(&mint_info.data.borrow())?;
512 if let Some(expected_decimals) = expected_decimals {
513 if expected_decimals != mint.decimals {
514 return Err(TokenError::MintDecimalsMismatch.into());
515 }
516 }
517
518 match mint.mint_authority {
519 COption::Some(mint_authority) => Self::validate_owner(
520 program_id,
521 &mint_authority,
522 owner_info,
523 account_info_iter.as_slice(),
524 )?,
525 COption::None => return Err(TokenError::FixedSupply.into()),
526 }
527
528 dest_account.amount = dest_account
529 .amount
530 .checked_add(amount)
531 .ok_or(TokenError::Overflow)?;
532
533 mint.supply = mint
534 .supply
535 .checked_add(amount)
536 .ok_or(TokenError::Overflow)?;
537
538 Account::pack(dest_account, &mut dest_account_info.data.borrow_mut())?;
539 Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
540
541 Ok(())
542 }
543
544 pub fn process_burn(
546 program_id: &Pubkey,
547 accounts: &[AccountInfo],
548 amount: u64,
549 expected_decimals: Option<u8>,
550 ) -> ProgramResult {
551 let account_info_iter = &mut accounts.iter();
552
553 let source_account_info = next_account_info(account_info_iter)?;
554 let mint_info = next_account_info(account_info_iter)?;
555 let authority_info = next_account_info(account_info_iter)?;
556
557 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
558 let mut mint = Mint::unpack(&mint_info.data.borrow())?;
559
560 if source_account.is_frozen() {
561 return Err(TokenError::AccountFrozen.into());
562 }
563 if source_account.is_native() {
564 return Err(TokenError::NativeNotSupported.into());
565 }
566 if source_account.amount < amount {
567 return Err(TokenError::InsufficientFunds.into());
568 }
569 if mint_info.key != &source_account.mint {
570 return Err(TokenError::MintMismatch.into());
571 }
572
573 if let Some(expected_decimals) = expected_decimals {
574 if expected_decimals != mint.decimals {
575 return Err(TokenError::MintDecimalsMismatch.into());
576 }
577 }
578
579 match source_account.delegate {
580 COption::Some(ref delegate) if authority_info.key == delegate => {
581 Self::validate_owner(
582 program_id,
583 delegate,
584 authority_info,
585 account_info_iter.as_slice(),
586 )?;
587
588 if source_account.delegated_amount < amount {
589 return Err(TokenError::InsufficientFunds.into());
590 }
591 source_account.delegated_amount = source_account
592 .delegated_amount
593 .checked_sub(amount)
594 .ok_or(TokenError::Overflow)?;
595 if source_account.delegated_amount == 0 {
596 source_account.delegate = COption::None;
597 }
598 }
599 _ => Self::validate_owner(
600 program_id,
601 &source_account.owner,
602 authority_info,
603 account_info_iter.as_slice(),
604 )?,
605 }
606
607 source_account.amount = source_account
608 .amount
609 .checked_sub(amount)
610 .ok_or(TokenError::Overflow)?;
611 mint.supply = mint
612 .supply
613 .checked_sub(amount)
614 .ok_or(TokenError::Overflow)?;
615
616 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
617 Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
618
619 Ok(())
620 }
621
622 pub fn process_close_account(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
624 let account_info_iter = &mut accounts.iter();
625 let source_account_info = next_account_info(account_info_iter)?;
626 let dest_account_info = next_account_info(account_info_iter)?;
627 let authority_info = next_account_info(account_info_iter)?;
628
629 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
630 if !source_account.is_native() && source_account.amount != 0 {
631 return Err(TokenError::NonNativeHasBalance.into());
632 }
633
634 let authority = source_account
635 .close_authority
636 .unwrap_or(source_account.owner);
637 Self::validate_owner(
638 program_id,
639 &authority,
640 authority_info,
641 account_info_iter.as_slice(),
642 )?;
643
644 let dest_starting_carats = dest_account_info.carats();
645 **dest_account_info.carats.borrow_mut() = dest_starting_carats
646 .checked_add(source_account_info.carats())
647 .ok_or(TokenError::Overflow)?;
648
649 **source_account_info.carats.borrow_mut() = 0;
650 source_account.amount = 0;
651
652 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
653
654 Ok(())
655 }
656
657 pub fn process_toggle_freeze_account(
660 program_id: &Pubkey,
661 accounts: &[AccountInfo],
662 freeze: bool,
663 ) -> ProgramResult {
664 let account_info_iter = &mut accounts.iter();
665 let source_account_info = next_account_info(account_info_iter)?;
666 let mint_info = next_account_info(account_info_iter)?;
667 let authority_info = next_account_info(account_info_iter)?;
668
669 let mut source_account = Account::unpack(&source_account_info.data.borrow())?;
670 if freeze && source_account.is_frozen() || !freeze && !source_account.is_frozen() {
671 return Err(TokenError::InvalidState.into());
672 }
673 if source_account.is_native() {
674 return Err(TokenError::NativeNotSupported.into());
675 }
676 if mint_info.key != &source_account.mint {
677 return Err(TokenError::MintMismatch.into());
678 }
679
680 let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
681 match mint.freeze_authority {
682 COption::Some(authority) => Self::validate_owner(
683 program_id,
684 &authority,
685 authority_info,
686 account_info_iter.as_slice(),
687 ),
688 COption::None => Err(TokenError::MintCannotFreeze.into()),
689 }?;
690
691 source_account.state = if freeze {
692 AccountState::Frozen
693 } else {
694 AccountState::Initialized
695 };
696
697 Account::pack(source_account, &mut source_account_info.data.borrow_mut())?;
698
699 Ok(())
700 }
701
702 pub fn process_sync_native(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
704 let account_info_iter = &mut accounts.iter();
705 let native_account_info = next_account_info(account_info_iter)?;
706
707 if native_account_info.owner != program_id {
708 return Err(ProgramError::IncorrectProgramId);
709 }
710 let mut native_account = Account::unpack(&native_account_info.data.borrow())?;
711
712 if let COption::Some(rent_exempt_reserve) = native_account.is_native {
713 let new_amount = native_account_info
714 .carats()
715 .checked_sub(rent_exempt_reserve)
716 .ok_or(TokenError::Overflow)?;
717 if new_amount < native_account.amount {
718 return Err(TokenError::InvalidState.into());
719 }
720 native_account.amount = new_amount;
721 } else {
722 return Err(TokenError::NonNativeNotSupported.into());
723 }
724
725 Account::pack(native_account, &mut native_account_info.data.borrow_mut())?;
726 Ok(())
727 }
728
729 pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {
731 let instruction = TokenInstruction::unpack(input)?;
732
733 match instruction {
734 TokenInstruction::InitializeMint {
735 decimals,
736 mint_authority,
737 freeze_authority,
738 } => {
739 msg!("Instruction: InitializeMint");
740 Self::process_initialize_mint(accounts, decimals, mint_authority, freeze_authority)
741 }
742 TokenInstruction::InitializeMint2 {
743 decimals,
744 mint_authority,
745 freeze_authority,
746 } => {
747 msg!("Instruction: InitializeMint2");
748 Self::process_initialize_mint2(accounts, decimals, mint_authority, freeze_authority)
749 }
750 TokenInstruction::InitializeAccount => {
751 msg!("Instruction: InitializeAccount");
752 Self::process_initialize_account(accounts)
753 }
754 TokenInstruction::InitializeAccount2 { owner } => {
755 msg!("Instruction: InitializeAccount2");
756 Self::process_initialize_account2(accounts, owner)
757 }
758 TokenInstruction::InitializeAccount3 { owner } => {
759 msg!("Instruction: InitializeAccount3");
760 Self::process_initialize_account3(accounts, owner)
761 }
762 TokenInstruction::InitializeMultisig { m } => {
763 msg!("Instruction: InitializeMultisig");
764 Self::process_initialize_multisig(accounts, m)
765 }
766 TokenInstruction::InitializeMultisig2 { m } => {
767 msg!("Instruction: InitializeMultisig2");
768 Self::process_initialize_multisig2(accounts, m)
769 }
770 TokenInstruction::Transfer { amount } => {
771 msg!("Instruction: Transfer");
772 Self::process_transfer(program_id, accounts, amount, None)
773 }
774 TokenInstruction::Approve { amount } => {
775 msg!("Instruction: Approve");
776 Self::process_approve(program_id, accounts, amount, None)
777 }
778 TokenInstruction::Revoke => {
779 msg!("Instruction: Revoke");
780 Self::process_revoke(program_id, accounts)
781 }
782 TokenInstruction::SetAuthority {
783 authority_type,
784 new_authority,
785 } => {
786 msg!("Instruction: SetAuthority");
787 Self::process_set_authority(program_id, accounts, authority_type, new_authority)
788 }
789 TokenInstruction::MintTo { amount } => {
790 msg!("Instruction: MintTo");
791 Self::process_mint_to(program_id, accounts, amount, None)
792 }
793 TokenInstruction::Burn { amount } => {
794 msg!("Instruction: Burn");
795 Self::process_burn(program_id, accounts, amount, None)
796 }
797 TokenInstruction::CloseAccount => {
798 msg!("Instruction: CloseAccount");
799 Self::process_close_account(program_id, accounts)
800 }
801 TokenInstruction::FreezeAccount => {
802 msg!("Instruction: FreezeAccount");
803 Self::process_toggle_freeze_account(program_id, accounts, true)
804 }
805 TokenInstruction::ThawAccount => {
806 msg!("Instruction: ThawAccount");
807 Self::process_toggle_freeze_account(program_id, accounts, false)
808 }
809 TokenInstruction::TransferChecked { amount, decimals } => {
810 msg!("Instruction: TransferChecked");
811 Self::process_transfer(program_id, accounts, amount, Some(decimals))
812 }
813 TokenInstruction::ApproveChecked { amount, decimals } => {
814 msg!("Instruction: ApproveChecked");
815 Self::process_approve(program_id, accounts, amount, Some(decimals))
816 }
817 TokenInstruction::MintToChecked { amount, decimals } => {
818 msg!("Instruction: MintToChecked");
819 Self::process_mint_to(program_id, accounts, amount, Some(decimals))
820 }
821 TokenInstruction::BurnChecked { amount, decimals } => {
822 msg!("Instruction: BurnChecked");
823 Self::process_burn(program_id, accounts, amount, Some(decimals))
824 }
825 TokenInstruction::SyncNative => {
826 msg!("Instruction: SyncNative");
827 Self::process_sync_native(program_id, accounts)
828 }
829 }
830 }
831
832 pub fn validate_owner(
834 program_id: &Pubkey,
835 expected_owner: &Pubkey,
836 owner_account_info: &AccountInfo,
837 signers: &[AccountInfo],
838 ) -> ProgramResult {
839 if expected_owner != owner_account_info.key {
840 return Err(TokenError::OwnerMismatch.into());
841 }
842 if program_id == owner_account_info.owner
843 && owner_account_info.data_len() == Multisig::get_packed_len()
844 {
845 let multisig = Multisig::unpack(&owner_account_info.data.borrow())?;
846 let mut num_signers = 0;
847 let mut matched = [false; MAX_SIGNERS];
848 for signer in signers.iter() {
849 for (position, key) in multisig.signers[0..multisig.n as usize].iter().enumerate() {
850 if key == signer.key && !matched[position] {
851 if !signer.is_signer {
852 return Err(ProgramError::MissingRequiredSignature);
853 }
854 matched[position] = true;
855 num_signers += 1;
856 }
857 }
858 }
859 if num_signers < multisig.m {
860 return Err(ProgramError::MissingRequiredSignature);
861 }
862 return Ok(());
863 } else if !owner_account_info.is_signer {
864 return Err(ProgramError::MissingRequiredSignature);
865 }
866 Ok(())
867 }
868}
869
870impl PrintProgramError for TokenError {
871 fn print<E>(&self)
872 where
873 E: 'static + std::error::Error + DecodeError<E> + PrintProgramError + FromPrimitive,
874 {
875 match self {
876 TokenError::NotRentExempt => msg!("Error: Carat balance below rent-exempt threshold"),
877 TokenError::InsufficientFunds => msg!("Error: insufficient funds"),
878 TokenError::InvalidMint => msg!("Error: Invalid Mint"),
879 TokenError::MintMismatch => msg!("Error: Account not associated with this Mint"),
880 TokenError::OwnerMismatch => msg!("Error: owner does not match"),
881 TokenError::FixedSupply => msg!("Error: the total supply of this token is fixed"),
882 TokenError::AlreadyInUse => msg!("Error: account or token already in use"),
883 TokenError::InvalidNumberOfProvidedSigners => {
884 msg!("Error: Invalid number of provided signers")
885 }
886 TokenError::InvalidNumberOfRequiredSigners => {
887 msg!("Error: Invalid number of required signers")
888 }
889 TokenError::UninitializedState => msg!("Error: State is uninitialized"),
890 TokenError::NativeNotSupported => {
891 msg!("Error: Instruction does not support native tokens")
892 }
893 TokenError::NonNativeHasBalance => {
894 msg!("Error: Non-native account can only be closed if its balance is zero")
895 }
896 TokenError::InvalidInstruction => msg!("Error: Invalid instruction"),
897 TokenError::InvalidState => msg!("Error: Invalid account state for operation"),
898 TokenError::Overflow => msg!("Error: Operation overflowed"),
899 TokenError::AuthorityTypeNotSupported => {
900 msg!("Error: Account does not support specified authority type")
901 }
902 TokenError::MintCannotFreeze => msg!("Error: This token mint cannot freeze accounts"),
903 TokenError::AccountFrozen => msg!("Error: Account is frozen"),
904 TokenError::MintDecimalsMismatch => {
905 msg!("Error: decimals different from the Mint decimals")
906 }
907 TokenError::NonNativeNotSupported => {
908 msg!("Error: Instruction does not support non-native tokens")
909 }
910 }
911 }
912}
913
914#[cfg(test)]
915mod tests {
916 use super::*;
917 use crate::instruction::*;
918 use gemachain_program::{
919 account_info::IntoAccountInfo, clock::Epoch, instruction::Instruction, program_error,
920 sysvar::rent,
921 };
922 use gemachain_sdk::account::{
923 create_account_for_test, create_is_signer_account_infos, Account as GemachainAccount,
924 };
925
926 struct SyscallStubs {}
927 impl gemachain_sdk::program_stubs::SyscallStubs for SyscallStubs {
928 fn gema_log(&self, _message: &str) {}
929
930 fn gema_invoke_signed(
931 &self,
932 _instruction: &Instruction,
933 _account_infos: &[AccountInfo],
934 _signers_seeds: &[&[&[u8]]],
935 ) -> ProgramResult {
936 Err(ProgramError::Custom(42)) }
938
939 fn gema_get_clock_sysvar(&self, _var_addr: *mut u8) -> u64 {
940 program_error::UNSUPPORTED_SYSVAR
941 }
942
943 fn gema_get_epoch_schedule_sysvar(&self, _var_addr: *mut u8) -> u64 {
944 program_error::UNSUPPORTED_SYSVAR
945 }
946
947 #[allow(deprecated)]
948 fn gema_get_fees_sysvar(&self, _var_addr: *mut u8) -> u64 {
949 program_error::UNSUPPORTED_SYSVAR
950 }
951
952 fn gema_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 {
953 unsafe {
954 *(var_addr as *mut _ as *mut Rent) = Rent::default();
955 }
956 gemachain_program::entrypoint::SUCCESS
957 }
958 }
959
960 fn do_process_instruction(
961 instruction: Instruction,
962 accounts: Vec<&mut GemachainAccount>,
963 ) -> ProgramResult {
964 {
965 use std::sync::Once;
966 static ONCE: Once = Once::new();
967
968 ONCE.call_once(|| {
969 gemachain_sdk::program_stubs::set_syscall_stubs(Box::new(SyscallStubs {}));
970 });
971 }
972
973 let mut meta = instruction
974 .accounts
975 .iter()
976 .zip(accounts)
977 .map(|(account_meta, account)| (&account_meta.pubkey, account_meta.is_signer, account))
978 .collect::<Vec<_>>();
979
980 let account_infos = create_is_signer_account_infos(&mut meta);
981 Processor::process(&instruction.program_id, &account_infos, &instruction.data)
982 }
983
984 fn do_process_instruction_dups(
985 instruction: Instruction,
986 account_infos: Vec<AccountInfo>,
987 ) -> ProgramResult {
988 Processor::process(&instruction.program_id, &account_infos, &instruction.data)
989 }
990
991 fn return_token_error_as_program_error() -> ProgramError {
992 TokenError::MintMismatch.into()
993 }
994
995 fn rent_sysvar() -> GemachainAccount {
996 create_account_for_test(&Rent::default())
997 }
998
999 fn mint_minimum_balance() -> u64 {
1000 Rent::default().minimum_balance(Mint::get_packed_len())
1001 }
1002
1003 fn account_minimum_balance() -> u64 {
1004 Rent::default().minimum_balance(Account::get_packed_len())
1005 }
1006
1007 fn multisig_minimum_balance() -> u64 {
1008 Rent::default().minimum_balance(Multisig::get_packed_len())
1009 }
1010
1011 #[test]
1012 fn test_print_error() {
1013 let error = return_token_error_as_program_error();
1014 error.print::<TokenError>();
1015 }
1016
1017 #[test]
1018 #[should_panic(expected = "Custom(3)")]
1019 fn test_error_unwrap() {
1020 Err::<(), ProgramError>(return_token_error_as_program_error()).unwrap();
1021 }
1022
1023 #[test]
1024 fn test_unique_account_sizes() {
1025 assert_ne!(Mint::get_packed_len(), 0);
1026 assert_ne!(Mint::get_packed_len(), Account::get_packed_len());
1027 assert_ne!(Mint::get_packed_len(), Multisig::get_packed_len());
1028 assert_ne!(Account::get_packed_len(), 0);
1029 assert_ne!(Account::get_packed_len(), Multisig::get_packed_len());
1030 assert_ne!(Multisig::get_packed_len(), 0);
1031 }
1032
1033 #[test]
1034 fn test_pack_unpack() {
1035 let check = Mint {
1037 mint_authority: COption::Some(Pubkey::new(&[1; 32])),
1038 supply: 42,
1039 decimals: 7,
1040 is_initialized: true,
1041 freeze_authority: COption::Some(Pubkey::new(&[2; 32])),
1042 };
1043 let mut packed = vec![0; Mint::get_packed_len() + 1];
1044 assert_eq!(
1045 Err(ProgramError::InvalidAccountData),
1046 Mint::pack(check, &mut packed)
1047 );
1048 let mut packed = vec![0; Mint::get_packed_len() - 1];
1049 assert_eq!(
1050 Err(ProgramError::InvalidAccountData),
1051 Mint::pack(check, &mut packed)
1052 );
1053 let mut packed = vec![0; Mint::get_packed_len()];
1054 Mint::pack(check, &mut packed).unwrap();
1055 let expect = vec![
1056 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,
1057 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,
1058 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1059 ];
1060 assert_eq!(packed, expect);
1061 let unpacked = Mint::unpack(&packed).unwrap();
1062 assert_eq!(unpacked, check);
1063
1064 let check = Account {
1066 mint: Pubkey::new(&[1; 32]),
1067 owner: Pubkey::new(&[2; 32]),
1068 amount: 3,
1069 delegate: COption::Some(Pubkey::new(&[4; 32])),
1070 state: AccountState::Frozen,
1071 is_native: COption::Some(5),
1072 delegated_amount: 6,
1073 close_authority: COption::Some(Pubkey::new(&[7; 32])),
1074 };
1075 let mut packed = vec![0; Account::get_packed_len() + 1];
1076 assert_eq!(
1077 Err(ProgramError::InvalidAccountData),
1078 Account::pack(check, &mut packed)
1079 );
1080 let mut packed = vec![0; Account::get_packed_len() - 1];
1081 assert_eq!(
1082 Err(ProgramError::InvalidAccountData),
1083 Account::pack(check, &mut packed)
1084 );
1085 let mut packed = vec![0; Account::get_packed_len()];
1086 Account::pack(check, &mut packed).unwrap();
1087 let expect = vec![
1088 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,
1089 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,
1090 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,
1091 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,
1092 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,
1093 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1094 ];
1095 assert_eq!(packed, expect);
1096 let unpacked = Account::unpack(&packed).unwrap();
1097 assert_eq!(unpacked, check);
1098
1099 let check = Multisig {
1101 m: 1,
1102 n: 2,
1103 is_initialized: true,
1104 signers: [Pubkey::new(&[3; 32]); MAX_SIGNERS],
1105 };
1106 let mut packed = vec![0; Multisig::get_packed_len() + 1];
1107 assert_eq!(
1108 Err(ProgramError::InvalidAccountData),
1109 Multisig::pack(check, &mut packed)
1110 );
1111 let mut packed = vec![0; Multisig::get_packed_len() - 1];
1112 assert_eq!(
1113 Err(ProgramError::InvalidAccountData),
1114 Multisig::pack(check, &mut packed)
1115 );
1116 let mut packed = vec![0; Multisig::get_packed_len()];
1117 Multisig::pack(check, &mut packed).unwrap();
1118 let expect = vec![
1119 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,
1120 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,
1121 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,
1122 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,
1123 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,
1124 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,
1125 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,
1126 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,
1127 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,
1128 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,
1129 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,
1130 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,
1131 3, 3, 3, 3, 3, 3, 3,
1132 ];
1133 assert_eq!(packed, expect);
1134 let unpacked = Multisig::unpack(&packed).unwrap();
1135 assert_eq!(unpacked, check);
1136 }
1137
1138 #[test]
1139 fn test_initialize_mint() {
1140 let program_id = crate::id();
1141 let owner_key = Pubkey::new_unique();
1142 let mint_key = Pubkey::new_unique();
1143 let mut mint_account = GemachainAccount::new(42, Mint::get_packed_len(), &program_id);
1144 let mint2_key = Pubkey::new_unique();
1145 let mut mint2_account =
1146 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1147 let mut rent_sysvar = rent_sysvar();
1148
1149 assert_eq!(
1151 Err(TokenError::NotRentExempt.into()),
1152 do_process_instruction(
1153 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1154 vec![&mut mint_account, &mut rent_sysvar]
1155 )
1156 );
1157
1158 mint_account.carats = mint_minimum_balance();
1159
1160 do_process_instruction(
1162 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1163 vec![&mut mint_account, &mut rent_sysvar],
1164 )
1165 .unwrap();
1166
1167 assert_eq!(
1169 Err(TokenError::AlreadyInUse.into()),
1170 do_process_instruction(
1171 initialize_mint(&program_id, &mint_key, &owner_key, None, 2,).unwrap(),
1172 vec![&mut mint_account, &mut rent_sysvar]
1173 )
1174 );
1175
1176 do_process_instruction(
1178 initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
1179 vec![&mut mint2_account, &mut rent_sysvar],
1180 )
1181 .unwrap();
1182 let mint = Mint::unpack_unchecked(&mint2_account.data).unwrap();
1183 assert_eq!(mint.freeze_authority, COption::Some(owner_key));
1184 }
1185
1186 #[test]
1187 fn test_initialize_mint2() {
1188 let program_id = crate::id();
1189 let owner_key = Pubkey::new_unique();
1190 let mint_key = Pubkey::new_unique();
1191 let mut mint_account = GemachainAccount::new(42, Mint::get_packed_len(), &program_id);
1192 let mint2_key = Pubkey::new_unique();
1193 let mut mint2_account =
1194 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1195
1196 assert_eq!(
1198 Err(TokenError::NotRentExempt.into()),
1199 do_process_instruction(
1200 initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1201 vec![&mut mint_account]
1202 )
1203 );
1204
1205 mint_account.carats = mint_minimum_balance();
1206
1207 do_process_instruction(
1209 initialize_mint2(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1210 vec![&mut mint_account],
1211 )
1212 .unwrap();
1213
1214 assert_eq!(
1216 Err(TokenError::AlreadyInUse.into()),
1217 do_process_instruction(
1218 initialize_mint2(&program_id, &mint_key, &owner_key, None, 2,).unwrap(),
1219 vec![&mut mint_account]
1220 )
1221 );
1222
1223 do_process_instruction(
1225 initialize_mint2(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
1226 vec![&mut mint2_account],
1227 )
1228 .unwrap();
1229 let mint = Mint::unpack_unchecked(&mint2_account.data).unwrap();
1230 assert_eq!(mint.freeze_authority, COption::Some(owner_key));
1231 }
1232
1233 #[test]
1234 fn test_initialize_mint_account() {
1235 let program_id = crate::id();
1236 let account_key = Pubkey::new_unique();
1237 let mut account_account = GemachainAccount::new(42, Account::get_packed_len(), &program_id);
1238 let owner_key = Pubkey::new_unique();
1239 let mut owner_account = GemachainAccount::default();
1240 let mint_key = Pubkey::new_unique();
1241 let mut mint_account =
1242 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1243 let mut rent_sysvar = rent_sysvar();
1244
1245 assert_eq!(
1247 Err(TokenError::NotRentExempt.into()),
1248 do_process_instruction(
1249 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1250 vec![
1251 &mut account_account,
1252 &mut mint_account,
1253 &mut owner_account,
1254 &mut rent_sysvar
1255 ],
1256 )
1257 );
1258
1259 account_account.carats = account_minimum_balance();
1260
1261 assert_eq!(
1263 Err(TokenError::InvalidMint.into()),
1264 do_process_instruction(
1265 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1266 vec![
1267 &mut account_account,
1268 &mut mint_account,
1269 &mut owner_account,
1270 &mut rent_sysvar
1271 ],
1272 )
1273 );
1274
1275 do_process_instruction(
1277 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1278 vec![&mut mint_account, &mut rent_sysvar],
1279 )
1280 .unwrap();
1281
1282 do_process_instruction(
1284 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1285 vec![
1286 &mut account_account,
1287 &mut mint_account,
1288 &mut owner_account,
1289 &mut rent_sysvar,
1290 ],
1291 )
1292 .unwrap();
1293
1294 assert_eq!(
1296 Err(TokenError::AlreadyInUse.into()),
1297 do_process_instruction(
1298 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1299 vec![
1300 &mut account_account,
1301 &mut mint_account,
1302 &mut owner_account,
1303 &mut rent_sysvar
1304 ],
1305 )
1306 );
1307 }
1308
1309 #[test]
1310 fn test_transfer_dups() {
1311 let program_id = crate::id();
1312 let account1_key = Pubkey::new_unique();
1313 let mut account1_account = GemachainAccount::new(
1314 account_minimum_balance(),
1315 Account::get_packed_len(),
1316 &program_id,
1317 );
1318 let mut account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
1319 let account2_key = Pubkey::new_unique();
1320 let mut account2_account = GemachainAccount::new(
1321 account_minimum_balance(),
1322 Account::get_packed_len(),
1323 &program_id,
1324 );
1325 let mut account2_info: AccountInfo = (&account2_key, false, &mut account2_account).into();
1326 let account3_key = Pubkey::new_unique();
1327 let mut account3_account = GemachainAccount::new(
1328 account_minimum_balance(),
1329 Account::get_packed_len(),
1330 &program_id,
1331 );
1332 let account3_info: AccountInfo = (&account3_key, false, &mut account3_account).into();
1333 let account4_key = Pubkey::new_unique();
1334 let mut account4_account = GemachainAccount::new(
1335 account_minimum_balance(),
1336 Account::get_packed_len(),
1337 &program_id,
1338 );
1339 let account4_info: AccountInfo = (&account4_key, true, &mut account4_account).into();
1340 let multisig_key = Pubkey::new_unique();
1341 let mut multisig_account = GemachainAccount::new(
1342 multisig_minimum_balance(),
1343 Multisig::get_packed_len(),
1344 &program_id,
1345 );
1346 let multisig_info: AccountInfo = (&multisig_key, true, &mut multisig_account).into();
1347 let owner_key = Pubkey::new_unique();
1348 let mut owner_account = GemachainAccount::default();
1349 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
1350 let mint_key = Pubkey::new_unique();
1351 let mut mint_account =
1352 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1353 let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
1354 let rent_key = rent::id();
1355 let mut rent_sysvar = rent_sysvar();
1356 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
1357
1358 do_process_instruction_dups(
1360 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1361 vec![mint_info.clone(), rent_info.clone()],
1362 )
1363 .unwrap();
1364
1365 do_process_instruction_dups(
1367 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
1368 vec![
1369 account1_info.clone(),
1370 mint_info.clone(),
1371 account1_info.clone(),
1372 rent_info.clone(),
1373 ],
1374 )
1375 .unwrap();
1376
1377 do_process_instruction_dups(
1379 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
1380 vec![
1381 account2_info.clone(),
1382 mint_info.clone(),
1383 owner_info.clone(),
1384 rent_info.clone(),
1385 ],
1386 )
1387 .unwrap();
1388
1389 do_process_instruction_dups(
1391 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
1392 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
1393 )
1394 .unwrap();
1395
1396 do_process_instruction_dups(
1398 transfer(
1399 &program_id,
1400 &account1_key,
1401 &account2_key,
1402 &account1_key,
1403 &[],
1404 500,
1405 )
1406 .unwrap(),
1407 vec![
1408 account1_info.clone(),
1409 account2_info.clone(),
1410 account1_info.clone(),
1411 ],
1412 )
1413 .unwrap();
1414
1415 do_process_instruction_dups(
1417 transfer_checked(
1418 &program_id,
1419 &account1_key,
1420 &mint_key,
1421 &account2_key,
1422 &account1_key,
1423 &[],
1424 500,
1425 2,
1426 )
1427 .unwrap(),
1428 vec![
1429 account1_info.clone(),
1430 mint_info.clone(),
1431 account2_info.clone(),
1432 account1_info.clone(),
1433 ],
1434 )
1435 .unwrap();
1436
1437 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
1439 account.amount = 1000;
1440 account.delegated_amount = 1000;
1441 account.delegate = COption::Some(account1_key);
1442 account.owner = owner_key;
1443 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
1444
1445 do_process_instruction_dups(
1446 transfer(
1447 &program_id,
1448 &account1_key,
1449 &account2_key,
1450 &account1_key,
1451 &[],
1452 500,
1453 )
1454 .unwrap(),
1455 vec![
1456 account1_info.clone(),
1457 account2_info.clone(),
1458 account1_info.clone(),
1459 ],
1460 )
1461 .unwrap();
1462
1463 do_process_instruction_dups(
1465 transfer_checked(
1466 &program_id,
1467 &account1_key,
1468 &mint_key,
1469 &account2_key,
1470 &account1_key,
1471 &[],
1472 500,
1473 2,
1474 )
1475 .unwrap(),
1476 vec![
1477 account1_info.clone(),
1478 mint_info.clone(),
1479 account2_info.clone(),
1480 account1_info.clone(),
1481 ],
1482 )
1483 .unwrap();
1484
1485 do_process_instruction_dups(
1487 initialize_account(&program_id, &account3_key, &mint_key, &account2_key).unwrap(),
1488 vec![
1489 account3_info.clone(),
1490 mint_info.clone(),
1491 account2_info.clone(),
1492 rent_info.clone(),
1493 ],
1494 )
1495 .unwrap();
1496 do_process_instruction_dups(
1497 mint_to(&program_id, &mint_key, &account3_key, &owner_key, &[], 1000).unwrap(),
1498 vec![mint_info.clone(), account3_info.clone(), owner_info.clone()],
1499 )
1500 .unwrap();
1501
1502 account1_info.is_signer = false;
1503 account2_info.is_signer = true;
1504 do_process_instruction_dups(
1505 transfer(
1506 &program_id,
1507 &account3_key,
1508 &account2_key,
1509 &account2_key,
1510 &[],
1511 500,
1512 )
1513 .unwrap(),
1514 vec![
1515 account3_info.clone(),
1516 account2_info.clone(),
1517 account2_info.clone(),
1518 ],
1519 )
1520 .unwrap();
1521
1522 do_process_instruction_dups(
1524 transfer_checked(
1525 &program_id,
1526 &account3_key,
1527 &mint_key,
1528 &account2_key,
1529 &account2_key,
1530 &[],
1531 500,
1532 2,
1533 )
1534 .unwrap(),
1535 vec![
1536 account3_info.clone(),
1537 mint_info.clone(),
1538 account2_info.clone(),
1539 account2_info.clone(),
1540 ],
1541 )
1542 .unwrap();
1543
1544 do_process_instruction_dups(
1546 initialize_multisig(&program_id, &multisig_key, &[&account4_key], 1).unwrap(),
1547 vec![
1548 multisig_info.clone(),
1549 rent_info.clone(),
1550 account4_info.clone(),
1551 ],
1552 )
1553 .unwrap();
1554
1555 do_process_instruction_dups(
1556 initialize_account(&program_id, &account4_key, &mint_key, &multisig_key).unwrap(),
1557 vec![
1558 account4_info.clone(),
1559 mint_info.clone(),
1560 multisig_info.clone(),
1561 rent_info.clone(),
1562 ],
1563 )
1564 .unwrap();
1565
1566 do_process_instruction_dups(
1567 mint_to(&program_id, &mint_key, &account4_key, &owner_key, &[], 1000).unwrap(),
1568 vec![mint_info.clone(), account4_info.clone(), owner_info.clone()],
1569 )
1570 .unwrap();
1571
1572 do_process_instruction_dups(
1574 transfer(
1575 &program_id,
1576 &account4_key,
1577 &account2_key,
1578 &multisig_key,
1579 &[&account4_key],
1580 500,
1581 )
1582 .unwrap(),
1583 vec![
1584 account4_info.clone(),
1585 account2_info.clone(),
1586 multisig_info.clone(),
1587 account4_info.clone(),
1588 ],
1589 )
1590 .unwrap();
1591
1592 do_process_instruction_dups(
1594 transfer_checked(
1595 &program_id,
1596 &account4_key,
1597 &mint_key,
1598 &account2_key,
1599 &multisig_key,
1600 &[&account4_key],
1601 500,
1602 2,
1603 )
1604 .unwrap(),
1605 vec![
1606 account4_info.clone(),
1607 mint_info.clone(),
1608 account2_info.clone(),
1609 multisig_info.clone(),
1610 account4_info.clone(),
1611 ],
1612 )
1613 .unwrap();
1614 }
1615
1616 #[test]
1617 fn test_transfer() {
1618 let program_id = crate::id();
1619 let account_key = Pubkey::new_unique();
1620 let mut account_account = GemachainAccount::new(
1621 account_minimum_balance(),
1622 Account::get_packed_len(),
1623 &program_id,
1624 );
1625 let account2_key = Pubkey::new_unique();
1626 let mut account2_account = GemachainAccount::new(
1627 account_minimum_balance(),
1628 Account::get_packed_len(),
1629 &program_id,
1630 );
1631 let account3_key = Pubkey::new_unique();
1632 let mut account3_account = GemachainAccount::new(
1633 account_minimum_balance(),
1634 Account::get_packed_len(),
1635 &program_id,
1636 );
1637 let delegate_key = Pubkey::new_unique();
1638 let mut delegate_account = GemachainAccount::default();
1639 let mismatch_key = Pubkey::new_unique();
1640 let mut mismatch_account = GemachainAccount::new(
1641 account_minimum_balance(),
1642 Account::get_packed_len(),
1643 &program_id,
1644 );
1645 let owner_key = Pubkey::new_unique();
1646 let mut owner_account = GemachainAccount::default();
1647 let owner2_key = Pubkey::new_unique();
1648 let mut owner2_account = GemachainAccount::default();
1649 let mint_key = Pubkey::new_unique();
1650 let mut mint_account =
1651 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
1652 let mint2_key = Pubkey::new_unique();
1653 let mut rent_sysvar = rent_sysvar();
1654
1655 do_process_instruction(
1657 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
1658 vec![&mut mint_account, &mut rent_sysvar],
1659 )
1660 .unwrap();
1661
1662 do_process_instruction(
1664 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
1665 vec![
1666 &mut account_account,
1667 &mut mint_account,
1668 &mut owner_account,
1669 &mut rent_sysvar,
1670 ],
1671 )
1672 .unwrap();
1673
1674 do_process_instruction(
1676 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
1677 vec![
1678 &mut account2_account,
1679 &mut mint_account,
1680 &mut owner_account,
1681 &mut rent_sysvar,
1682 ],
1683 )
1684 .unwrap();
1685
1686 do_process_instruction(
1688 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
1689 vec![
1690 &mut account3_account,
1691 &mut mint_account,
1692 &mut owner_account,
1693 &mut rent_sysvar,
1694 ],
1695 )
1696 .unwrap();
1697
1698 do_process_instruction(
1700 initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
1701 vec![
1702 &mut mismatch_account,
1703 &mut mint_account,
1704 &mut owner_account,
1705 &mut rent_sysvar,
1706 ],
1707 )
1708 .unwrap();
1709 let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
1710 account.mint = mint2_key;
1711 Account::pack(account, &mut mismatch_account.data).unwrap();
1712
1713 do_process_instruction(
1715 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
1716 vec![&mut mint_account, &mut account_account, &mut owner_account],
1717 )
1718 .unwrap();
1719
1720 let mut instruction = transfer(
1722 &program_id,
1723 &account_key,
1724 &account2_key,
1725 &owner_key,
1726 &[],
1727 1000,
1728 )
1729 .unwrap();
1730 instruction.accounts[2].is_signer = false;
1731 assert_eq!(
1732 Err(ProgramError::MissingRequiredSignature),
1733 do_process_instruction(
1734 instruction,
1735 vec![
1736 &mut account_account,
1737 &mut account2_account,
1738 &mut owner_account,
1739 ],
1740 )
1741 );
1742
1743 assert_eq!(
1745 Err(TokenError::MintMismatch.into()),
1746 do_process_instruction(
1747 transfer(
1748 &program_id,
1749 &account_key,
1750 &mismatch_key,
1751 &owner_key,
1752 &[],
1753 1000
1754 )
1755 .unwrap(),
1756 vec![
1757 &mut account_account,
1758 &mut mismatch_account,
1759 &mut owner_account,
1760 ],
1761 )
1762 );
1763
1764 assert_eq!(
1766 Err(TokenError::OwnerMismatch.into()),
1767 do_process_instruction(
1768 transfer(
1769 &program_id,
1770 &account_key,
1771 &account2_key,
1772 &owner2_key,
1773 &[],
1774 1000
1775 )
1776 .unwrap(),
1777 vec![
1778 &mut account_account,
1779 &mut account2_account,
1780 &mut owner2_account,
1781 ],
1782 )
1783 );
1784
1785 do_process_instruction(
1787 transfer(
1788 &program_id,
1789 &account_key,
1790 &account2_key,
1791 &owner_key,
1792 &[],
1793 1000,
1794 )
1795 .unwrap(),
1796 vec![
1797 &mut account_account,
1798 &mut account2_account,
1799 &mut owner_account,
1800 ],
1801 )
1802 .unwrap();
1803
1804 assert_eq!(
1806 Err(TokenError::InsufficientFunds.into()),
1807 do_process_instruction(
1808 transfer(&program_id, &account_key, &account2_key, &owner_key, &[], 1).unwrap(),
1809 vec![
1810 &mut account_account,
1811 &mut account2_account,
1812 &mut owner_account,
1813 ],
1814 )
1815 );
1816
1817 do_process_instruction(
1819 transfer(
1820 &program_id,
1821 &account2_key,
1822 &account_key,
1823 &owner_key,
1824 &[],
1825 500,
1826 )
1827 .unwrap(),
1828 vec![
1829 &mut account2_account,
1830 &mut account_account,
1831 &mut owner_account,
1832 ],
1833 )
1834 .unwrap();
1835
1836 assert_eq!(
1838 Err(TokenError::MintDecimalsMismatch.into()),
1839 do_process_instruction(
1840 transfer_checked(
1841 &program_id,
1842 &account2_key,
1843 &mint_key,
1844 &account_key,
1845 &owner_key,
1846 &[],
1847 1,
1848 10 )
1850 .unwrap(),
1851 vec![
1852 &mut account2_account,
1853 &mut mint_account,
1854 &mut account_account,
1855 &mut owner_account,
1856 ],
1857 )
1858 );
1859
1860 assert_eq!(
1862 Err(TokenError::MintMismatch.into()),
1863 do_process_instruction(
1864 transfer_checked(
1865 &program_id,
1866 &account2_key,
1867 &account3_key, &account_key,
1869 &owner_key,
1870 &[],
1871 1,
1872 2
1873 )
1874 .unwrap(),
1875 vec![
1876 &mut account2_account,
1877 &mut account3_account, &mut account_account,
1879 &mut owner_account,
1880 ],
1881 )
1882 );
1883 do_process_instruction(
1885 transfer_checked(
1886 &program_id,
1887 &account2_key,
1888 &mint_key,
1889 &account_key,
1890 &owner_key,
1891 &[],
1892 500,
1893 2,
1894 )
1895 .unwrap(),
1896 vec![
1897 &mut account2_account,
1898 &mut mint_account,
1899 &mut account_account,
1900 &mut owner_account,
1901 ],
1902 )
1903 .unwrap();
1904
1905 assert_eq!(
1907 Err(TokenError::InsufficientFunds.into()),
1908 do_process_instruction(
1909 transfer(&program_id, &account2_key, &account_key, &owner_key, &[], 1).unwrap(),
1910 vec![
1911 &mut account2_account,
1912 &mut account_account,
1913 &mut owner_account,
1914 ],
1915 )
1916 );
1917
1918 do_process_instruction(
1920 approve(
1921 &program_id,
1922 &account_key,
1923 &delegate_key,
1924 &owner_key,
1925 &[],
1926 100,
1927 )
1928 .unwrap(),
1929 vec![
1930 &mut account_account,
1931 &mut delegate_account,
1932 &mut owner_account,
1933 ],
1934 )
1935 .unwrap();
1936
1937 do_process_instruction(
1939 transfer(
1940 &program_id,
1941 &account_key,
1942 &account2_key,
1943 &delegate_key,
1944 &[],
1945 100,
1946 )
1947 .unwrap(),
1948 vec![
1949 &mut account_account,
1950 &mut account2_account,
1951 &mut delegate_account,
1952 ],
1953 )
1954 .unwrap();
1955
1956 assert_eq!(
1958 Err(TokenError::OwnerMismatch.into()),
1959 do_process_instruction(
1960 transfer(
1961 &program_id,
1962 &account_key,
1963 &account2_key,
1964 &delegate_key,
1965 &[],
1966 100
1967 )
1968 .unwrap(),
1969 vec![
1970 &mut account_account,
1971 &mut account2_account,
1972 &mut delegate_account,
1973 ],
1974 )
1975 );
1976
1977 do_process_instruction(
1979 transfer(
1980 &program_id,
1981 &account_key,
1982 &account2_key,
1983 &owner_key,
1984 &[],
1985 900,
1986 )
1987 .unwrap(),
1988 vec![
1989 &mut account_account,
1990 &mut account2_account,
1991 &mut owner_account,
1992 ],
1993 )
1994 .unwrap();
1995
1996 do_process_instruction(
1998 approve(
1999 &program_id,
2000 &account_key,
2001 &delegate_key,
2002 &owner_key,
2003 &[],
2004 100,
2005 )
2006 .unwrap(),
2007 vec![
2008 &mut account_account,
2009 &mut delegate_account,
2010 &mut owner_account,
2011 ],
2012 )
2013 .unwrap();
2014
2015 assert_eq!(
2017 Err(TokenError::InsufficientFunds.into()),
2018 do_process_instruction(
2019 transfer(
2020 &program_id,
2021 &account_key,
2022 &account2_key,
2023 &delegate_key,
2024 &[],
2025 100
2026 )
2027 .unwrap(),
2028 vec![
2029 &mut account_account,
2030 &mut account2_account,
2031 &mut delegate_account,
2032 ],
2033 )
2034 );
2035 }
2036
2037 #[test]
2038 fn test_self_transfer() {
2039 let program_id = crate::id();
2040 let account_key = Pubkey::new_unique();
2041 let mut account_account = GemachainAccount::new(
2042 account_minimum_balance(),
2043 Account::get_packed_len(),
2044 &program_id,
2045 );
2046 let account2_key = Pubkey::new_unique();
2047 let mut account2_account = GemachainAccount::new(
2048 account_minimum_balance(),
2049 Account::get_packed_len(),
2050 &program_id,
2051 );
2052 let account3_key = Pubkey::new_unique();
2053 let mut account3_account = GemachainAccount::new(
2054 account_minimum_balance(),
2055 Account::get_packed_len(),
2056 &program_id,
2057 );
2058 let delegate_key = Pubkey::new_unique();
2059 let mut delegate_account = GemachainAccount::default();
2060 let owner_key = Pubkey::new_unique();
2061 let mut owner_account = GemachainAccount::default();
2062 let owner2_key = Pubkey::new_unique();
2063 let mut owner2_account = GemachainAccount::default();
2064 let mint_key = Pubkey::new_unique();
2065 let mut mint_account =
2066 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
2067 let mut rent_sysvar = rent_sysvar();
2068
2069 do_process_instruction(
2071 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
2072 vec![&mut mint_account, &mut rent_sysvar],
2073 )
2074 .unwrap();
2075
2076 do_process_instruction(
2078 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
2079 vec![
2080 &mut account_account,
2081 &mut mint_account,
2082 &mut owner_account,
2083 &mut rent_sysvar,
2084 ],
2085 )
2086 .unwrap();
2087
2088 do_process_instruction(
2090 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
2091 vec![
2092 &mut account2_account,
2093 &mut mint_account,
2094 &mut owner_account,
2095 &mut rent_sysvar,
2096 ],
2097 )
2098 .unwrap();
2099
2100 do_process_instruction(
2102 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
2103 vec![
2104 &mut account3_account,
2105 &mut mint_account,
2106 &mut owner_account,
2107 &mut rent_sysvar,
2108 ],
2109 )
2110 .unwrap();
2111
2112 do_process_instruction(
2114 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
2115 vec![&mut mint_account, &mut account_account, &mut owner_account],
2116 )
2117 .unwrap();
2118
2119 let account_info = (&account_key, false, &mut account_account).into_account_info();
2120 let account3_info = (&account3_key, false, &mut account3_account).into_account_info();
2121 let delegate_info = (&delegate_key, true, &mut delegate_account).into_account_info();
2122 let owner_info = (&owner_key, true, &mut owner_account).into_account_info();
2123 let owner2_info = (&owner2_key, true, &mut owner2_account).into_account_info();
2124 let mint_info = (&mint_key, false, &mut mint_account).into_account_info();
2125
2126 let instruction = transfer(
2128 &program_id,
2129 account_info.key,
2130 account_info.key,
2131 owner_info.key,
2132 &[],
2133 1000,
2134 )
2135 .unwrap();
2136 assert_eq!(
2137 Ok(()),
2138 Processor::process(
2139 &instruction.program_id,
2140 &[
2141 account_info.clone(),
2142 account_info.clone(),
2143 owner_info.clone(),
2144 ],
2145 &instruction.data,
2146 )
2147 );
2148 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2150 assert_eq!(account.amount, 1000);
2151
2152 let instruction = transfer_checked(
2154 &program_id,
2155 account_info.key,
2156 mint_info.key,
2157 account_info.key,
2158 owner_info.key,
2159 &[],
2160 1000,
2161 2,
2162 )
2163 .unwrap();
2164 assert_eq!(
2165 Ok(()),
2166 Processor::process(
2167 &instruction.program_id,
2168 &[
2169 account_info.clone(),
2170 mint_info.clone(),
2171 account_info.clone(),
2172 owner_info.clone(),
2173 ],
2174 &instruction.data,
2175 )
2176 );
2177 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2179 assert_eq!(account.amount, 1000);
2180
2181 let mut owner_no_sign_info = owner_info.clone();
2183 let mut instruction = transfer(
2184 &program_id,
2185 account_info.key,
2186 account_info.key,
2187 owner_no_sign_info.key,
2188 &[],
2189 1000,
2190 )
2191 .unwrap();
2192 instruction.accounts[2].is_signer = false;
2193 owner_no_sign_info.is_signer = false;
2194 assert_eq!(
2195 Err(ProgramError::MissingRequiredSignature),
2196 Processor::process(
2197 &instruction.program_id,
2198 &[
2199 account_info.clone(),
2200 account_info.clone(),
2201 owner_no_sign_info.clone(),
2202 ],
2203 &instruction.data,
2204 )
2205 );
2206
2207 let mut instruction = transfer_checked(
2209 &program_id,
2210 account_info.key,
2211 mint_info.key,
2212 account_info.key,
2213 owner_no_sign_info.key,
2214 &[],
2215 1000,
2216 2,
2217 )
2218 .unwrap();
2219 instruction.accounts[3].is_signer = false;
2220 assert_eq!(
2221 Err(ProgramError::MissingRequiredSignature),
2222 Processor::process(
2223 &instruction.program_id,
2224 &[
2225 account_info.clone(),
2226 mint_info.clone(),
2227 account_info.clone(),
2228 owner_no_sign_info,
2229 ],
2230 &instruction.data,
2231 )
2232 );
2233
2234 let instruction = transfer(
2236 &program_id,
2237 account_info.key,
2238 account_info.key,
2239 owner2_info.key,
2240 &[],
2241 1000,
2242 )
2243 .unwrap();
2244 assert_eq!(
2245 Err(TokenError::OwnerMismatch.into()),
2246 Processor::process(
2247 &instruction.program_id,
2248 &[
2249 account_info.clone(),
2250 account_info.clone(),
2251 owner2_info.clone(),
2252 ],
2253 &instruction.data,
2254 )
2255 );
2256
2257 let instruction = transfer_checked(
2259 &program_id,
2260 account_info.key,
2261 mint_info.key,
2262 account_info.key,
2263 owner2_info.key,
2264 &[],
2265 1000,
2266 2,
2267 )
2268 .unwrap();
2269 assert_eq!(
2270 Err(TokenError::OwnerMismatch.into()),
2271 Processor::process(
2272 &instruction.program_id,
2273 &[
2274 account_info.clone(),
2275 mint_info.clone(),
2276 account_info.clone(),
2277 owner2_info.clone(),
2278 ],
2279 &instruction.data,
2280 )
2281 );
2282
2283 let instruction = transfer(
2285 &program_id,
2286 account_info.key,
2287 account_info.key,
2288 owner_info.key,
2289 &[],
2290 1001,
2291 )
2292 .unwrap();
2293 assert_eq!(
2294 Err(TokenError::InsufficientFunds.into()),
2295 Processor::process(
2296 &instruction.program_id,
2297 &[
2298 account_info.clone(),
2299 account_info.clone(),
2300 owner_info.clone(),
2301 ],
2302 &instruction.data,
2303 )
2304 );
2305
2306 let instruction = transfer_checked(
2308 &program_id,
2309 account_info.key,
2310 mint_info.key,
2311 account_info.key,
2312 owner_info.key,
2313 &[],
2314 1001,
2315 2,
2316 )
2317 .unwrap();
2318 assert_eq!(
2319 Err(TokenError::InsufficientFunds.into()),
2320 Processor::process(
2321 &instruction.program_id,
2322 &[
2323 account_info.clone(),
2324 mint_info.clone(),
2325 account_info.clone(),
2326 owner_info.clone(),
2327 ],
2328 &instruction.data,
2329 )
2330 );
2331
2332 let instruction = transfer_checked(
2334 &program_id,
2335 account_info.key,
2336 mint_info.key,
2337 account_info.key,
2338 owner_info.key,
2339 &[],
2340 1,
2341 10, )
2343 .unwrap();
2344 assert_eq!(
2345 Err(TokenError::MintDecimalsMismatch.into()),
2346 Processor::process(
2347 &instruction.program_id,
2348 &[
2349 account_info.clone(),
2350 mint_info.clone(),
2351 account_info.clone(),
2352 owner_info.clone(),
2353 ],
2354 &instruction.data,
2355 )
2356 );
2357
2358 let instruction = transfer_checked(
2360 &program_id,
2361 account_info.key,
2362 account3_info.key, account_info.key,
2364 owner_info.key,
2365 &[],
2366 1,
2367 2,
2368 )
2369 .unwrap();
2370 assert_eq!(
2371 Err(TokenError::MintMismatch.into()),
2372 Processor::process(
2373 &instruction.program_id,
2374 &[
2375 account_info.clone(),
2376 account3_info.clone(), account_info.clone(),
2378 owner_info.clone(),
2379 ],
2380 &instruction.data,
2381 )
2382 );
2383
2384 let instruction = approve(
2386 &program_id,
2387 account_info.key,
2388 delegate_info.key,
2389 owner_info.key,
2390 &[],
2391 100,
2392 )
2393 .unwrap();
2394 Processor::process(
2395 &instruction.program_id,
2396 &[
2397 account_info.clone(),
2398 delegate_info.clone(),
2399 owner_info.clone(),
2400 ],
2401 &instruction.data,
2402 )
2403 .unwrap();
2404
2405 let instruction = transfer(
2407 &program_id,
2408 account_info.key,
2409 account_info.key,
2410 delegate_info.key,
2411 &[],
2412 100,
2413 )
2414 .unwrap();
2415 assert_eq!(
2416 Ok(()),
2417 Processor::process(
2418 &instruction.program_id,
2419 &[
2420 account_info.clone(),
2421 account_info.clone(),
2422 delegate_info.clone(),
2423 ],
2424 &instruction.data,
2425 )
2426 );
2427 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2429 assert_eq!(account.amount, 1000);
2430 assert_eq!(account.delegated_amount, 100);
2431
2432 let instruction = transfer_checked(
2434 &program_id,
2435 account_info.key,
2436 mint_info.key,
2437 account_info.key,
2438 delegate_info.key,
2439 &[],
2440 100,
2441 2,
2442 )
2443 .unwrap();
2444 assert_eq!(
2445 Ok(()),
2446 Processor::process(
2447 &instruction.program_id,
2448 &[
2449 account_info.clone(),
2450 mint_info.clone(),
2451 account_info.clone(),
2452 delegate_info.clone(),
2453 ],
2454 &instruction.data,
2455 )
2456 );
2457 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2459 assert_eq!(account.amount, 1000);
2460 assert_eq!(account.delegated_amount, 100);
2461
2462 let instruction = transfer(
2464 &program_id,
2465 account_info.key,
2466 account_info.key,
2467 delegate_info.key,
2468 &[],
2469 101,
2470 )
2471 .unwrap();
2472 assert_eq!(
2473 Err(TokenError::InsufficientFunds.into()),
2474 Processor::process(
2475 &instruction.program_id,
2476 &[
2477 account_info.clone(),
2478 account_info.clone(),
2479 delegate_info.clone(),
2480 ],
2481 &instruction.data,
2482 )
2483 );
2484
2485 let instruction = transfer_checked(
2487 &program_id,
2488 account_info.key,
2489 mint_info.key,
2490 account_info.key,
2491 delegate_info.key,
2492 &[],
2493 101,
2494 2,
2495 )
2496 .unwrap();
2497 assert_eq!(
2498 Err(TokenError::InsufficientFunds.into()),
2499 Processor::process(
2500 &instruction.program_id,
2501 &[
2502 account_info.clone(),
2503 mint_info.clone(),
2504 account_info.clone(),
2505 delegate_info.clone(),
2506 ],
2507 &instruction.data,
2508 )
2509 );
2510
2511 let instruction = transfer(
2513 &program_id,
2514 account_info.key,
2515 account_info.key,
2516 owner_info.key,
2517 &[],
2518 1000,
2519 )
2520 .unwrap();
2521 assert_eq!(
2522 Ok(()),
2523 Processor::process(
2524 &instruction.program_id,
2525 &[
2526 account_info.clone(),
2527 account_info.clone(),
2528 owner_info.clone(),
2529 ],
2530 &instruction.data,
2531 )
2532 );
2533 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2535 assert_eq!(account.amount, 1000);
2536
2537 let instruction = transfer_checked(
2539 &program_id,
2540 account_info.key,
2541 mint_info.key,
2542 account_info.key,
2543 owner_info.key,
2544 &[],
2545 1000,
2546 2,
2547 )
2548 .unwrap();
2549 assert_eq!(
2550 Ok(()),
2551 Processor::process(
2552 &instruction.program_id,
2553 &[
2554 account_info.clone(),
2555 mint_info.clone(),
2556 account_info.clone(),
2557 owner_info.clone(),
2558 ],
2559 &instruction.data,
2560 )
2561 );
2562 let account = Account::unpack_unchecked(&account_info.try_borrow_data().unwrap()).unwrap();
2564 assert_eq!(account.amount, 1000);
2565 }
2566
2567 #[test]
2568 fn test_mintable_token_with_zero_supply() {
2569 let program_id = crate::id();
2570 let account_key = Pubkey::new_unique();
2571 let mut account_account = GemachainAccount::new(
2572 account_minimum_balance(),
2573 Account::get_packed_len(),
2574 &program_id,
2575 );
2576 let owner_key = Pubkey::new_unique();
2577 let mut owner_account = GemachainAccount::default();
2578 let mint_key = Pubkey::new_unique();
2579 let mut mint_account =
2580 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
2581 let mut rent_sysvar = rent_sysvar();
2582
2583 let decimals = 2;
2585 do_process_instruction(
2586 initialize_mint(&program_id, &mint_key, &owner_key, None, decimals).unwrap(),
2587 vec![&mut mint_account, &mut rent_sysvar],
2588 )
2589 .unwrap();
2590 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
2591 assert_eq!(
2592 mint,
2593 Mint {
2594 mint_authority: COption::Some(owner_key),
2595 supply: 0,
2596 decimals,
2597 is_initialized: true,
2598 freeze_authority: COption::None,
2599 }
2600 );
2601
2602 do_process_instruction(
2604 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
2605 vec![
2606 &mut account_account,
2607 &mut mint_account,
2608 &mut owner_account,
2609 &mut rent_sysvar,
2610 ],
2611 )
2612 .unwrap();
2613
2614 do_process_instruction(
2616 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
2617 vec![&mut mint_account, &mut account_account, &mut owner_account],
2618 )
2619 .unwrap();
2620 let _ = Mint::unpack(&mint_account.data).unwrap();
2621 let account = Account::unpack_unchecked(&account_account.data).unwrap();
2622 assert_eq!(account.amount, 42);
2623
2624 assert_eq!(
2626 Err(TokenError::MintDecimalsMismatch.into()),
2627 do_process_instruction(
2628 mint_to_checked(
2629 &program_id,
2630 &mint_key,
2631 &account_key,
2632 &owner_key,
2633 &[],
2634 42,
2635 decimals + 1
2636 )
2637 .unwrap(),
2638 vec![&mut mint_account, &mut account_account, &mut owner_account],
2639 )
2640 );
2641
2642 let _ = Mint::unpack(&mint_account.data).unwrap();
2643 let account = Account::unpack_unchecked(&account_account.data).unwrap();
2644 assert_eq!(account.amount, 42);
2645
2646 do_process_instruction(
2648 mint_to_checked(
2649 &program_id,
2650 &mint_key,
2651 &account_key,
2652 &owner_key,
2653 &[],
2654 42,
2655 decimals,
2656 )
2657 .unwrap(),
2658 vec![&mut mint_account, &mut account_account, &mut owner_account],
2659 )
2660 .unwrap();
2661 let _ = Mint::unpack(&mint_account.data).unwrap();
2662 let account = Account::unpack_unchecked(&account_account.data).unwrap();
2663 assert_eq!(account.amount, 84);
2664 }
2665
2666 #[test]
2667 fn test_approve_dups() {
2668 let program_id = crate::id();
2669 let account1_key = Pubkey::new_unique();
2670 let mut account1_account = GemachainAccount::new(
2671 account_minimum_balance(),
2672 Account::get_packed_len(),
2673 &program_id,
2674 );
2675 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
2676 let account2_key = Pubkey::new_unique();
2677 let mut account2_account = GemachainAccount::new(
2678 account_minimum_balance(),
2679 Account::get_packed_len(),
2680 &program_id,
2681 );
2682 let account2_info: AccountInfo = (&account2_key, false, &mut account2_account).into();
2683 let account3_key = Pubkey::new_unique();
2684 let mut account3_account = GemachainAccount::new(
2685 account_minimum_balance(),
2686 Account::get_packed_len(),
2687 &program_id,
2688 );
2689 let account3_info: AccountInfo = (&account3_key, true, &mut account3_account).into();
2690 let multisig_key = Pubkey::new_unique();
2691 let mut multisig_account = GemachainAccount::new(
2692 multisig_minimum_balance(),
2693 Multisig::get_packed_len(),
2694 &program_id,
2695 );
2696 let multisig_info: AccountInfo = (&multisig_key, true, &mut multisig_account).into();
2697 let owner_key = Pubkey::new_unique();
2698 let mut owner_account = GemachainAccount::default();
2699 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
2700 let mint_key = Pubkey::new_unique();
2701 let mut mint_account =
2702 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
2703 let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
2704 let rent_key = rent::id();
2705 let mut rent_sysvar = rent_sysvar();
2706 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
2707
2708 do_process_instruction_dups(
2710 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
2711 vec![mint_info.clone(), rent_info.clone()],
2712 )
2713 .unwrap();
2714
2715 do_process_instruction_dups(
2717 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
2718 vec![
2719 account1_info.clone(),
2720 mint_info.clone(),
2721 account1_info.clone(),
2722 rent_info.clone(),
2723 ],
2724 )
2725 .unwrap();
2726
2727 do_process_instruction_dups(
2729 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
2730 vec![
2731 account2_info.clone(),
2732 mint_info.clone(),
2733 owner_info.clone(),
2734 rent_info.clone(),
2735 ],
2736 )
2737 .unwrap();
2738
2739 do_process_instruction_dups(
2741 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
2742 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
2743 )
2744 .unwrap();
2745
2746 do_process_instruction_dups(
2748 approve(
2749 &program_id,
2750 &account1_key,
2751 &account2_key,
2752 &account1_key,
2753 &[],
2754 500,
2755 )
2756 .unwrap(),
2757 vec![
2758 account1_info.clone(),
2759 account2_info.clone(),
2760 account1_info.clone(),
2761 ],
2762 )
2763 .unwrap();
2764
2765 do_process_instruction_dups(
2767 approve_checked(
2768 &program_id,
2769 &account1_key,
2770 &mint_key,
2771 &account2_key,
2772 &account1_key,
2773 &[],
2774 500,
2775 2,
2776 )
2777 .unwrap(),
2778 vec![
2779 account1_info.clone(),
2780 mint_info.clone(),
2781 account2_info.clone(),
2782 account1_info.clone(),
2783 ],
2784 )
2785 .unwrap();
2786
2787 do_process_instruction_dups(
2789 revoke(&program_id, &account1_key, &account1_key, &[]).unwrap(),
2790 vec![account1_info.clone(), account1_info.clone()],
2791 )
2792 .unwrap();
2793
2794 do_process_instruction_dups(
2796 initialize_multisig(&program_id, &multisig_key, &[&account3_key], 1).unwrap(),
2797 vec![
2798 multisig_info.clone(),
2799 rent_info.clone(),
2800 account3_info.clone(),
2801 ],
2802 )
2803 .unwrap();
2804
2805 do_process_instruction_dups(
2806 initialize_account(&program_id, &account3_key, &mint_key, &multisig_key).unwrap(),
2807 vec![
2808 account3_info.clone(),
2809 mint_info.clone(),
2810 multisig_info.clone(),
2811 rent_info.clone(),
2812 ],
2813 )
2814 .unwrap();
2815
2816 do_process_instruction_dups(
2817 mint_to(&program_id, &mint_key, &account3_key, &owner_key, &[], 1000).unwrap(),
2818 vec![mint_info.clone(), account3_info.clone(), owner_info.clone()],
2819 )
2820 .unwrap();
2821
2822 do_process_instruction_dups(
2824 approve(
2825 &program_id,
2826 &account3_key,
2827 &account2_key,
2828 &multisig_key,
2829 &[&account3_key],
2830 500,
2831 )
2832 .unwrap(),
2833 vec![
2834 account3_info.clone(),
2835 account2_info.clone(),
2836 multisig_info.clone(),
2837 account3_info.clone(),
2838 ],
2839 )
2840 .unwrap();
2841
2842 do_process_instruction_dups(
2844 approve_checked(
2845 &program_id,
2846 &account3_key,
2847 &mint_key,
2848 &account2_key,
2849 &multisig_key,
2850 &[&account3_key],
2851 500,
2852 2,
2853 )
2854 .unwrap(),
2855 vec![
2856 account3_info.clone(),
2857 mint_info.clone(),
2858 account2_info.clone(),
2859 multisig_info.clone(),
2860 account3_info.clone(),
2861 ],
2862 )
2863 .unwrap();
2864
2865 do_process_instruction_dups(
2867 revoke(&program_id, &account3_key, &multisig_key, &[&account3_key]).unwrap(),
2868 vec![
2869 account3_info.clone(),
2870 multisig_info.clone(),
2871 account3_info.clone(),
2872 ],
2873 )
2874 .unwrap();
2875 }
2876
2877 #[test]
2878 fn test_approve() {
2879 let program_id = crate::id();
2880 let account_key = Pubkey::new_unique();
2881 let mut account_account = GemachainAccount::new(
2882 account_minimum_balance(),
2883 Account::get_packed_len(),
2884 &program_id,
2885 );
2886 let account2_key = Pubkey::new_unique();
2887 let mut account2_account = GemachainAccount::new(
2888 account_minimum_balance(),
2889 Account::get_packed_len(),
2890 &program_id,
2891 );
2892 let delegate_key = Pubkey::new_unique();
2893 let mut delegate_account = GemachainAccount::default();
2894 let owner_key = Pubkey::new_unique();
2895 let mut owner_account = GemachainAccount::default();
2896 let owner2_key = Pubkey::new_unique();
2897 let mut owner2_account = GemachainAccount::default();
2898 let mint_key = Pubkey::new_unique();
2899 let mut mint_account =
2900 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
2901 let mut rent_sysvar = rent_sysvar();
2902
2903 do_process_instruction(
2905 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
2906 vec![&mut mint_account, &mut rent_sysvar],
2907 )
2908 .unwrap();
2909
2910 do_process_instruction(
2912 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
2913 vec![
2914 &mut account_account,
2915 &mut mint_account,
2916 &mut owner_account,
2917 &mut rent_sysvar,
2918 ],
2919 )
2920 .unwrap();
2921
2922 do_process_instruction(
2924 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
2925 vec![
2926 &mut account2_account,
2927 &mut mint_account,
2928 &mut owner_account,
2929 &mut rent_sysvar,
2930 ],
2931 )
2932 .unwrap();
2933
2934 do_process_instruction(
2936 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
2937 vec![&mut mint_account, &mut account_account, &mut owner_account],
2938 )
2939 .unwrap();
2940
2941 let mut instruction = approve(
2943 &program_id,
2944 &account_key,
2945 &delegate_key,
2946 &owner_key,
2947 &[],
2948 100,
2949 )
2950 .unwrap();
2951 instruction.accounts[2].is_signer = false;
2952 assert_eq!(
2953 Err(ProgramError::MissingRequiredSignature),
2954 do_process_instruction(
2955 instruction,
2956 vec![
2957 &mut account_account,
2958 &mut delegate_account,
2959 &mut owner_account,
2960 ],
2961 )
2962 );
2963
2964 assert_eq!(
2966 Err(TokenError::OwnerMismatch.into()),
2967 do_process_instruction(
2968 approve(
2969 &program_id,
2970 &account_key,
2971 &delegate_key,
2972 &owner2_key,
2973 &[],
2974 100
2975 )
2976 .unwrap(),
2977 vec![
2978 &mut account_account,
2979 &mut delegate_account,
2980 &mut owner2_account,
2981 ],
2982 )
2983 );
2984
2985 do_process_instruction(
2987 approve(
2988 &program_id,
2989 &account_key,
2990 &delegate_key,
2991 &owner_key,
2992 &[],
2993 100,
2994 )
2995 .unwrap(),
2996 vec![
2997 &mut account_account,
2998 &mut delegate_account,
2999 &mut owner_account,
3000 ],
3001 )
3002 .unwrap();
3003
3004 assert_eq!(
3006 Err(TokenError::MintDecimalsMismatch.into()),
3007 do_process_instruction(
3008 approve_checked(
3009 &program_id,
3010 &account_key,
3011 &mint_key,
3012 &delegate_key,
3013 &owner_key,
3014 &[],
3015 100,
3016 0 )
3018 .unwrap(),
3019 vec![
3020 &mut account_account,
3021 &mut mint_account,
3022 &mut delegate_account,
3023 &mut owner_account,
3024 ],
3025 )
3026 );
3027
3028 assert_eq!(
3030 Err(TokenError::MintMismatch.into()),
3031 do_process_instruction(
3032 approve_checked(
3033 &program_id,
3034 &account_key,
3035 &account2_key, &delegate_key,
3037 &owner_key,
3038 &[],
3039 100,
3040 0
3041 )
3042 .unwrap(),
3043 vec![
3044 &mut account_account,
3045 &mut account2_account, &mut delegate_account,
3047 &mut owner_account,
3048 ],
3049 )
3050 );
3051
3052 do_process_instruction(
3054 approve_checked(
3055 &program_id,
3056 &account_key,
3057 &mint_key,
3058 &delegate_key,
3059 &owner_key,
3060 &[],
3061 100,
3062 2,
3063 )
3064 .unwrap(),
3065 vec![
3066 &mut account_account,
3067 &mut mint_account,
3068 &mut delegate_account,
3069 &mut owner_account,
3070 ],
3071 )
3072 .unwrap();
3073
3074 do_process_instruction(
3076 revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
3077 vec![&mut account_account, &mut owner_account],
3078 )
3079 .unwrap();
3080 }
3081
3082 #[test]
3083 fn test_set_authority_dups() {
3084 let program_id = crate::id();
3085 let account1_key = Pubkey::new_unique();
3086 let mut account1_account = GemachainAccount::new(
3087 account_minimum_balance(),
3088 Account::get_packed_len(),
3089 &program_id,
3090 );
3091 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
3092 let owner_key = Pubkey::new_unique();
3093 let mint_key = Pubkey::new_unique();
3094 let mut mint_account =
3095 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3096 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
3097 let rent_key = rent::id();
3098 let mut rent_sysvar = rent_sysvar();
3099 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
3100
3101 do_process_instruction_dups(
3103 initialize_mint(&program_id, &mint_key, &mint_key, Some(&mint_key), 2).unwrap(),
3104 vec![mint_info.clone(), rent_info.clone()],
3105 )
3106 .unwrap();
3107
3108 do_process_instruction_dups(
3110 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
3111 vec![
3112 account1_info.clone(),
3113 mint_info.clone(),
3114 account1_info.clone(),
3115 rent_info.clone(),
3116 ],
3117 )
3118 .unwrap();
3119
3120 do_process_instruction_dups(
3122 set_authority(
3123 &program_id,
3124 &mint_key,
3125 Some(&owner_key),
3126 AuthorityType::MintTokens,
3127 &mint_key,
3128 &[],
3129 )
3130 .unwrap(),
3131 vec![mint_info.clone(), mint_info.clone()],
3132 )
3133 .unwrap();
3134
3135 do_process_instruction_dups(
3137 set_authority(
3138 &program_id,
3139 &mint_key,
3140 Some(&owner_key),
3141 AuthorityType::FreezeAccount,
3142 &mint_key,
3143 &[],
3144 )
3145 .unwrap(),
3146 vec![mint_info.clone(), mint_info.clone()],
3147 )
3148 .unwrap();
3149
3150 do_process_instruction_dups(
3152 set_authority(
3153 &program_id,
3154 &account1_key,
3155 Some(&owner_key),
3156 AuthorityType::AccountOwner,
3157 &account1_key,
3158 &[],
3159 )
3160 .unwrap(),
3161 vec![account1_info.clone(), account1_info.clone()],
3162 )
3163 .unwrap();
3164
3165 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
3167 account.close_authority = COption::Some(account1_key);
3168 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
3169
3170 do_process_instruction_dups(
3171 set_authority(
3172 &program_id,
3173 &account1_key,
3174 Some(&owner_key),
3175 AuthorityType::CloseAccount,
3176 &account1_key,
3177 &[],
3178 )
3179 .unwrap(),
3180 vec![account1_info.clone(), account1_info.clone()],
3181 )
3182 .unwrap();
3183 }
3184
3185 #[test]
3186 fn test_set_authority() {
3187 let program_id = crate::id();
3188 let account_key = Pubkey::new_unique();
3189 let mut account_account = GemachainAccount::new(
3190 account_minimum_balance(),
3191 Account::get_packed_len(),
3192 &program_id,
3193 );
3194 let account2_key = Pubkey::new_unique();
3195 let mut account2_account = GemachainAccount::new(
3196 account_minimum_balance(),
3197 Account::get_packed_len(),
3198 &program_id,
3199 );
3200 let owner_key = Pubkey::new_unique();
3201 let mut owner_account = GemachainAccount::default();
3202 let owner2_key = Pubkey::new_unique();
3203 let mut owner2_account = GemachainAccount::default();
3204 let owner3_key = Pubkey::new_unique();
3205 let mut owner3_account = GemachainAccount::default();
3206 let mint_key = Pubkey::new_unique();
3207 let mut mint_account =
3208 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3209 let mint2_key = Pubkey::new_unique();
3210 let mut mint2_account =
3211 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3212 let mut rent_sysvar = rent_sysvar();
3213
3214 do_process_instruction(
3216 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
3217 vec![&mut mint_account, &mut rent_sysvar],
3218 )
3219 .unwrap();
3220
3221 do_process_instruction(
3223 initialize_mint(&program_id, &mint2_key, &owner_key, Some(&owner_key), 2).unwrap(),
3224 vec![&mut mint2_account, &mut rent_sysvar],
3225 )
3226 .unwrap();
3227
3228 assert_eq!(
3230 Err(ProgramError::UninitializedAccount),
3231 do_process_instruction(
3232 set_authority(
3233 &program_id,
3234 &account_key,
3235 Some(&owner2_key),
3236 AuthorityType::AccountOwner,
3237 &owner_key,
3238 &[]
3239 )
3240 .unwrap(),
3241 vec![&mut account_account, &mut owner_account],
3242 )
3243 );
3244
3245 do_process_instruction(
3247 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
3248 vec![
3249 &mut account_account,
3250 &mut mint_account,
3251 &mut owner_account,
3252 &mut rent_sysvar,
3253 ],
3254 )
3255 .unwrap();
3256
3257 do_process_instruction(
3259 initialize_account(&program_id, &account2_key, &mint2_key, &owner_key).unwrap(),
3260 vec![
3261 &mut account2_account,
3262 &mut mint2_account,
3263 &mut owner_account,
3264 &mut rent_sysvar,
3265 ],
3266 )
3267 .unwrap();
3268
3269 assert_eq!(
3271 Err(TokenError::OwnerMismatch.into()),
3272 do_process_instruction(
3273 set_authority(
3274 &program_id,
3275 &account_key,
3276 Some(&owner_key),
3277 AuthorityType::AccountOwner,
3278 &owner2_key,
3279 &[]
3280 )
3281 .unwrap(),
3282 vec![&mut account_account, &mut owner2_account],
3283 )
3284 );
3285
3286 let mut instruction = set_authority(
3288 &program_id,
3289 &account_key,
3290 Some(&owner2_key),
3291 AuthorityType::AccountOwner,
3292 &owner_key,
3293 &[],
3294 )
3295 .unwrap();
3296 instruction.accounts[1].is_signer = false;
3297 assert_eq!(
3298 Err(ProgramError::MissingRequiredSignature),
3299 do_process_instruction(instruction, vec![&mut account_account, &mut owner_account,],)
3300 );
3301
3302 assert_eq!(
3304 Err(TokenError::AuthorityTypeNotSupported.into()),
3305 do_process_instruction(
3306 set_authority(
3307 &program_id,
3308 &account_key,
3309 Some(&owner2_key),
3310 AuthorityType::FreezeAccount,
3311 &owner_key,
3312 &[],
3313 )
3314 .unwrap(),
3315 vec![&mut account_account, &mut owner_account],
3316 )
3317 );
3318
3319 assert_eq!(
3321 Err(TokenError::InvalidInstruction.into()),
3322 do_process_instruction(
3323 set_authority(
3324 &program_id,
3325 &account_key,
3326 None,
3327 AuthorityType::AccountOwner,
3328 &owner_key,
3329 &[],
3330 )
3331 .unwrap(),
3332 vec![&mut account_account, &mut owner_account],
3333 )
3334 );
3335
3336 do_process_instruction(
3338 approve(
3339 &program_id,
3340 &account_key,
3341 &owner2_key,
3342 &owner_key,
3343 &[],
3344 u64::MAX,
3345 )
3346 .unwrap(),
3347 vec![
3348 &mut account_account,
3349 &mut owner2_account,
3350 &mut owner_account,
3351 ],
3352 )
3353 .unwrap();
3354 let account = Account::unpack_unchecked(&account_account.data).unwrap();
3355 assert_eq!(account.delegate, COption::Some(owner2_key));
3356 assert_eq!(account.delegated_amount, u64::MAX);
3357
3358 do_process_instruction(
3360 set_authority(
3361 &program_id,
3362 &account_key,
3363 Some(&owner3_key),
3364 AuthorityType::AccountOwner,
3365 &owner_key,
3366 &[],
3367 )
3368 .unwrap(),
3369 vec![&mut account_account, &mut owner_account],
3370 )
3371 .unwrap();
3372
3373 let account = Account::unpack_unchecked(&account_account.data).unwrap();
3375 assert_eq!(account.delegate, COption::None);
3376 assert_eq!(account.delegated_amount, 0);
3377
3378 do_process_instruction(
3380 set_authority(
3381 &program_id,
3382 &account_key,
3383 Some(&owner2_key),
3384 AuthorityType::AccountOwner,
3385 &owner3_key,
3386 &[],
3387 )
3388 .unwrap(),
3389 vec![&mut account_account, &mut owner3_account],
3390 )
3391 .unwrap();
3392
3393 do_process_instruction(
3395 set_authority(
3396 &program_id,
3397 &account_key,
3398 Some(&owner2_key),
3399 AuthorityType::CloseAccount,
3400 &owner2_key,
3401 &[],
3402 )
3403 .unwrap(),
3404 vec![&mut account_account, &mut owner2_account],
3405 )
3406 .unwrap();
3407
3408 do_process_instruction(
3410 set_authority(
3411 &program_id,
3412 &account_key,
3413 None,
3414 AuthorityType::CloseAccount,
3415 &owner2_key,
3416 &[],
3417 )
3418 .unwrap(),
3419 vec![&mut account_account, &mut owner2_account],
3420 )
3421 .unwrap();
3422
3423 assert_eq!(
3425 Err(TokenError::OwnerMismatch.into()),
3426 do_process_instruction(
3427 set_authority(
3428 &program_id,
3429 &mint_key,
3430 Some(&owner3_key),
3431 AuthorityType::MintTokens,
3432 &owner2_key,
3433 &[]
3434 )
3435 .unwrap(),
3436 vec![&mut mint_account, &mut owner2_account],
3437 )
3438 );
3439
3440 let mut instruction = set_authority(
3442 &program_id,
3443 &mint_key,
3444 Some(&owner2_key),
3445 AuthorityType::MintTokens,
3446 &owner_key,
3447 &[],
3448 )
3449 .unwrap();
3450 instruction.accounts[1].is_signer = false;
3451 assert_eq!(
3452 Err(ProgramError::MissingRequiredSignature),
3453 do_process_instruction(instruction, vec![&mut mint_account, &mut owner_account],)
3454 );
3455
3456 assert_eq!(
3458 Err(TokenError::MintCannotFreeze.into()),
3459 do_process_instruction(
3460 set_authority(
3461 &program_id,
3462 &mint_key,
3463 Some(&owner2_key),
3464 AuthorityType::FreezeAccount,
3465 &owner_key,
3466 &[],
3467 )
3468 .unwrap(),
3469 vec![&mut mint_account, &mut owner_account],
3470 )
3471 );
3472
3473 do_process_instruction(
3475 set_authority(
3476 &program_id,
3477 &mint_key,
3478 Some(&owner2_key),
3479 AuthorityType::MintTokens,
3480 &owner_key,
3481 &[],
3482 )
3483 .unwrap(),
3484 vec![&mut mint_account, &mut owner_account],
3485 )
3486 .unwrap();
3487
3488 do_process_instruction(
3490 set_authority(
3491 &program_id,
3492 &mint_key,
3493 None,
3494 AuthorityType::MintTokens,
3495 &owner2_key,
3496 &[],
3497 )
3498 .unwrap(),
3499 vec![&mut mint_account, &mut owner2_account],
3500 )
3501 .unwrap();
3502
3503 assert_eq!(
3505 Err(TokenError::FixedSupply.into()),
3506 do_process_instruction(
3507 set_authority(
3508 &program_id,
3509 &mint2_key,
3510 Some(&owner2_key),
3511 AuthorityType::MintTokens,
3512 &owner_key,
3513 &[]
3514 )
3515 .unwrap(),
3516 vec![&mut mint_account, &mut owner_account],
3517 )
3518 );
3519
3520 do_process_instruction(
3522 set_authority(
3523 &program_id,
3524 &mint2_key,
3525 Some(&owner2_key),
3526 AuthorityType::FreezeAccount,
3527 &owner_key,
3528 &[],
3529 )
3530 .unwrap(),
3531 vec![&mut mint2_account, &mut owner_account],
3532 )
3533 .unwrap();
3534
3535 do_process_instruction(
3537 set_authority(
3538 &program_id,
3539 &mint2_key,
3540 None,
3541 AuthorityType::FreezeAccount,
3542 &owner2_key,
3543 &[],
3544 )
3545 .unwrap(),
3546 vec![&mut mint2_account, &mut owner2_account],
3547 )
3548 .unwrap();
3549
3550 assert_eq!(
3551 Err(TokenError::MintCannotFreeze.into()),
3552 do_process_instruction(
3553 set_authority(
3554 &program_id,
3555 &mint2_key,
3556 Some(&owner2_key),
3557 AuthorityType::FreezeAccount,
3558 &owner_key,
3559 &[],
3560 )
3561 .unwrap(),
3562 vec![&mut mint2_account, &mut owner2_account],
3563 )
3564 );
3565 }
3566
3567 #[test]
3568 fn test_mint_to_dups() {
3569 let program_id = crate::id();
3570 let account1_key = Pubkey::new_unique();
3571 let mut account1_account = GemachainAccount::new(
3572 account_minimum_balance(),
3573 Account::get_packed_len(),
3574 &program_id,
3575 );
3576 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
3577 let owner_key = Pubkey::new_unique();
3578 let mut owner_account = GemachainAccount::default();
3579 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
3580 let mint_key = Pubkey::new_unique();
3581 let mut mint_account =
3582 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3583 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
3584 let rent_key = rent::id();
3585 let mut rent_sysvar = rent_sysvar();
3586 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
3587
3588 do_process_instruction_dups(
3590 initialize_mint(&program_id, &mint_key, &mint_key, None, 2).unwrap(),
3591 vec![mint_info.clone(), rent_info.clone()],
3592 )
3593 .unwrap();
3594
3595 do_process_instruction_dups(
3597 initialize_account(&program_id, &account1_key, &mint_key, &owner_key).unwrap(),
3598 vec![
3599 account1_info.clone(),
3600 mint_info.clone(),
3601 owner_info.clone(),
3602 rent_info.clone(),
3603 ],
3604 )
3605 .unwrap();
3606
3607 do_process_instruction_dups(
3609 mint_to(&program_id, &mint_key, &account1_key, &mint_key, &[], 42).unwrap(),
3610 vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
3611 )
3612 .unwrap();
3613
3614 do_process_instruction_dups(
3616 mint_to_checked(&program_id, &mint_key, &account1_key, &mint_key, &[], 42, 2).unwrap(),
3617 vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
3618 )
3619 .unwrap();
3620
3621 let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow()).unwrap();
3623 mint.mint_authority = COption::Some(account1_key);
3624 Mint::pack(mint, &mut mint_info.data.borrow_mut()).unwrap();
3625 do_process_instruction_dups(
3626 mint_to(
3627 &program_id,
3628 &mint_key,
3629 &account1_key,
3630 &account1_key,
3631 &[],
3632 42,
3633 )
3634 .unwrap(),
3635 vec![
3636 mint_info.clone(),
3637 account1_info.clone(),
3638 account1_info.clone(),
3639 ],
3640 )
3641 .unwrap();
3642
3643 do_process_instruction_dups(
3645 mint_to(
3646 &program_id,
3647 &mint_key,
3648 &account1_key,
3649 &account1_key,
3650 &[],
3651 42,
3652 )
3653 .unwrap(),
3654 vec![
3655 mint_info.clone(),
3656 account1_info.clone(),
3657 account1_info.clone(),
3658 ],
3659 )
3660 .unwrap();
3661 }
3662
3663 #[test]
3664 fn test_mint_to() {
3665 let program_id = crate::id();
3666 let account_key = Pubkey::new_unique();
3667 let mut account_account = GemachainAccount::new(
3668 account_minimum_balance(),
3669 Account::get_packed_len(),
3670 &program_id,
3671 );
3672 let account2_key = Pubkey::new_unique();
3673 let mut account2_account = GemachainAccount::new(
3674 account_minimum_balance(),
3675 Account::get_packed_len(),
3676 &program_id,
3677 );
3678 let account3_key = Pubkey::new_unique();
3679 let mut account3_account = GemachainAccount::new(
3680 account_minimum_balance(),
3681 Account::get_packed_len(),
3682 &program_id,
3683 );
3684 let mismatch_key = Pubkey::new_unique();
3685 let mut mismatch_account = GemachainAccount::new(
3686 account_minimum_balance(),
3687 Account::get_packed_len(),
3688 &program_id,
3689 );
3690 let owner_key = Pubkey::new_unique();
3691 let mut owner_account = GemachainAccount::default();
3692 let owner2_key = Pubkey::new_unique();
3693 let mut owner2_account = GemachainAccount::default();
3694 let mint_key = Pubkey::new_unique();
3695 let mut mint_account =
3696 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3697 let mint2_key = Pubkey::new_unique();
3698 let uninitialized_key = Pubkey::new_unique();
3699 let mut uninitialized_account = GemachainAccount::new(
3700 account_minimum_balance(),
3701 Account::get_packed_len(),
3702 &program_id,
3703 );
3704 let mut rent_sysvar = rent_sysvar();
3705
3706 do_process_instruction(
3708 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
3709 vec![&mut mint_account, &mut rent_sysvar],
3710 )
3711 .unwrap();
3712
3713 do_process_instruction(
3715 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
3716 vec![
3717 &mut account_account,
3718 &mut mint_account,
3719 &mut owner_account,
3720 &mut rent_sysvar,
3721 ],
3722 )
3723 .unwrap();
3724
3725 do_process_instruction(
3727 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
3728 vec![
3729 &mut account2_account,
3730 &mut mint_account,
3731 &mut owner_account,
3732 &mut rent_sysvar,
3733 ],
3734 )
3735 .unwrap();
3736
3737 do_process_instruction(
3739 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
3740 vec![
3741 &mut account3_account,
3742 &mut mint_account,
3743 &mut owner_account,
3744 &mut rent_sysvar,
3745 ],
3746 )
3747 .unwrap();
3748
3749 do_process_instruction(
3751 initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
3752 vec![
3753 &mut mismatch_account,
3754 &mut mint_account,
3755 &mut owner_account,
3756 &mut rent_sysvar,
3757 ],
3758 )
3759 .unwrap();
3760 let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
3761 account.mint = mint2_key;
3762 Account::pack(account, &mut mismatch_account.data).unwrap();
3763
3764 do_process_instruction(
3766 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
3767 vec![&mut mint_account, &mut account_account, &mut owner_account],
3768 )
3769 .unwrap();
3770
3771 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
3772 assert_eq!(mint.supply, 42);
3773 let account = Account::unpack_unchecked(&account_account.data).unwrap();
3774 assert_eq!(account.amount, 42);
3775
3776 do_process_instruction(
3778 mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
3779 vec![&mut mint_account, &mut account2_account, &mut owner_account],
3780 )
3781 .unwrap();
3782
3783 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
3784 assert_eq!(mint.supply, 84);
3785 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
3786 assert_eq!(account.amount, 42);
3787
3788 let mut instruction =
3790 mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap();
3791 instruction.accounts[2].is_signer = false;
3792 assert_eq!(
3793 Err(ProgramError::MissingRequiredSignature),
3794 do_process_instruction(
3795 instruction,
3796 vec![&mut mint_account, &mut account2_account, &mut owner_account],
3797 )
3798 );
3799
3800 assert_eq!(
3802 Err(TokenError::MintMismatch.into()),
3803 do_process_instruction(
3804 mint_to(&program_id, &mint_key, &mismatch_key, &owner_key, &[], 42).unwrap(),
3805 vec![&mut mint_account, &mut mismatch_account, &mut owner_account],
3806 )
3807 );
3808
3809 assert_eq!(
3811 Err(TokenError::OwnerMismatch.into()),
3812 do_process_instruction(
3813 mint_to(&program_id, &mint_key, &account2_key, &owner2_key, &[], 42).unwrap(),
3814 vec![
3815 &mut mint_account,
3816 &mut account2_account,
3817 &mut owner2_account,
3818 ],
3819 )
3820 );
3821
3822 assert_eq!(
3824 Err(ProgramError::UninitializedAccount),
3825 do_process_instruction(
3826 mint_to(
3827 &program_id,
3828 &mint_key,
3829 &uninitialized_key,
3830 &owner_key,
3831 &[],
3832 42
3833 )
3834 .unwrap(),
3835 vec![
3836 &mut mint_account,
3837 &mut uninitialized_account,
3838 &mut owner_account,
3839 ],
3840 )
3841 );
3842
3843 do_process_instruction(
3845 set_authority(
3846 &program_id,
3847 &mint_key,
3848 None,
3849 AuthorityType::MintTokens,
3850 &owner_key,
3851 &[],
3852 )
3853 .unwrap(),
3854 vec![&mut mint_account, &mut owner_account],
3855 )
3856 .unwrap();
3857 assert_eq!(
3858 Err(TokenError::FixedSupply.into()),
3859 do_process_instruction(
3860 mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
3861 vec![&mut mint_account, &mut account2_account, &mut owner_account],
3862 )
3863 );
3864 }
3865
3866 #[test]
3867 fn test_burn_dups() {
3868 let program_id = crate::id();
3869 let account1_key = Pubkey::new_unique();
3870 let mut account1_account = GemachainAccount::new(
3871 account_minimum_balance(),
3872 Account::get_packed_len(),
3873 &program_id,
3874 );
3875 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
3876 let owner_key = Pubkey::new_unique();
3877 let mut owner_account = GemachainAccount::default();
3878 let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
3879 let mint_key = Pubkey::new_unique();
3880 let mut mint_account =
3881 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
3882 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
3883 let rent_key = rent::id();
3884 let mut rent_sysvar = rent_sysvar();
3885 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
3886
3887 do_process_instruction_dups(
3889 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
3890 vec![mint_info.clone(), rent_info.clone()],
3891 )
3892 .unwrap();
3893
3894 do_process_instruction_dups(
3896 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
3897 vec![
3898 account1_info.clone(),
3899 mint_info.clone(),
3900 account1_info.clone(),
3901 rent_info.clone(),
3902 ],
3903 )
3904 .unwrap();
3905
3906 do_process_instruction_dups(
3908 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
3909 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
3910 )
3911 .unwrap();
3912
3913 do_process_instruction_dups(
3915 burn(
3916 &program_id,
3917 &mint_key,
3918 &account1_key,
3919 &account1_key,
3920 &[],
3921 500,
3922 )
3923 .unwrap(),
3924 vec![
3925 account1_info.clone(),
3926 mint_info.clone(),
3927 account1_info.clone(),
3928 ],
3929 )
3930 .unwrap();
3931
3932 do_process_instruction_dups(
3934 burn_checked(
3935 &program_id,
3936 &account1_key,
3937 &mint_key,
3938 &account1_key,
3939 &[],
3940 500,
3941 2,
3942 )
3943 .unwrap(),
3944 vec![
3945 account1_info.clone(),
3946 mint_info.clone(),
3947 account1_info.clone(),
3948 ],
3949 )
3950 .unwrap();
3951
3952 do_process_instruction_dups(
3954 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
3955 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
3956 )
3957 .unwrap();
3958 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
3959 account.owner = mint_key;
3960 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
3961 do_process_instruction_dups(
3962 burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
3963 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
3964 )
3965 .unwrap();
3966
3967 do_process_instruction_dups(
3969 burn_checked(
3970 &program_id,
3971 &account1_key,
3972 &mint_key,
3973 &mint_key,
3974 &[],
3975 500,
3976 2,
3977 )
3978 .unwrap(),
3979 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
3980 )
3981 .unwrap();
3982
3983 do_process_instruction_dups(
3985 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
3986 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
3987 )
3988 .unwrap();
3989 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
3990 account.delegated_amount = 1000;
3991 account.delegate = COption::Some(account1_key);
3992 account.owner = owner_key;
3993 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
3994 do_process_instruction_dups(
3995 burn(
3996 &program_id,
3997 &account1_key,
3998 &mint_key,
3999 &account1_key,
4000 &[],
4001 500,
4002 )
4003 .unwrap(),
4004 vec![
4005 account1_info.clone(),
4006 mint_info.clone(),
4007 account1_info.clone(),
4008 ],
4009 )
4010 .unwrap();
4011
4012 do_process_instruction_dups(
4014 burn_checked(
4015 &program_id,
4016 &account1_key,
4017 &mint_key,
4018 &account1_key,
4019 &[],
4020 500,
4021 2,
4022 )
4023 .unwrap(),
4024 vec![
4025 account1_info.clone(),
4026 mint_info.clone(),
4027 account1_info.clone(),
4028 ],
4029 )
4030 .unwrap();
4031
4032 do_process_instruction_dups(
4034 mint_to(&program_id, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(),
4035 vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
4036 )
4037 .unwrap();
4038 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
4039 account.delegated_amount = 1000;
4040 account.delegate = COption::Some(mint_key);
4041 account.owner = owner_key;
4042 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
4043 do_process_instruction_dups(
4044 burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
4045 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
4046 )
4047 .unwrap();
4048
4049 do_process_instruction_dups(
4051 burn_checked(
4052 &program_id,
4053 &account1_key,
4054 &mint_key,
4055 &mint_key,
4056 &[],
4057 500,
4058 2,
4059 )
4060 .unwrap(),
4061 vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
4062 )
4063 .unwrap();
4064 }
4065
4066 #[test]
4067 fn test_burn() {
4068 let program_id = crate::id();
4069 let account_key = Pubkey::new_unique();
4070 let mut account_account = GemachainAccount::new(
4071 account_minimum_balance(),
4072 Account::get_packed_len(),
4073 &program_id,
4074 );
4075 let account2_key = Pubkey::new_unique();
4076 let mut account2_account = GemachainAccount::new(
4077 account_minimum_balance(),
4078 Account::get_packed_len(),
4079 &program_id,
4080 );
4081 let account3_key = Pubkey::new_unique();
4082 let mut account3_account = GemachainAccount::new(
4083 account_minimum_balance(),
4084 Account::get_packed_len(),
4085 &program_id,
4086 );
4087 let delegate_key = Pubkey::new_unique();
4088 let mut delegate_account = GemachainAccount::default();
4089 let mismatch_key = Pubkey::new_unique();
4090 let mut mismatch_account = GemachainAccount::new(
4091 account_minimum_balance(),
4092 Account::get_packed_len(),
4093 &program_id,
4094 );
4095 let owner_key = Pubkey::new_unique();
4096 let mut owner_account = GemachainAccount::default();
4097 let owner2_key = Pubkey::new_unique();
4098 let mut owner2_account = GemachainAccount::default();
4099 let mint_key = Pubkey::new_unique();
4100 let mut mint_account =
4101 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4102 let mint2_key = Pubkey::new_unique();
4103 let mut rent_sysvar = rent_sysvar();
4104
4105 do_process_instruction(
4107 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
4108 vec![&mut mint_account, &mut rent_sysvar],
4109 )
4110 .unwrap();
4111
4112 do_process_instruction(
4114 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
4115 vec![
4116 &mut account_account,
4117 &mut mint_account,
4118 &mut owner_account,
4119 &mut rent_sysvar,
4120 ],
4121 )
4122 .unwrap();
4123
4124 do_process_instruction(
4126 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
4127 vec![
4128 &mut account2_account,
4129 &mut mint_account,
4130 &mut owner_account,
4131 &mut rent_sysvar,
4132 ],
4133 )
4134 .unwrap();
4135
4136 do_process_instruction(
4138 initialize_account(&program_id, &account3_key, &mint_key, &owner_key).unwrap(),
4139 vec![
4140 &mut account3_account,
4141 &mut mint_account,
4142 &mut owner_account,
4143 &mut rent_sysvar,
4144 ],
4145 )
4146 .unwrap();
4147
4148 do_process_instruction(
4150 initialize_account(&program_id, &mismatch_key, &mint_key, &owner_key).unwrap(),
4151 vec![
4152 &mut mismatch_account,
4153 &mut mint_account,
4154 &mut owner_account,
4155 &mut rent_sysvar,
4156 ],
4157 )
4158 .unwrap();
4159
4160 do_process_instruction(
4162 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
4163 vec![&mut mint_account, &mut account_account, &mut owner_account],
4164 )
4165 .unwrap();
4166
4167 do_process_instruction(
4169 mint_to(&program_id, &mint_key, &mismatch_key, &owner_key, &[], 1000).unwrap(),
4170 vec![&mut mint_account, &mut mismatch_account, &mut owner_account],
4171 )
4172 .unwrap();
4173 let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
4174 account.mint = mint2_key;
4175 Account::pack(account, &mut mismatch_account.data).unwrap();
4176
4177 let mut instruction =
4179 burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 42).unwrap();
4180 instruction.accounts[1].is_signer = false;
4181 assert_eq!(
4182 Err(TokenError::OwnerMismatch.into()),
4183 do_process_instruction(
4184 instruction,
4185 vec![
4186 &mut account_account,
4187 &mut mint_account,
4188 &mut delegate_account
4189 ],
4190 )
4191 );
4192
4193 assert_eq!(
4195 Err(TokenError::OwnerMismatch.into()),
4196 do_process_instruction(
4197 burn(&program_id, &account_key, &mint_key, &owner2_key, &[], 42).unwrap(),
4198 vec![&mut account_account, &mut mint_account, &mut owner2_account],
4199 )
4200 );
4201
4202 assert_eq!(
4204 Err(TokenError::MintMismatch.into()),
4205 do_process_instruction(
4206 burn(&program_id, &mismatch_key, &mint_key, &owner_key, &[], 42).unwrap(),
4207 vec![&mut mismatch_account, &mut mint_account, &mut owner_account],
4208 )
4209 );
4210
4211 do_process_instruction(
4213 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 21).unwrap(),
4214 vec![&mut account_account, &mut mint_account, &mut owner_account],
4215 )
4216 .unwrap();
4217
4218 assert_eq!(
4220 Err(TokenError::MintDecimalsMismatch.into()),
4221 do_process_instruction(
4222 burn_checked(&program_id, &account_key, &mint_key, &owner_key, &[], 21, 3).unwrap(),
4223 vec![&mut account_account, &mut mint_account, &mut owner_account],
4224 )
4225 );
4226
4227 do_process_instruction(
4229 burn_checked(&program_id, &account_key, &mint_key, &owner_key, &[], 21, 2).unwrap(),
4230 vec![&mut account_account, &mut mint_account, &mut owner_account],
4231 )
4232 .unwrap();
4233
4234 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
4235 assert_eq!(mint.supply, 2000 - 42);
4236 let account = Account::unpack_unchecked(&account_account.data).unwrap();
4237 assert_eq!(account.amount, 1000 - 42);
4238
4239 assert_eq!(
4241 Err(TokenError::InsufficientFunds.into()),
4242 do_process_instruction(
4243 burn(
4244 &program_id,
4245 &account_key,
4246 &mint_key,
4247 &owner_key,
4248 &[],
4249 100_000_000
4250 )
4251 .unwrap(),
4252 vec![&mut account_account, &mut mint_account, &mut owner_account],
4253 )
4254 );
4255
4256 do_process_instruction(
4258 approve(
4259 &program_id,
4260 &account_key,
4261 &delegate_key,
4262 &owner_key,
4263 &[],
4264 84,
4265 )
4266 .unwrap(),
4267 vec![
4268 &mut account_account,
4269 &mut delegate_account,
4270 &mut owner_account,
4271 ],
4272 )
4273 .unwrap();
4274
4275 assert_eq!(
4277 Err(TokenError::InsufficientFunds.into()),
4278 do_process_instruction(
4279 burn(
4280 &program_id,
4281 &account_key,
4282 &mint_key,
4283 &owner_key,
4284 &[],
4285 100_000_000
4286 )
4287 .unwrap(),
4288 vec![&mut account_account, &mut mint_account, &mut owner_account],
4289 )
4290 );
4291
4292 do_process_instruction(
4294 burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 84).unwrap(),
4295 vec![
4296 &mut account_account,
4297 &mut mint_account,
4298 &mut delegate_account,
4299 ],
4300 )
4301 .unwrap();
4302
4303 let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
4305 assert_eq!(mint.supply, 2000 - 42 - 84);
4306 let account = Account::unpack_unchecked(&account_account.data).unwrap();
4307 assert_eq!(account.amount, 1000 - 42 - 84);
4308
4309 assert_eq!(
4311 Err(TokenError::OwnerMismatch.into()),
4312 do_process_instruction(
4313 burn(
4314 &program_id,
4315 &account_key,
4316 &mint_key,
4317 &delegate_key,
4318 &[],
4319 100
4320 )
4321 .unwrap(),
4322 vec![
4323 &mut account_account,
4324 &mut mint_account,
4325 &mut delegate_account
4326 ],
4327 )
4328 );
4329 }
4330
4331 #[test]
4332 fn test_multisig() {
4333 let program_id = crate::id();
4334 let mint_key = Pubkey::new_unique();
4335 let mut mint_account =
4336 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4337 let account_key = Pubkey::new_unique();
4338 let mut account = GemachainAccount::new(
4339 account_minimum_balance(),
4340 Account::get_packed_len(),
4341 &program_id,
4342 );
4343 let account2_key = Pubkey::new_unique();
4344 let mut account2_account = GemachainAccount::new(
4345 account_minimum_balance(),
4346 Account::get_packed_len(),
4347 &program_id,
4348 );
4349 let owner_key = Pubkey::new_unique();
4350 let mut owner_account = GemachainAccount::default();
4351 let multisig_key = Pubkey::new_unique();
4352 let mut multisig_account = GemachainAccount::new(42, Multisig::get_packed_len(), &program_id);
4353 let multisig_delegate_key = Pubkey::new_unique();
4354 let mut multisig_delegate_account = GemachainAccount::new(
4355 multisig_minimum_balance(),
4356 Multisig::get_packed_len(),
4357 &program_id,
4358 );
4359 let signer_keys = vec![Pubkey::new_unique(); MAX_SIGNERS];
4360 let signer_key_refs: Vec<&Pubkey> = signer_keys.iter().collect();
4361 let mut signer_accounts = vec![GemachainAccount::new(0, 0, &program_id); MAX_SIGNERS];
4362 let mut rent_sysvar = rent_sysvar();
4363
4364 let account_info_iter = &mut signer_accounts.iter_mut();
4366 assert_eq!(
4367 Err(TokenError::NotRentExempt.into()),
4368 do_process_instruction(
4369 initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
4370 vec![
4371 &mut multisig_account,
4372 &mut rent_sysvar,
4373 &mut account_info_iter.next().unwrap(),
4374 ],
4375 )
4376 );
4377
4378 multisig_account.carats = multisig_minimum_balance();
4379 let mut multisig_account2 = multisig_account.clone();
4380
4381 let account_info_iter = &mut signer_accounts.iter_mut();
4383 do_process_instruction(
4384 initialize_multisig(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
4385 vec![
4386 &mut multisig_account,
4387 &mut rent_sysvar,
4388 &mut account_info_iter.next().unwrap(),
4389 ],
4390 )
4391 .unwrap();
4392
4393 let account_info_iter = &mut signer_accounts.iter_mut();
4395 do_process_instruction(
4396 initialize_multisig2(&program_id, &multisig_key, &[&signer_keys[0]], 1).unwrap(),
4397 vec![
4398 &mut multisig_account2,
4399 &mut account_info_iter.next().unwrap(),
4400 ],
4401 )
4402 .unwrap();
4403
4404 let account_info_iter = &mut signer_accounts.iter_mut();
4406 do_process_instruction(
4407 initialize_multisig(
4408 &program_id,
4409 &multisig_delegate_key,
4410 &signer_key_refs,
4411 MAX_SIGNERS as u8,
4412 )
4413 .unwrap(),
4414 vec![
4415 &mut multisig_delegate_account,
4416 &mut rent_sysvar,
4417 &mut account_info_iter.next().unwrap(),
4418 &mut account_info_iter.next().unwrap(),
4419 &mut account_info_iter.next().unwrap(),
4420 &mut account_info_iter.next().unwrap(),
4421 &mut account_info_iter.next().unwrap(),
4422 &mut account_info_iter.next().unwrap(),
4423 &mut account_info_iter.next().unwrap(),
4424 &mut account_info_iter.next().unwrap(),
4425 &mut account_info_iter.next().unwrap(),
4426 &mut account_info_iter.next().unwrap(),
4427 &mut account_info_iter.next().unwrap(),
4428 ],
4429 )
4430 .unwrap();
4431
4432 do_process_instruction(
4434 initialize_mint(&program_id, &mint_key, &multisig_key, None, 2).unwrap(),
4435 vec![&mut mint_account, &mut rent_sysvar],
4436 )
4437 .unwrap();
4438
4439 do_process_instruction(
4441 initialize_account(&program_id, &account_key, &mint_key, &multisig_key).unwrap(),
4442 vec![
4443 &mut account,
4444 &mut mint_account,
4445 &mut multisig_account,
4446 &mut rent_sysvar,
4447 ],
4448 )
4449 .unwrap();
4450
4451 do_process_instruction(
4453 initialize_account(
4454 &program_id,
4455 &account2_key,
4456 &mint_key,
4457 &multisig_delegate_key,
4458 )
4459 .unwrap(),
4460 vec![
4461 &mut account2_account,
4462 &mut mint_account,
4463 &mut multisig_account,
4464 &mut rent_sysvar,
4465 ],
4466 )
4467 .unwrap();
4468
4469 let account_info_iter = &mut signer_accounts.iter_mut();
4471 do_process_instruction(
4472 mint_to(
4473 &program_id,
4474 &mint_key,
4475 &account_key,
4476 &multisig_key,
4477 &[&signer_keys[0]],
4478 1000,
4479 )
4480 .unwrap(),
4481 vec![
4482 &mut mint_account,
4483 &mut account,
4484 &mut multisig_account,
4485 &mut account_info_iter.next().unwrap(),
4486 ],
4487 )
4488 .unwrap();
4489
4490 let account_info_iter = &mut signer_accounts.iter_mut();
4492 do_process_instruction(
4493 approve(
4494 &program_id,
4495 &account_key,
4496 &multisig_delegate_key,
4497 &multisig_key,
4498 &[&signer_keys[0]],
4499 100,
4500 )
4501 .unwrap(),
4502 vec![
4503 &mut account,
4504 &mut multisig_delegate_account,
4505 &mut multisig_account,
4506 &mut account_info_iter.next().unwrap(),
4507 ],
4508 )
4509 .unwrap();
4510
4511 let account_info_iter = &mut signer_accounts.iter_mut();
4513 do_process_instruction(
4514 transfer(
4515 &program_id,
4516 &account_key,
4517 &account2_key,
4518 &multisig_key,
4519 &[&signer_keys[0]],
4520 42,
4521 )
4522 .unwrap(),
4523 vec![
4524 &mut account,
4525 &mut account2_account,
4526 &mut multisig_account,
4527 &mut account_info_iter.next().unwrap(),
4528 ],
4529 )
4530 .unwrap();
4531
4532 let account_info_iter = &mut signer_accounts.iter_mut();
4534 do_process_instruction(
4535 transfer(
4536 &program_id,
4537 &account_key,
4538 &account2_key,
4539 &multisig_delegate_key,
4540 &signer_key_refs,
4541 42,
4542 )
4543 .unwrap(),
4544 vec![
4545 &mut account,
4546 &mut account2_account,
4547 &mut multisig_delegate_account,
4548 &mut account_info_iter.next().unwrap(),
4549 &mut account_info_iter.next().unwrap(),
4550 &mut account_info_iter.next().unwrap(),
4551 &mut account_info_iter.next().unwrap(),
4552 &mut account_info_iter.next().unwrap(),
4553 &mut account_info_iter.next().unwrap(),
4554 &mut account_info_iter.next().unwrap(),
4555 &mut account_info_iter.next().unwrap(),
4556 &mut account_info_iter.next().unwrap(),
4557 &mut account_info_iter.next().unwrap(),
4558 &mut account_info_iter.next().unwrap(),
4559 ],
4560 )
4561 .unwrap();
4562
4563 let account_info_iter = &mut signer_accounts.iter_mut();
4565 do_process_instruction(
4566 mint_to(
4567 &program_id,
4568 &mint_key,
4569 &account2_key,
4570 &multisig_key,
4571 &[&signer_keys[0]],
4572 42,
4573 )
4574 .unwrap(),
4575 vec![
4576 &mut mint_account,
4577 &mut account2_account,
4578 &mut multisig_account,
4579 &mut account_info_iter.next().unwrap(),
4580 ],
4581 )
4582 .unwrap();
4583
4584 let account_info_iter = &mut signer_accounts.iter_mut();
4586 do_process_instruction(
4587 burn(
4588 &program_id,
4589 &account_key,
4590 &mint_key,
4591 &multisig_key,
4592 &[&signer_keys[0]],
4593 42,
4594 )
4595 .unwrap(),
4596 vec![
4597 &mut account,
4598 &mut mint_account,
4599 &mut multisig_account,
4600 &mut account_info_iter.next().unwrap(),
4601 ],
4602 )
4603 .unwrap();
4604
4605 let account_info_iter = &mut signer_accounts.iter_mut();
4607 do_process_instruction(
4608 burn(
4609 &program_id,
4610 &account_key,
4611 &mint_key,
4612 &multisig_delegate_key,
4613 &signer_key_refs,
4614 42,
4615 )
4616 .unwrap(),
4617 vec![
4618 &mut account,
4619 &mut mint_account,
4620 &mut multisig_delegate_account,
4621 &mut account_info_iter.next().unwrap(),
4622 &mut account_info_iter.next().unwrap(),
4623 &mut account_info_iter.next().unwrap(),
4624 &mut account_info_iter.next().unwrap(),
4625 &mut account_info_iter.next().unwrap(),
4626 &mut account_info_iter.next().unwrap(),
4627 &mut account_info_iter.next().unwrap(),
4628 &mut account_info_iter.next().unwrap(),
4629 &mut account_info_iter.next().unwrap(),
4630 &mut account_info_iter.next().unwrap(),
4631 &mut account_info_iter.next().unwrap(),
4632 ],
4633 )
4634 .unwrap();
4635
4636 let account3_key = Pubkey::new_unique();
4638 let mut account3_account = GemachainAccount::new(
4639 account_minimum_balance(),
4640 Account::get_packed_len(),
4641 &program_id,
4642 );
4643 let mint2_key = Pubkey::new_unique();
4644 let mut mint2_account =
4645 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4646 do_process_instruction(
4647 initialize_mint(
4648 &program_id,
4649 &mint2_key,
4650 &multisig_key,
4651 Some(&multisig_key),
4652 2,
4653 )
4654 .unwrap(),
4655 vec![&mut mint2_account, &mut rent_sysvar],
4656 )
4657 .unwrap();
4658 do_process_instruction(
4659 initialize_account(&program_id, &account3_key, &mint2_key, &owner_key).unwrap(),
4660 vec![
4661 &mut account3_account,
4662 &mut mint2_account,
4663 &mut owner_account,
4664 &mut rent_sysvar,
4665 ],
4666 )
4667 .unwrap();
4668 let account_info_iter = &mut signer_accounts.iter_mut();
4669 do_process_instruction(
4670 mint_to(
4671 &program_id,
4672 &mint2_key,
4673 &account3_key,
4674 &multisig_key,
4675 &[&signer_keys[0]],
4676 1000,
4677 )
4678 .unwrap(),
4679 vec![
4680 &mut mint2_account,
4681 &mut account3_account,
4682 &mut multisig_account,
4683 &mut account_info_iter.next().unwrap(),
4684 ],
4685 )
4686 .unwrap();
4687 let account_info_iter = &mut signer_accounts.iter_mut();
4688 do_process_instruction(
4689 freeze_account(
4690 &program_id,
4691 &account3_key,
4692 &mint2_key,
4693 &multisig_key,
4694 &[&signer_keys[0]],
4695 )
4696 .unwrap(),
4697 vec![
4698 &mut account3_account,
4699 &mut mint2_account,
4700 &mut multisig_account,
4701 &mut account_info_iter.next().unwrap(),
4702 ],
4703 )
4704 .unwrap();
4705
4706 let account_info_iter = &mut signer_accounts.iter_mut();
4708 do_process_instruction(
4709 set_authority(
4710 &program_id,
4711 &mint_key,
4712 Some(&owner_key),
4713 AuthorityType::MintTokens,
4714 &multisig_key,
4715 &[&signer_keys[0]],
4716 )
4717 .unwrap(),
4718 vec![
4719 &mut mint_account,
4720 &mut multisig_account,
4721 &mut account_info_iter.next().unwrap(),
4722 ],
4723 )
4724 .unwrap();
4725
4726 let account_info_iter = &mut signer_accounts.iter_mut();
4728 do_process_instruction(
4729 set_authority(
4730 &program_id,
4731 &account_key,
4732 Some(&owner_key),
4733 AuthorityType::AccountOwner,
4734 &multisig_key,
4735 &[&signer_keys[0]],
4736 )
4737 .unwrap(),
4738 vec![
4739 &mut account,
4740 &mut multisig_account,
4741 &mut account_info_iter.next().unwrap(),
4742 ],
4743 )
4744 .unwrap();
4745 }
4746
4747 #[test]
4748 fn test_validate_owner() {
4749 let program_id = crate::id();
4750 let owner_key = Pubkey::new_unique();
4751 let mut signer_keys = [Pubkey::default(); MAX_SIGNERS];
4752 for signer_key in signer_keys.iter_mut().take(MAX_SIGNERS) {
4753 *signer_key = Pubkey::new_unique();
4754 }
4755 let mut signer_carats = 0;
4756 let mut signer_data = vec![];
4757 let mut signers = vec![
4758 AccountInfo::new(
4759 &owner_key,
4760 true,
4761 false,
4762 &mut signer_carats,
4763 &mut signer_data,
4764 &program_id,
4765 false,
4766 Epoch::default(),
4767 );
4768 MAX_SIGNERS + 1
4769 ];
4770 for (signer, key) in signers.iter_mut().zip(&signer_keys) {
4771 signer.key = key;
4772 }
4773 let mut carats = 0;
4774 let mut data = vec![0; Multisig::get_packed_len()];
4775 let mut multisig = Multisig::unpack_unchecked(&data).unwrap();
4776 multisig.m = MAX_SIGNERS as u8;
4777 multisig.n = MAX_SIGNERS as u8;
4778 multisig.signers = signer_keys;
4779 multisig.is_initialized = true;
4780 Multisig::pack(multisig, &mut data).unwrap();
4781 let owner_account_info = AccountInfo::new(
4782 &owner_key,
4783 false,
4784 false,
4785 &mut carats,
4786 &mut data,
4787 &program_id,
4788 false,
4789 Epoch::default(),
4790 );
4791
4792 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
4794
4795 {
4797 let mut multisig =
4798 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4799 multisig.m = 1;
4800 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4801 }
4802 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
4803
4804 {
4806 let mut multisig =
4807 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4808 multisig.m = 2;
4809 multisig.n = 1;
4810 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4811 }
4812 assert_eq!(
4813 Err(ProgramError::MissingRequiredSignature),
4814 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
4815 );
4816
4817 {
4819 let mut multisig =
4820 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4821 multisig.m = 0;
4822 multisig.n = 11;
4823 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4824 }
4825 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
4826
4827 {
4829 let mut multisig =
4830 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4831 multisig.m = 2;
4832 multisig.n = 11;
4833 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4834 }
4835 assert_eq!(
4836 Err(ProgramError::MissingRequiredSignature),
4837 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &[])
4838 );
4839 {
4841 let mut multisig =
4842 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4843 multisig.m = 2;
4844 multisig.n = 11;
4845 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4846 }
4847 assert_eq!(
4848 Err(ProgramError::MissingRequiredSignature),
4849 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[0..1])
4850 );
4851
4852 {
4854 let mut multisig =
4855 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4856 multisig.m = 2;
4857 multisig.n = 11;
4858 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4859 }
4860 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[5..7])
4861 .unwrap();
4862
4863 {
4865 let mut multisig =
4866 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4867 multisig.m = 11;
4868 multisig.n = 11;
4869 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4870 }
4871 signers[5].is_signer = false;
4872 assert_eq!(
4873 Err(ProgramError::MissingRequiredSignature),
4874 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
4875 );
4876 signers[5].is_signer = true;
4877
4878 {
4880 let mut signer_carats = 0;
4881 let mut signer_data = vec![];
4882 let signers = vec![
4883 AccountInfo::new(
4884 &signer_keys[5],
4885 true,
4886 false,
4887 &mut signer_carats,
4888 &mut signer_data,
4889 &program_id,
4890 false,
4891 Epoch::default(),
4892 );
4893 MAX_SIGNERS + 1
4894 ];
4895 let mut multisig =
4896 Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
4897 multisig.m = 11;
4898 multisig.n = 11;
4899 Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
4900 assert_eq!(
4901 Err(ProgramError::MissingRequiredSignature),
4902 Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers)
4903 );
4904 }
4905 }
4906
4907 #[test]
4908 fn test_close_account_dups() {
4909 let program_id = crate::id();
4910 let account1_key = Pubkey::new_unique();
4911 let mut account1_account = GemachainAccount::new(
4912 account_minimum_balance(),
4913 Account::get_packed_len(),
4914 &program_id,
4915 );
4916 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
4917 let account2_key = Pubkey::new_unique();
4918 let mut account2_account = GemachainAccount::new(
4919 account_minimum_balance(),
4920 Account::get_packed_len(),
4921 &program_id,
4922 );
4923 let account2_info: AccountInfo = (&account2_key, true, &mut account2_account).into();
4924 let owner_key = Pubkey::new_unique();
4925 let mint_key = Pubkey::new_unique();
4926 let mut mint_account =
4927 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4928 let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into();
4929 let rent_key = rent::id();
4930 let mut rent_sysvar = rent_sysvar();
4931 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
4932
4933 do_process_instruction_dups(
4935 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
4936 vec![mint_info.clone(), rent_info.clone()],
4937 )
4938 .unwrap();
4939
4940 do_process_instruction_dups(
4942 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
4943 vec![
4944 account1_info.clone(),
4945 mint_info.clone(),
4946 account1_info.clone(),
4947 rent_info.clone(),
4948 ],
4949 )
4950 .unwrap();
4951
4952 do_process_instruction_dups(
4954 close_account(
4955 &program_id,
4956 &account1_key,
4957 &account2_key,
4958 &account1_key,
4959 &[],
4960 )
4961 .unwrap(),
4962 vec![
4963 account1_info.clone(),
4964 account2_info.clone(),
4965 account1_info.clone(),
4966 ],
4967 )
4968 .unwrap();
4969
4970 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
4972 account.close_authority = COption::Some(account1_key);
4973 account.owner = owner_key;
4974 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
4975 do_process_instruction_dups(
4976 close_account(
4977 &program_id,
4978 &account1_key,
4979 &account2_key,
4980 &account1_key,
4981 &[],
4982 )
4983 .unwrap(),
4984 vec![
4985 account1_info.clone(),
4986 account2_info.clone(),
4987 account1_info.clone(),
4988 ],
4989 )
4990 .unwrap();
4991 }
4992
4993 #[test]
4994 fn test_close_account() {
4995 let program_id = crate::id();
4996 let mint_key = Pubkey::new_unique();
4997 let mut mint_account =
4998 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
4999 let account_key = Pubkey::new_unique();
5000 let mut account_account = GemachainAccount::new(
5001 account_minimum_balance(),
5002 Account::get_packed_len(),
5003 &program_id,
5004 );
5005 let account2_key = Pubkey::new_unique();
5006 let mut account2_account = GemachainAccount::new(
5007 account_minimum_balance() + 42,
5008 Account::get_packed_len(),
5009 &program_id,
5010 );
5011 let account3_key = Pubkey::new_unique();
5012 let mut account3_account = GemachainAccount::new(
5013 account_minimum_balance(),
5014 Account::get_packed_len(),
5015 &program_id,
5016 );
5017 let owner_key = Pubkey::new_unique();
5018 let mut owner_account = GemachainAccount::default();
5019 let owner2_key = Pubkey::new_unique();
5020 let mut owner2_account = GemachainAccount::default();
5021 let mut rent_sysvar = rent_sysvar();
5022
5023 assert_eq!(
5025 Err(ProgramError::UninitializedAccount),
5026 do_process_instruction(
5027 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
5028 vec![
5029 &mut account_account,
5030 &mut account3_account,
5031 &mut owner2_account,
5032 ],
5033 )
5034 );
5035
5036 do_process_instruction(
5038 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
5039 vec![&mut mint_account, &mut rent_sysvar],
5040 )
5041 .unwrap();
5042 do_process_instruction(
5043 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
5044 vec![
5045 &mut account_account,
5046 &mut mint_account,
5047 &mut owner_account,
5048 &mut rent_sysvar,
5049 ],
5050 )
5051 .unwrap();
5052 do_process_instruction(
5053 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
5054 vec![
5055 &mut mint_account,
5056 &mut account_account,
5057 &mut owner_account,
5058 &mut rent_sysvar,
5059 ],
5060 )
5061 .unwrap();
5062 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5063 assert_eq!(account.amount, 42);
5064
5065 do_process_instruction(
5067 initialize_account(
5068 &program_id,
5069 &account2_key,
5070 &crate::native_mint::id(),
5071 &owner_key,
5072 )
5073 .unwrap(),
5074 vec![
5075 &mut account2_account,
5076 &mut mint_account,
5077 &mut owner_account,
5078 &mut rent_sysvar,
5079 ],
5080 )
5081 .unwrap();
5082 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
5083 assert!(account.is_native());
5084 assert_eq!(account.amount, 42);
5085
5086 assert_eq!(
5088 Err(TokenError::NonNativeHasBalance.into()),
5089 do_process_instruction(
5090 close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
5091 vec![
5092 &mut account_account,
5093 &mut account3_account,
5094 &mut owner_account,
5095 ],
5096 )
5097 );
5098 assert_eq!(account_account.carats, account_minimum_balance());
5099
5100 do_process_instruction(
5102 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 42).unwrap(),
5103 vec![&mut account_account, &mut mint_account, &mut owner_account],
5104 )
5105 .unwrap();
5106
5107 assert_eq!(
5109 Err(TokenError::OwnerMismatch.into()),
5110 do_process_instruction(
5111 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
5112 vec![
5113 &mut account_account,
5114 &mut account3_account,
5115 &mut owner2_account,
5116 ],
5117 )
5118 );
5119
5120 do_process_instruction(
5122 close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
5123 vec![
5124 &mut account_account,
5125 &mut account3_account,
5126 &mut owner_account,
5127 ],
5128 )
5129 .unwrap();
5130 assert_eq!(account_account.carats, 0);
5131 assert_eq!(account3_account.carats, 2 * account_minimum_balance());
5132 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5133 assert_eq!(account.amount, 0);
5134
5135 let account_key = Pubkey::new_unique();
5137 let mut account_account = GemachainAccount::new(
5138 account_minimum_balance(),
5139 Account::get_packed_len(),
5140 &program_id,
5141 );
5142 let owner2_key = Pubkey::new_unique();
5143 let mut owner2_account = GemachainAccount::new(
5144 account_minimum_balance(),
5145 Account::get_packed_len(),
5146 &program_id,
5147 );
5148 do_process_instruction(
5149 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
5150 vec![
5151 &mut account_account,
5152 &mut mint_account,
5153 &mut owner_account,
5154 &mut rent_sysvar,
5155 ],
5156 )
5157 .unwrap();
5158 account_account.carats = 2;
5159
5160 do_process_instruction(
5161 set_authority(
5162 &program_id,
5163 &account_key,
5164 Some(&owner2_key),
5165 AuthorityType::CloseAccount,
5166 &owner_key,
5167 &[],
5168 )
5169 .unwrap(),
5170 vec![&mut account_account, &mut owner_account],
5171 )
5172 .unwrap();
5173
5174 assert_eq!(
5176 Err(TokenError::OwnerMismatch.into()),
5177 do_process_instruction(
5178 close_account(&program_id, &account_key, &account3_key, &owner_key, &[]).unwrap(),
5179 vec![
5180 &mut account_account,
5181 &mut account3_account,
5182 &mut owner_account,
5183 ],
5184 )
5185 );
5186
5187 do_process_instruction(
5189 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
5190 vec![
5191 &mut account_account,
5192 &mut account3_account,
5193 &mut owner2_account,
5194 ],
5195 )
5196 .unwrap();
5197 assert_eq!(account_account.carats, 0);
5198 assert_eq!(account3_account.carats, 2 * account_minimum_balance() + 2);
5199 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5200 assert_eq!(account.amount, 0);
5201
5202 do_process_instruction(
5204 close_account(&program_id, &account2_key, &account3_key, &owner_key, &[]).unwrap(),
5205 vec![
5206 &mut account2_account,
5207 &mut account3_account,
5208 &mut owner_account,
5209 ],
5210 )
5211 .unwrap();
5212 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
5213 assert!(account.is_native());
5214 assert_eq!(account_account.carats, 0);
5215 assert_eq!(account.amount, 0);
5216 assert_eq!(
5217 account3_account.carats,
5218 3 * account_minimum_balance() + 2 + 42
5219 );
5220 }
5221
5222 #[test]
5223 fn test_native_token() {
5224 let program_id = crate::id();
5225 let mut mint_account =
5226 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5227 let account_key = Pubkey::new_unique();
5228 let mut account_account = GemachainAccount::new(
5229 account_minimum_balance() + 40,
5230 Account::get_packed_len(),
5231 &program_id,
5232 );
5233 let account2_key = Pubkey::new_unique();
5234 let mut account2_account = GemachainAccount::new(
5235 account_minimum_balance(),
5236 Account::get_packed_len(),
5237 &program_id,
5238 );
5239 let account3_key = Pubkey::new_unique();
5240 let mut account3_account = GemachainAccount::new(account_minimum_balance(), 0, &program_id);
5241 let owner_key = Pubkey::new_unique();
5242 let mut owner_account = GemachainAccount::default();
5243 let owner2_key = Pubkey::new_unique();
5244 let mut owner2_account = GemachainAccount::default();
5245 let owner3_key = Pubkey::new_unique();
5246 let mut rent_sysvar = rent_sysvar();
5247
5248 do_process_instruction(
5250 initialize_account(
5251 &program_id,
5252 &account_key,
5253 &crate::native_mint::id(),
5254 &owner_key,
5255 )
5256 .unwrap(),
5257 vec![
5258 &mut account_account,
5259 &mut mint_account,
5260 &mut owner_account,
5261 &mut rent_sysvar,
5262 ],
5263 )
5264 .unwrap();
5265 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5266 assert!(account.is_native());
5267 assert_eq!(account.amount, 40);
5268
5269 do_process_instruction(
5271 initialize_account(
5272 &program_id,
5273 &account2_key,
5274 &crate::native_mint::id(),
5275 &owner_key,
5276 )
5277 .unwrap(),
5278 vec![
5279 &mut account2_account,
5280 &mut mint_account,
5281 &mut owner_account,
5282 &mut rent_sysvar,
5283 ],
5284 )
5285 .unwrap();
5286 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
5287 assert!(account.is_native());
5288 assert_eq!(account.amount, 0);
5289
5290 assert_eq!(
5292 Err(TokenError::NativeNotSupported.into()),
5293 do_process_instruction(
5294 mint_to(
5295 &program_id,
5296 &crate::native_mint::id(),
5297 &account_key,
5298 &owner_key,
5299 &[],
5300 42
5301 )
5302 .unwrap(),
5303 vec![&mut mint_account, &mut account_account, &mut owner_account],
5304 )
5305 );
5306
5307 let bogus_mint_key = Pubkey::new_unique();
5309 let mut bogus_mint_account =
5310 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5311 do_process_instruction(
5312 initialize_mint(&program_id, &bogus_mint_key, &owner_key, None, 2).unwrap(),
5313 vec![&mut bogus_mint_account, &mut rent_sysvar],
5314 )
5315 .unwrap();
5316
5317 assert_eq!(
5318 Err(TokenError::NativeNotSupported.into()),
5319 do_process_instruction(
5320 burn(
5321 &program_id,
5322 &account_key,
5323 &bogus_mint_key,
5324 &owner_key,
5325 &[],
5326 42
5327 )
5328 .unwrap(),
5329 vec![
5330 &mut account_account,
5331 &mut bogus_mint_account,
5332 &mut owner_account
5333 ],
5334 )
5335 );
5336
5337 assert_eq!(
5339 Err(TokenError::InsufficientFunds.into()),
5340 do_process_instruction(
5341 transfer(
5342 &program_id,
5343 &account_key,
5344 &account2_key,
5345 &owner_key,
5346 &[],
5347 50,
5348 )
5349 .unwrap(),
5350 vec![
5351 &mut account_account,
5352 &mut account2_account,
5353 &mut owner_account,
5354 ],
5355 )
5356 );
5357
5358 do_process_instruction(
5360 transfer(
5361 &program_id,
5362 &account_key,
5363 &account2_key,
5364 &owner_key,
5365 &[],
5366 40,
5367 )
5368 .unwrap(),
5369 vec![
5370 &mut account_account,
5371 &mut account2_account,
5372 &mut owner_account,
5373 ],
5374 )
5375 .unwrap();
5376 assert_eq!(account_account.carats, account_minimum_balance());
5377 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5378 assert!(account.is_native());
5379 assert_eq!(account.amount, 0);
5380 assert_eq!(account2_account.carats, account_minimum_balance() + 40);
5381 let account = Account::unpack_unchecked(&account2_account.data).unwrap();
5382 assert!(account.is_native());
5383 assert_eq!(account.amount, 40);
5384
5385 do_process_instruction(
5387 set_authority(
5388 &program_id,
5389 &account_key,
5390 Some(&owner3_key),
5391 AuthorityType::CloseAccount,
5392 &owner_key,
5393 &[],
5394 )
5395 .unwrap(),
5396 vec![&mut account_account, &mut owner_account],
5397 )
5398 .unwrap();
5399 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5400 assert_eq!(account.close_authority, COption::Some(owner3_key));
5401
5402 do_process_instruction(
5404 set_authority(
5405 &program_id,
5406 &account_key,
5407 Some(&owner2_key),
5408 AuthorityType::AccountOwner,
5409 &owner_key,
5410 &[],
5411 )
5412 .unwrap(),
5413 vec![&mut account_account, &mut owner_account],
5414 )
5415 .unwrap();
5416
5417 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5419 assert_eq!(account.close_authority, COption::None);
5420
5421 do_process_instruction(
5423 close_account(&program_id, &account_key, &account3_key, &owner2_key, &[]).unwrap(),
5424 vec![
5425 &mut account_account,
5426 &mut account3_account,
5427 &mut owner2_account,
5428 ],
5429 )
5430 .unwrap();
5431 assert_eq!(account_account.carats, 0);
5432 assert_eq!(account3_account.carats, 2 * account_minimum_balance());
5433 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5434 assert!(account.is_native());
5435 assert_eq!(account.amount, 0);
5436 }
5437
5438 #[test]
5439 fn test_overflow() {
5440 let program_id = crate::id();
5441 let account_key = Pubkey::new_unique();
5442 let mut account_account = GemachainAccount::new(
5443 account_minimum_balance(),
5444 Account::get_packed_len(),
5445 &program_id,
5446 );
5447 let account2_key = Pubkey::new_unique();
5448 let mut account2_account = GemachainAccount::new(
5449 account_minimum_balance(),
5450 Account::get_packed_len(),
5451 &program_id,
5452 );
5453 let owner_key = Pubkey::new_unique();
5454 let mut owner_account = GemachainAccount::default();
5455 let owner2_key = Pubkey::new_unique();
5456 let mut owner2_account = GemachainAccount::default();
5457 let mint_owner_key = Pubkey::new_unique();
5458 let mut mint_owner_account = GemachainAccount::default();
5459 let mint_key = Pubkey::new_unique();
5460 let mut mint_account =
5461 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5462 let mut rent_sysvar = rent_sysvar();
5463
5464 do_process_instruction(
5466 initialize_mint(&program_id, &mint_key, &mint_owner_key, None, 2).unwrap(),
5467 vec![&mut mint_account, &mut rent_sysvar],
5468 )
5469 .unwrap();
5470
5471 do_process_instruction(
5473 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
5474 vec![
5475 &mut account_account,
5476 &mut mint_account,
5477 &mut owner_account,
5478 &mut rent_sysvar,
5479 ],
5480 )
5481 .unwrap();
5482
5483 do_process_instruction(
5485 initialize_account(&program_id, &account2_key, &mint_key, &owner2_key).unwrap(),
5486 vec![
5487 &mut account2_account,
5488 &mut mint_account,
5489 &mut owner2_account,
5490 &mut rent_sysvar,
5491 ],
5492 )
5493 .unwrap();
5494
5495 do_process_instruction(
5497 mint_to(
5498 &program_id,
5499 &mint_key,
5500 &account_key,
5501 &mint_owner_key,
5502 &[],
5503 u64::MAX,
5504 )
5505 .unwrap(),
5506 vec![
5507 &mut mint_account,
5508 &mut account_account,
5509 &mut mint_owner_account,
5510 ],
5511 )
5512 .unwrap();
5513 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5514 assert_eq!(account.amount, u64::MAX);
5515
5516 assert_eq!(
5518 Err(TokenError::Overflow.into()),
5519 do_process_instruction(
5520 mint_to(
5521 &program_id,
5522 &mint_key,
5523 &account_key,
5524 &mint_owner_key,
5525 &[],
5526 1,
5527 )
5528 .unwrap(),
5529 vec![
5530 &mut mint_account,
5531 &mut account_account,
5532 &mut mint_owner_account,
5533 ],
5534 )
5535 );
5536 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5537 assert_eq!(account.amount, u64::MAX);
5538
5539 assert_eq!(
5541 Err(TokenError::Overflow.into()),
5542 do_process_instruction(
5543 mint_to(
5544 &program_id,
5545 &mint_key,
5546 &account2_key,
5547 &mint_owner_key,
5548 &[],
5549 1,
5550 )
5551 .unwrap(),
5552 vec![
5553 &mut mint_account,
5554 &mut account2_account,
5555 &mut mint_owner_account,
5556 ],
5557 )
5558 );
5559
5560 do_process_instruction(
5562 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
5563 vec![&mut account_account, &mut mint_account, &mut owner_account],
5564 )
5565 .unwrap();
5566 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5567 assert_eq!(account.amount, u64::MAX - 100);
5568
5569 do_process_instruction(
5570 mint_to(
5571 &program_id,
5572 &mint_key,
5573 &account_key,
5574 &mint_owner_key,
5575 &[],
5576 100,
5577 )
5578 .unwrap(),
5579 vec![
5580 &mut mint_account,
5581 &mut account_account,
5582 &mut mint_owner_account,
5583 ],
5584 )
5585 .unwrap();
5586 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5587 assert_eq!(account.amount, u64::MAX);
5588
5589 let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
5591 account.amount = 1;
5592 Account::pack(account, &mut account2_account.data).unwrap();
5593
5594 assert_eq!(
5595 Err(TokenError::Overflow.into()),
5596 do_process_instruction(
5597 transfer(
5598 &program_id,
5599 &account2_key,
5600 &account_key,
5601 &owner2_key,
5602 &[],
5603 1,
5604 )
5605 .unwrap(),
5606 vec![
5607 &mut account2_account,
5608 &mut account_account,
5609 &mut owner2_account,
5610 ],
5611 )
5612 );
5613 }
5614
5615 #[test]
5616 fn test_frozen() {
5617 let program_id = crate::id();
5618 let account_key = Pubkey::new_unique();
5619 let mut account_account = GemachainAccount::new(
5620 account_minimum_balance(),
5621 Account::get_packed_len(),
5622 &program_id,
5623 );
5624 let account2_key = Pubkey::new_unique();
5625 let mut account2_account = GemachainAccount::new(
5626 account_minimum_balance(),
5627 Account::get_packed_len(),
5628 &program_id,
5629 );
5630 let owner_key = Pubkey::new_unique();
5631 let mut owner_account = GemachainAccount::default();
5632 let mint_key = Pubkey::new_unique();
5633 let mut mint_account =
5634 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5635 let mut rent_sysvar = rent_sysvar();
5636
5637 do_process_instruction(
5639 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
5640 vec![&mut mint_account, &mut rent_sysvar],
5641 )
5642 .unwrap();
5643
5644 do_process_instruction(
5646 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
5647 vec![
5648 &mut account_account,
5649 &mut mint_account,
5650 &mut owner_account,
5651 &mut rent_sysvar,
5652 ],
5653 )
5654 .unwrap();
5655
5656 do_process_instruction(
5658 initialize_account(&program_id, &account2_key, &mint_key, &owner_key).unwrap(),
5659 vec![
5660 &mut account2_account,
5661 &mut mint_account,
5662 &mut owner_account,
5663 &mut rent_sysvar,
5664 ],
5665 )
5666 .unwrap();
5667
5668 do_process_instruction(
5670 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
5671 vec![&mut mint_account, &mut account_account, &mut owner_account],
5672 )
5673 .unwrap();
5674
5675 let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
5677 account.state = AccountState::Frozen;
5678 Account::pack(account, &mut account2_account.data).unwrap();
5679 assert_eq!(
5680 Err(TokenError::AccountFrozen.into()),
5681 do_process_instruction(
5682 transfer(
5683 &program_id,
5684 &account_key,
5685 &account2_key,
5686 &owner_key,
5687 &[],
5688 500,
5689 )
5690 .unwrap(),
5691 vec![
5692 &mut account_account,
5693 &mut account2_account,
5694 &mut owner_account,
5695 ],
5696 )
5697 );
5698
5699 let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
5700 account.state = AccountState::Initialized;
5701 Account::pack(account, &mut account_account.data).unwrap();
5702 let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
5703 account.state = AccountState::Frozen;
5704 Account::pack(account, &mut account2_account.data).unwrap();
5705 assert_eq!(
5706 Err(TokenError::AccountFrozen.into()),
5707 do_process_instruction(
5708 transfer(
5709 &program_id,
5710 &account_key,
5711 &account2_key,
5712 &owner_key,
5713 &[],
5714 500,
5715 )
5716 .unwrap(),
5717 vec![
5718 &mut account_account,
5719 &mut account2_account,
5720 &mut owner_account,
5721 ],
5722 )
5723 );
5724
5725 let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
5727 account.state = AccountState::Frozen;
5728 Account::pack(account, &mut account_account.data).unwrap();
5729 let delegate_key = Pubkey::new_unique();
5730 let mut delegate_account = GemachainAccount::default();
5731 assert_eq!(
5732 Err(TokenError::AccountFrozen.into()),
5733 do_process_instruction(
5734 approve(
5735 &program_id,
5736 &account_key,
5737 &delegate_key,
5738 &owner_key,
5739 &[],
5740 100
5741 )
5742 .unwrap(),
5743 vec![
5744 &mut account_account,
5745 &mut delegate_account,
5746 &mut owner_account,
5747 ],
5748 )
5749 );
5750
5751 let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
5753 account.delegate = COption::Some(delegate_key);
5754 account.delegated_amount = 100;
5755 Account::pack(account, &mut account_account.data).unwrap();
5756 assert_eq!(
5757 Err(TokenError::AccountFrozen.into()),
5758 do_process_instruction(
5759 revoke(&program_id, &account_key, &owner_key, &[]).unwrap(),
5760 vec![&mut account_account, &mut owner_account],
5761 )
5762 );
5763
5764 let new_owner_key = Pubkey::new_unique();
5766 assert_eq!(
5767 Err(TokenError::AccountFrozen.into()),
5768 do_process_instruction(
5769 set_authority(
5770 &program_id,
5771 &account_key,
5772 Some(&new_owner_key),
5773 AuthorityType::AccountOwner,
5774 &owner_key,
5775 &[]
5776 )
5777 .unwrap(),
5778 vec![&mut account_account, &mut owner_account,],
5779 )
5780 );
5781
5782 assert_eq!(
5784 Err(TokenError::AccountFrozen.into()),
5785 do_process_instruction(
5786 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 100).unwrap(),
5787 vec![&mut mint_account, &mut account_account, &mut owner_account,],
5788 )
5789 );
5790
5791 assert_eq!(
5793 Err(TokenError::AccountFrozen.into()),
5794 do_process_instruction(
5795 burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
5796 vec![&mut account_account, &mut mint_account, &mut owner_account],
5797 )
5798 );
5799 }
5800
5801 #[test]
5802 fn test_freeze_thaw_dups() {
5803 let program_id = crate::id();
5804 let account1_key = Pubkey::new_unique();
5805 let mut account1_account = GemachainAccount::new(
5806 account_minimum_balance(),
5807 Account::get_packed_len(),
5808 &program_id,
5809 );
5810 let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
5811 let owner_key = Pubkey::new_unique();
5812 let mint_key = Pubkey::new_unique();
5813 let mut mint_account =
5814 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5815 let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
5816 let rent_key = rent::id();
5817 let mut rent_sysvar = rent_sysvar();
5818 let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
5819
5820 do_process_instruction_dups(
5822 initialize_mint(&program_id, &mint_key, &owner_key, Some(&account1_key), 2).unwrap(),
5823 vec![mint_info.clone(), rent_info.clone()],
5824 )
5825 .unwrap();
5826
5827 do_process_instruction_dups(
5829 initialize_account(&program_id, &account1_key, &mint_key, &account1_key).unwrap(),
5830 vec![
5831 account1_info.clone(),
5832 mint_info.clone(),
5833 account1_info.clone(),
5834 rent_info.clone(),
5835 ],
5836 )
5837 .unwrap();
5838
5839 do_process_instruction_dups(
5841 freeze_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
5842 vec![
5843 account1_info.clone(),
5844 mint_info.clone(),
5845 account1_info.clone(),
5846 ],
5847 )
5848 .unwrap();
5849
5850 let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
5852 account.state = AccountState::Frozen;
5853 Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
5854 do_process_instruction_dups(
5855 thaw_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
5856 vec![
5857 account1_info.clone(),
5858 mint_info.clone(),
5859 account1_info.clone(),
5860 ],
5861 )
5862 .unwrap();
5863 }
5864
5865 #[test]
5866 fn test_freeze_account() {
5867 let program_id = crate::id();
5868 let account_key = Pubkey::new_unique();
5869 let mut account_account = GemachainAccount::new(
5870 account_minimum_balance(),
5871 Account::get_packed_len(),
5872 &program_id,
5873 );
5874 let account_owner_key = Pubkey::new_unique();
5875 let mut account_owner_account = GemachainAccount::default();
5876 let owner_key = Pubkey::new_unique();
5877 let mut owner_account = GemachainAccount::default();
5878 let owner2_key = Pubkey::new_unique();
5879 let mut owner2_account = GemachainAccount::default();
5880 let mint_key = Pubkey::new_unique();
5881 let mut mint_account =
5882 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
5883 let mut rent_sysvar = rent_sysvar();
5884
5885 do_process_instruction(
5887 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
5888 vec![&mut mint_account, &mut rent_sysvar],
5889 )
5890 .unwrap();
5891
5892 do_process_instruction(
5894 initialize_account(&program_id, &account_key, &mint_key, &account_owner_key).unwrap(),
5895 vec![
5896 &mut account_account,
5897 &mut mint_account,
5898 &mut account_owner_account,
5899 &mut rent_sysvar,
5900 ],
5901 )
5902 .unwrap();
5903
5904 do_process_instruction(
5906 mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(),
5907 vec![&mut mint_account, &mut account_account, &mut owner_account],
5908 )
5909 .unwrap();
5910
5911 assert_eq!(
5913 Err(TokenError::MintCannotFreeze.into()),
5914 do_process_instruction(
5915 freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
5916 vec![&mut account_account, &mut mint_account, &mut owner_account],
5917 )
5918 );
5919
5920 let mut mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
5922 mint.freeze_authority = COption::Some(owner_key);
5923 Mint::pack(mint, &mut mint_account.data).unwrap();
5924 assert_eq!(
5925 Err(TokenError::OwnerMismatch.into()),
5926 do_process_instruction(
5927 freeze_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
5928 vec![&mut account_account, &mut mint_account, &mut owner2_account],
5929 )
5930 );
5931
5932 assert_eq!(
5934 Err(TokenError::InvalidState.into()),
5935 do_process_instruction(
5936 thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
5937 vec![&mut account_account, &mut mint_account, &mut owner2_account],
5938 )
5939 );
5940
5941 do_process_instruction(
5943 freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
5944 vec![&mut account_account, &mut mint_account, &mut owner_account],
5945 )
5946 .unwrap();
5947 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5948 assert_eq!(account.state, AccountState::Frozen);
5949
5950 assert_eq!(
5952 Err(TokenError::InvalidState.into()),
5953 do_process_instruction(
5954 freeze_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
5955 vec![&mut account_account, &mut mint_account, &mut owner_account],
5956 )
5957 );
5958
5959 assert_eq!(
5961 Err(TokenError::OwnerMismatch.into()),
5962 do_process_instruction(
5963 thaw_account(&program_id, &account_key, &mint_key, &owner2_key, &[]).unwrap(),
5964 vec![&mut account_account, &mut mint_account, &mut owner2_account],
5965 )
5966 );
5967
5968 do_process_instruction(
5970 thaw_account(&program_id, &account_key, &mint_key, &owner_key, &[]).unwrap(),
5971 vec![&mut account_account, &mut mint_account, &mut owner_account],
5972 )
5973 .unwrap();
5974 let account = Account::unpack_unchecked(&account_account.data).unwrap();
5975 assert_eq!(account.state, AccountState::Initialized);
5976 }
5977
5978 #[test]
5979 fn test_initialize_account2_and_3() {
5980 let program_id = crate::id();
5981 let account_key = Pubkey::new_unique();
5982 let mut account_account = GemachainAccount::new(
5983 account_minimum_balance(),
5984 Account::get_packed_len(),
5985 &program_id,
5986 );
5987 let mut account2_account = GemachainAccount::new(
5988 account_minimum_balance(),
5989 Account::get_packed_len(),
5990 &program_id,
5991 );
5992 let mut account3_account = GemachainAccount::new(
5993 account_minimum_balance(),
5994 Account::get_packed_len(),
5995 &program_id,
5996 );
5997 let owner_key = Pubkey::new_unique();
5998 let mut owner_account = GemachainAccount::default();
5999 let mint_key = Pubkey::new_unique();
6000 let mut mint_account =
6001 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6002 let mut rent_sysvar = rent_sysvar();
6003
6004 do_process_instruction(
6006 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6007 vec![&mut mint_account, &mut rent_sysvar],
6008 )
6009 .unwrap();
6010
6011 do_process_instruction(
6012 initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6013 vec![
6014 &mut account_account,
6015 &mut mint_account,
6016 &mut owner_account,
6017 &mut rent_sysvar,
6018 ],
6019 )
6020 .unwrap();
6021
6022 do_process_instruction(
6023 initialize_account2(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6024 vec![&mut account2_account, &mut mint_account, &mut rent_sysvar],
6025 )
6026 .unwrap();
6027
6028 assert_eq!(account_account, account2_account);
6029
6030 do_process_instruction(
6031 initialize_account3(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
6032 vec![&mut account3_account, &mut mint_account],
6033 )
6034 .unwrap();
6035
6036 assert_eq!(account_account, account3_account);
6037 }
6038
6039 #[test]
6040 fn test_sync_native() {
6041 let program_id = crate::id();
6042 let mint_key = Pubkey::new_unique();
6043 let mut mint_account =
6044 GemachainAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
6045 let native_account_key = Pubkey::new_unique();
6046 let carats = 40;
6047 let mut native_account = GemachainAccount::new(
6048 account_minimum_balance() + carats,
6049 Account::get_packed_len(),
6050 &program_id,
6051 );
6052 let non_native_account_key = Pubkey::new_unique();
6053 let mut non_native_account = GemachainAccount::new(
6054 account_minimum_balance() + 50,
6055 Account::get_packed_len(),
6056 &program_id,
6057 );
6058
6059 let owner_key = Pubkey::new_unique();
6060 let mut owner_account = GemachainAccount::default();
6061 let mut rent_sysvar = rent_sysvar();
6062
6063 do_process_instruction(
6065 initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),
6066 vec![&mut mint_account, &mut rent_sysvar],
6067 )
6068 .unwrap();
6069
6070 do_process_instruction(
6072 initialize_account(&program_id, &non_native_account_key, &mint_key, &owner_key)
6073 .unwrap(),
6074 vec![
6075 &mut non_native_account,
6076 &mut mint_account,
6077 &mut owner_account,
6078 &mut rent_sysvar,
6079 ],
6080 )
6081 .unwrap();
6082
6083 let account = Account::unpack_unchecked(&non_native_account.data).unwrap();
6084 assert!(!account.is_native());
6085 assert_eq!(account.amount, 0);
6086
6087 assert_eq!(
6089 Err(TokenError::NonNativeNotSupported.into()),
6090 do_process_instruction(
6091 sync_native(&program_id, &non_native_account_key,).unwrap(),
6092 vec![&mut non_native_account],
6093 )
6094 );
6095
6096 assert_eq!(
6098 Err(ProgramError::UninitializedAccount),
6099 do_process_instruction(
6100 sync_native(&program_id, &native_account_key,).unwrap(),
6101 vec![&mut native_account],
6102 )
6103 );
6104
6105 do_process_instruction(
6107 initialize_account(
6108 &program_id,
6109 &native_account_key,
6110 &crate::native_mint::id(),
6111 &owner_key,
6112 )
6113 .unwrap(),
6114 vec![
6115 &mut native_account,
6116 &mut mint_account,
6117 &mut owner_account,
6118 &mut rent_sysvar,
6119 ],
6120 )
6121 .unwrap();
6122 let account = Account::unpack_unchecked(&native_account.data).unwrap();
6123 assert!(account.is_native());
6124 assert_eq!(account.amount, carats);
6125
6126 do_process_instruction(
6128 sync_native(&program_id, &native_account_key).unwrap(),
6129 vec![&mut native_account],
6130 )
6131 .unwrap();
6132 let account = Account::unpack_unchecked(&native_account.data).unwrap();
6133 assert_eq!(account.amount, carats);
6134
6135 let new_carats = carats + 50;
6137 native_account.carats = account_minimum_balance() + new_carats;
6138
6139 do_process_instruction(
6141 sync_native(&program_id, &native_account_key).unwrap(),
6142 vec![&mut native_account],
6143 )
6144 .unwrap();
6145 let account = Account::unpack_unchecked(&native_account.data).unwrap();
6146 assert_eq!(account.amount, new_carats);
6147
6148 native_account.carats -= 1;
6150
6151 assert_eq!(
6153 Err(TokenError::InvalidState.into()),
6154 do_process_instruction(
6155 sync_native(&program_id, &native_account_key,).unwrap(),
6156 vec![&mut native_account],
6157 )
6158 );
6159 }
6160}