Browse Source

backport #436 to v2

Jack May 5 years ago
parent
commit
7b54f8639c
1 changed files with 103 additions and 6 deletions
  1. 103 6
      program/src/processor.rs

+ 103 - 6
program/src/processor.rs

@@ -421,8 +421,7 @@ impl Processor {
         let dest_account_info = next_account_info(account_info_iter)?;
         let owner_info = next_account_info(account_info_iter)?;
 
-        let mut dest_account_data = dest_account_info.data.borrow_mut();
-        Account::unpack_mut(&mut dest_account_data, &mut |dest_account: &mut Account| {
+        let mut dest_account = Account::unpack(&dest_account_info.data.borrow())?;
             if dest_account.is_frozen() {
                 return Err(TokenError::AccountFrozen.into());
             }
@@ -434,8 +433,7 @@ impl Processor {
                 return Err(TokenError::MintMismatch.into());
             }
 
-            let mut mint_data = mint_info.data.borrow_mut();
-            Mint::unpack_mut(&mut mint_data, &mut |mint: &mut Mint| {
+        let mut mint = Mint::unpack(&mint_info.data.borrow())?;
                 if let Some(expected_decimals) = expected_decimals {
                     if expected_decimals != mint.decimals {
                         return Err(TokenError::MintDecimalsMismatch.into());
@@ -462,9 +460,10 @@ impl Processor {
                     .checked_add(amount)
                     .ok_or(TokenError::Overflow)?;
 
+        Account::pack(dest_account, &mut dest_account_info.data.borrow_mut())?;
+        Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
+
                 Ok(())
-            })
-        })
     }
 
     /// Processes a [Burn](enum.TokenInstruction.html) instruction.
@@ -2524,6 +2523,104 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_mint_to_dups() {
+        let program_id = pubkey_rand();
+        let account1_key = pubkey_rand();
+        let mut account1_account = SolanaAccount::new(
+            account_minimum_balance(),
+            Account::get_packed_len(),
+            &program_id,
+        );
+        let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into();
+        let owner_key = pubkey_rand();
+        let mut owner_account = SolanaAccount::default();
+        let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into();
+        let mint_key = pubkey_rand();
+        let mut mint_account =
+            SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id);
+        let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into();
+        let rent_key = rent::id();
+        let mut rent_sysvar = rent_sysvar();
+        let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into();
+
+        // create mint
+        do_process_instruction_dups(
+            initialize_mint(&program_id, &mint_key, &mint_key, None, 2).unwrap(),
+            vec![mint_info.clone(), rent_info.clone()],
+        )
+        .unwrap();
+
+        // create account
+        do_process_instruction_dups(
+            initialize_account(&program_id, &account1_key, &mint_key, &owner_key).unwrap(),
+            vec![
+                account1_info.clone(),
+                mint_info.clone(),
+                owner_info.clone(),
+                rent_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // mint_to when mint_authority is self
+        do_process_instruction_dups(
+            mint_to(&program_id, &mint_key, &account1_key, &mint_key, &[], 42).unwrap(),
+            vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
+        )
+        .unwrap();
+
+        // mint_to2 when mint_authority is self
+        do_process_instruction_dups(
+            mint_to2(&program_id, &mint_key, &account1_key, &mint_key, &[], 42, 2).unwrap(),
+            vec![mint_info.clone(), account1_info.clone(), mint_info.clone()],
+        )
+        .unwrap();
+
+        // mint_to when mint_authority is account owner
+        Mint::unpack_unchecked_mut(&mut mint_info.data.borrow_mut(), &mut |mint: &mut Mint| {
+            mint.mint_authority = COption::Some(account1_key);
+            Ok(())
+        })
+        .unwrap();
+        do_process_instruction_dups(
+            mint_to(
+                &program_id,
+                &mint_key,
+                &account1_key,
+                &account1_key,
+                &[],
+                42,
+            )
+            .unwrap(),
+            vec![
+                mint_info.clone(),
+                account1_info.clone(),
+                account1_info.clone(),
+            ],
+        )
+        .unwrap();
+
+        // mint_to2 when mint_authority is account owner
+        do_process_instruction_dups(
+            mint_to(
+                &program_id,
+                &mint_key,
+                &account1_key,
+                &account1_key,
+                &[],
+                42,
+            )
+            .unwrap(),
+            vec![
+                mint_info.clone(),
+                account1_info.clone(),
+                account1_info.clone(),
+            ],
+        )
+        .unwrap();
+    }
+
     #[test]
     fn test_mint_to() {
         let program_id = pubkey_rand();