Reinstate Mint supply (#342)
* Reinstate Mint supply, and adjust with Minto & Burn * C headers * Patch token-cli * Patch token-swap
This commit is contained in:
parent
fec5717d2a
commit
49e6e4a589
|
@ -89,13 +89,20 @@ impl State {
|
|||
token_program_id: &Pubkey,
|
||||
swap: &Pubkey,
|
||||
burn_account: &Pubkey,
|
||||
mint: &Pubkey,
|
||||
authority: &Pubkey,
|
||||
amount: u64,
|
||||
) -> Result<(), ProgramError> {
|
||||
let swap_bytes = swap.to_bytes();
|
||||
let signers = &[&[&swap_bytes[..32]][..]];
|
||||
let ix =
|
||||
spl_token::instruction::burn(token_program_id, burn_account, authority, &[], amount)?;
|
||||
let ix = spl_token::instruction::burn(
|
||||
token_program_id,
|
||||
burn_account,
|
||||
mint,
|
||||
authority,
|
||||
&[],
|
||||
amount,
|
||||
)?;
|
||||
invoke_signed(&ix, accounts, signers)
|
||||
}
|
||||
|
||||
|
@ -414,6 +421,7 @@ impl State {
|
|||
token_program_info.key,
|
||||
swap_info.key,
|
||||
source_info.key,
|
||||
&token_swap.pool_mint,
|
||||
authority_info.key,
|
||||
amount,
|
||||
)?;
|
||||
|
|
|
@ -20,7 +20,7 @@ use spl_token::{
|
|||
self,
|
||||
instruction::*,
|
||||
native_mint,
|
||||
state::{Account, Mint},
|
||||
state::{self, Account, Mint},
|
||||
};
|
||||
use std::{mem::size_of, process::exit};
|
||||
|
||||
|
@ -213,12 +213,20 @@ fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommmandResu
|
|||
.rpc_client
|
||||
.get_token_account_balance_with_commitment(&source, config.commitment_config)?
|
||||
.value;
|
||||
let source_account = config
|
||||
.rpc_client
|
||||
.get_account_with_commitment(&source, config.commitment_config)?
|
||||
.value
|
||||
.unwrap_or_default();
|
||||
let mut data = source_account.data.to_vec();
|
||||
let mint_pubkey = state::unpack::<Account>(&mut data)?.mint;
|
||||
|
||||
let amount = spl_token::ui_amount_to_amount(ui_amount, source_token_balance.decimals);
|
||||
let mut transaction = Transaction::new_with_payer(
|
||||
&[burn(
|
||||
&spl_token::id(),
|
||||
&source,
|
||||
&mint_pubkey,
|
||||
&config.owner.pubkey(),
|
||||
&[],
|
||||
amount,
|
||||
|
|
|
@ -152,8 +152,8 @@ typedef enum Token_TokenInstruction_Tag {
|
|||
* Accounts expected by this instruction:
|
||||
*
|
||||
* 0. `[writable]` The multisignature account to initialize.
|
||||
* 2. `[]` Rent sysvar
|
||||
* 3. ..2+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
|
||||
* 1. `[]` Rent sysvar
|
||||
* 2. ..2+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
|
||||
*/
|
||||
Token_TokenInstruction_InitializeMultisig,
|
||||
/**
|
||||
|
@ -219,7 +219,7 @@ typedef enum Token_TokenInstruction_Tag {
|
|||
* * Multisignature authority
|
||||
* 0. `[writable]` The mint or account to change the authority of.
|
||||
* 1. `[]` The mint's or account's multisignature authority.
|
||||
* 3. ..3+M '[signer]' M signer accounts
|
||||
* 2. ..2+M '[signer]' M signer accounts
|
||||
*/
|
||||
Token_TokenInstruction_SetAuthority,
|
||||
/**
|
||||
|
@ -247,12 +247,14 @@ typedef enum Token_TokenInstruction_Tag {
|
|||
*
|
||||
* * Single owner/delegate
|
||||
* 0. `[writable]` The account to burn from.
|
||||
* 1. `[signer]` The account's owner/delegate.
|
||||
* 1. '[writable]' The token mint.
|
||||
* 2. `[signer]` The account's owner/delegate.
|
||||
*
|
||||
* * Multisignature owner/delegate
|
||||
* 0. `[writable]` The account to burn from.
|
||||
* 1. `[]` The account's multisignature owner/delegate.
|
||||
* 2. ..2+M '[signer]' M signer accounts.
|
||||
* 1. '[writable]' The token mint.
|
||||
* 2. `[]` The account's multisignature owner/delegate.
|
||||
* 3. ..3+M '[signer]' M signer accounts.
|
||||
*/
|
||||
Token_TokenInstruction_Burn,
|
||||
/**
|
||||
|
@ -393,6 +395,10 @@ typedef struct Token_Mint {
|
|||
* further tokens may be minted.
|
||||
*/
|
||||
Token_COption_Pubkey mint_authority;
|
||||
/**
|
||||
* Total supply of tokens.
|
||||
*/
|
||||
uint64_t supply;
|
||||
/**
|
||||
* Number of base 10 digits to the right of the decimal place.
|
||||
*/
|
||||
|
|
|
@ -64,8 +64,8 @@ pub enum TokenInstruction {
|
|||
/// Accounts expected by this instruction:
|
||||
///
|
||||
/// 0. `[writable]` The multisignature account to initialize.
|
||||
/// 2. `[]` Rent sysvar
|
||||
/// 3. ..2+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
|
||||
/// 1. `[]` Rent sysvar
|
||||
/// 2. ..2+N. `[]` The signer accounts, must equal to N where 1 <= N <= 11.
|
||||
InitializeMultisig {
|
||||
/// The number of signers (M) required to validate this multisignature account.
|
||||
m: u8,
|
||||
|
@ -133,7 +133,7 @@ pub enum TokenInstruction {
|
|||
/// * Multisignature authority
|
||||
/// 0. `[writable]` The mint or account to change the authority of.
|
||||
/// 1. `[]` The mint's or account's multisignature authority.
|
||||
/// 3. ..3+M '[signer]' M signer accounts
|
||||
/// 2. ..2+M '[signer]' M signer accounts
|
||||
SetAuthority {
|
||||
/// The type of authority to update.
|
||||
authority_type: AuthorityType,
|
||||
|
@ -165,12 +165,14 @@ pub enum TokenInstruction {
|
|||
///
|
||||
/// * Single owner/delegate
|
||||
/// 0. `[writable]` The account to burn from.
|
||||
/// 1. `[signer]` The account's owner/delegate.
|
||||
/// 1. '[writable]' The token mint.
|
||||
/// 2. `[signer]` The account's owner/delegate.
|
||||
///
|
||||
/// * Multisignature owner/delegate
|
||||
/// 0. `[writable]` The account to burn from.
|
||||
/// 1. `[]` The account's multisignature owner/delegate.
|
||||
/// 2. ..2+M '[signer]' M signer accounts.
|
||||
/// 1. '[writable]' The token mint.
|
||||
/// 2. `[]` The account's multisignature owner/delegate.
|
||||
/// 3. ..3+M '[signer]' M signer accounts.
|
||||
Burn {
|
||||
/// The amount of tokens to burn.
|
||||
amount: u64,
|
||||
|
@ -696,14 +698,16 @@ pub fn mint_to(
|
|||
pub fn burn(
|
||||
token_program_id: &Pubkey,
|
||||
account_pubkey: &Pubkey,
|
||||
mint_pubkey: &Pubkey,
|
||||
authority_pubkey: &Pubkey,
|
||||
signer_pubkeys: &[&Pubkey],
|
||||
amount: u64,
|
||||
) -> Result<Instruction, ProgramError> {
|
||||
let data = TokenInstruction::Burn { amount }.pack()?;
|
||||
|
||||
let mut accounts = Vec::with_capacity(2 + signer_pubkeys.len());
|
||||
let mut accounts = Vec::with_capacity(3 + signer_pubkeys.len());
|
||||
accounts.push(AccountMeta::new(*account_pubkey, false));
|
||||
accounts.push(AccountMeta::new(*mint_pubkey, false));
|
||||
accounts.push(AccountMeta::new_readonly(
|
||||
*authority_pubkey,
|
||||
signer_pubkeys.is_empty(),
|
||||
|
|
|
@ -387,6 +387,11 @@ impl Processor {
|
|||
.checked_add(amount)
|
||||
.ok_or(TokenError::Overflow)?;
|
||||
|
||||
mint.supply = mint
|
||||
.supply
|
||||
.checked_add(amount)
|
||||
.ok_or(TokenError::Overflow)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -398,14 +403,21 @@ impl Processor {
|
|||
) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
let source_account_info = next_account_info(account_info_iter)?;
|
||||
let mint_info = next_account_info(account_info_iter)?;
|
||||
let authority_info = next_account_info(account_info_iter)?;
|
||||
|
||||
let mut mint_data = mint_info.data.borrow_mut();
|
||||
let mint: &mut Mint = state::unpack(&mut mint_data)?;
|
||||
|
||||
let mut source_data = source_account_info.data.borrow_mut();
|
||||
let source_account: &mut Account = state::unpack(&mut source_data)?;
|
||||
|
||||
if source_account.is_native() {
|
||||
return Err(TokenError::NativeNotSupported.into());
|
||||
}
|
||||
if mint_info.key != &source_account.mint {
|
||||
return Err(TokenError::MintMismatch.into());
|
||||
}
|
||||
if source_account.amount < amount {
|
||||
return Err(TokenError::InsufficientFunds.into());
|
||||
}
|
||||
|
@ -439,6 +451,7 @@ impl Processor {
|
|||
}
|
||||
|
||||
source_account.amount -= amount;
|
||||
mint.supply -= amount;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1268,6 +1281,7 @@ mod tests {
|
|||
*mint,
|
||||
Mint {
|
||||
mint_authority: COption::Some(owner_key),
|
||||
supply: 0,
|
||||
decimals,
|
||||
is_initialized: true,
|
||||
freeze_authority: COption::None,
|
||||
|
@ -1832,13 +1846,26 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
// mint to
|
||||
do_process_instruction(
|
||||
mint_to(&program_id, &mint_key, &account_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut mint_account, &mut account_account, &mut owner_account],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
|
||||
assert_eq!(mint.supply, 42);
|
||||
let dest_account: &mut Account = state::unpack(&mut account_account.data).unwrap();
|
||||
assert_eq!(dest_account.amount, 42);
|
||||
|
||||
// mint to another account to test supply accumulation
|
||||
do_process_instruction(
|
||||
mint_to(&program_id, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut mint_account, &mut account2_account, &mut owner_account],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let _: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
|
||||
let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
|
||||
assert_eq!(mint.supply, 84);
|
||||
let dest_account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
|
||||
assert_eq!(dest_account.amount, 42);
|
||||
|
||||
|
@ -2010,13 +2037,18 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
// missing signer
|
||||
let mut instruction = burn(&program_id, &account_key, &delegate_key, &[], 42).unwrap();
|
||||
let mut instruction =
|
||||
burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 42).unwrap();
|
||||
instruction.accounts[1].is_signer = false;
|
||||
assert_eq!(
|
||||
Err(TokenError::OwnerMismatch.into()),
|
||||
do_process_instruction(
|
||||
instruction,
|
||||
vec![&mut account_account, &mut delegate_account],
|
||||
vec![
|
||||
&mut account_account,
|
||||
&mut mint_account,
|
||||
&mut delegate_account
|
||||
],
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -2024,19 +2056,29 @@ mod tests {
|
|||
assert_eq!(
|
||||
Err(TokenError::OwnerMismatch.into()),
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &owner2_key, &[], 42).unwrap(),
|
||||
vec![&mut account_account, &mut owner2_account],
|
||||
burn(&program_id, &account_key, &mint_key, &owner2_key, &[], 42).unwrap(),
|
||||
vec![&mut account_account, &mut mint_account, &mut owner2_account],
|
||||
)
|
||||
);
|
||||
|
||||
// mint mismatch
|
||||
assert_eq!(
|
||||
Err(TokenError::MintMismatch.into()),
|
||||
do_process_instruction(
|
||||
burn(&program_id, &mismatch_key, &mint_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut mismatch_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
);
|
||||
|
||||
// burn
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut account_account, &mut owner_account],
|
||||
burn(&program_id, &account_key, &mint_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut account_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let _: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
|
||||
let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
|
||||
assert_eq!(mint.supply, 1000 - 42);
|
||||
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
|
||||
assert_eq!(account.amount, 1000 - 42);
|
||||
|
||||
|
@ -2044,8 +2086,16 @@ mod tests {
|
|||
assert_eq!(
|
||||
Err(TokenError::InsufficientFunds.into()),
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &owner_key, &[], 100_000_000).unwrap(),
|
||||
vec![&mut account_account, &mut owner_account],
|
||||
burn(
|
||||
&program_id,
|
||||
&account_key,
|
||||
&mint_key,
|
||||
&owner_key,
|
||||
&[],
|
||||
100_000_000
|
||||
)
|
||||
.unwrap(),
|
||||
vec![&mut account_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -2072,20 +2122,33 @@ mod tests {
|
|||
assert_eq!(
|
||||
Err(TokenError::InsufficientFunds.into()),
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &owner_key, &[], 100_000_000).unwrap(),
|
||||
vec![&mut account_account, &mut owner_account],
|
||||
burn(
|
||||
&program_id,
|
||||
&account_key,
|
||||
&mint_key,
|
||||
&owner_key,
|
||||
&[],
|
||||
100_000_000
|
||||
)
|
||||
.unwrap(),
|
||||
vec![&mut account_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
);
|
||||
|
||||
// burn via delegate
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &delegate_key, &[], 84).unwrap(),
|
||||
vec![&mut account_account, &mut delegate_account],
|
||||
burn(&program_id, &account_key, &mint_key, &delegate_key, &[], 84).unwrap(),
|
||||
vec![
|
||||
&mut account_account,
|
||||
&mut mint_account,
|
||||
&mut delegate_account,
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// match
|
||||
let _: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
|
||||
let mint: &mut Mint = state::unpack(&mut mint_account.data).unwrap();
|
||||
assert_eq!(mint.supply, 1000 - 42 - 84);
|
||||
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
|
||||
assert_eq!(account.amount, 1000 - 42 - 84);
|
||||
|
||||
|
@ -2093,8 +2156,20 @@ mod tests {
|
|||
assert_eq!(
|
||||
Err(TokenError::OwnerMismatch.into()),
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &delegate_key, &[], 100).unwrap(),
|
||||
vec![&mut account_account, &mut delegate_account],
|
||||
burn(
|
||||
&program_id,
|
||||
&account_key,
|
||||
&mint_key,
|
||||
&delegate_key,
|
||||
&[],
|
||||
100
|
||||
)
|
||||
.unwrap(),
|
||||
vec![
|
||||
&mut account_account,
|
||||
&mut mint_account,
|
||||
&mut delegate_account
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -2338,6 +2413,7 @@ mod tests {
|
|||
burn(
|
||||
&program_id,
|
||||
&account_key,
|
||||
&mint_key,
|
||||
&multisig_key,
|
||||
&[&signer_keys[0]],
|
||||
42,
|
||||
|
@ -2345,6 +2421,7 @@ mod tests {
|
|||
.unwrap(),
|
||||
vec![
|
||||
&mut account,
|
||||
&mut mint_account,
|
||||
&mut multisig_account,
|
||||
&mut account_info_iter.next().unwrap(),
|
||||
],
|
||||
|
@ -2357,6 +2434,7 @@ mod tests {
|
|||
burn(
|
||||
&program_id,
|
||||
&account_key,
|
||||
&mint_key,
|
||||
&multisig_delegate_key,
|
||||
&signer_key_refs,
|
||||
42,
|
||||
|
@ -2364,6 +2442,7 @@ mod tests {
|
|||
.unwrap(),
|
||||
vec![
|
||||
&mut account,
|
||||
&mut mint_account,
|
||||
&mut multisig_delegate_account,
|
||||
&mut account_info_iter.next().unwrap(),
|
||||
&mut account_info_iter.next().unwrap(),
|
||||
|
@ -2715,8 +2794,8 @@ mod tests {
|
|||
|
||||
// empty account
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut account_account, &mut owner_account],
|
||||
burn(&program_id, &account_key, &mint_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut account_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2908,11 +2987,32 @@ mod tests {
|
|||
);
|
||||
|
||||
// burn unsupported
|
||||
let bogus_mint_key = pubkey_rand();
|
||||
let mut bogus_mint_account =
|
||||
SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
|
||||
do_process_instruction(
|
||||
initialize_mint(&program_id, &bogus_mint_key, &owner_key, None, 2).unwrap(),
|
||||
vec![&mut bogus_mint_account, &mut rent_sysvar],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
Err(TokenError::NativeNotSupported.into()),
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &owner_key, &[], 42).unwrap(),
|
||||
vec![&mut account_account, &mut owner_account],
|
||||
burn(
|
||||
&program_id,
|
||||
&account_key,
|
||||
&bogus_mint_key,
|
||||
&owner_key,
|
||||
&[],
|
||||
42
|
||||
)
|
||||
.unwrap(),
|
||||
vec![
|
||||
&mut account_account,
|
||||
&mut bogus_mint_account,
|
||||
&mut owner_account
|
||||
],
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -3002,7 +3102,7 @@ mod tests {
|
|||
SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
|
||||
let mut rent_sysvar = rent_sysvar();
|
||||
|
||||
// create victim account
|
||||
// create an account
|
||||
do_process_instruction(
|
||||
initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(),
|
||||
vec![
|
||||
|
@ -3033,28 +3133,7 @@ mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
// mint the max to attacker
|
||||
do_process_instruction(
|
||||
mint_to(
|
||||
&program_id,
|
||||
&mint_key,
|
||||
&account2_key,
|
||||
&mint_owner_key,
|
||||
&[],
|
||||
42,
|
||||
)
|
||||
.unwrap(),
|
||||
vec![
|
||||
&mut mint_account,
|
||||
&mut account2_account,
|
||||
&mut mint_owner_account,
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
let account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
|
||||
assert_eq!(account.amount, 42);
|
||||
|
||||
// mint the max to victum
|
||||
// mint the max to an account
|
||||
do_process_instruction(
|
||||
mint_to(
|
||||
&program_id,
|
||||
|
@ -3075,7 +3154,7 @@ mod tests {
|
|||
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
|
||||
assert_eq!(account.amount, u64::MAX);
|
||||
|
||||
// mint one more
|
||||
// attempt to mint one more to account
|
||||
assert_eq!(
|
||||
Err(TokenError::Overflow.into()),
|
||||
do_process_instruction(
|
||||
|
@ -3095,10 +3174,39 @@ mod tests {
|
|||
],
|
||||
)
|
||||
);
|
||||
|
||||
// mint back to large amount
|
||||
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
|
||||
account.amount = 0;
|
||||
assert_eq!(account.amount, u64::MAX);
|
||||
|
||||
// atttempt to mint one more to the other account
|
||||
assert_eq!(
|
||||
Err(TokenError::Overflow.into()),
|
||||
do_process_instruction(
|
||||
mint_to(
|
||||
&program_id,
|
||||
&mint_key,
|
||||
&account2_key,
|
||||
&mint_owner_key,
|
||||
&[],
|
||||
1,
|
||||
)
|
||||
.unwrap(),
|
||||
vec![
|
||||
&mut mint_account,
|
||||
&mut account2_account,
|
||||
&mut mint_owner_account,
|
||||
],
|
||||
)
|
||||
);
|
||||
|
||||
// burn some of the supply
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
|
||||
vec![&mut account_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
.unwrap();
|
||||
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
|
||||
assert_eq!(account.amount, u64::MAX - 100);
|
||||
|
||||
do_process_instruction(
|
||||
mint_to(
|
||||
&program_id,
|
||||
|
@ -3106,7 +3214,7 @@ mod tests {
|
|||
&account_key,
|
||||
&mint_owner_key,
|
||||
&[],
|
||||
u64::MAX,
|
||||
100,
|
||||
)
|
||||
.unwrap(),
|
||||
vec![
|
||||
|
@ -3119,7 +3227,10 @@ mod tests {
|
|||
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
|
||||
assert_eq!(account.amount, u64::MAX);
|
||||
|
||||
// transfer to burn victim
|
||||
// manipulate account balance to attempt overflow transfer
|
||||
let account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
|
||||
account.amount = 1;
|
||||
|
||||
assert_eq!(
|
||||
Err(TokenError::Overflow.into()),
|
||||
do_process_instruction(
|
||||
|
@ -3308,8 +3419,8 @@ mod tests {
|
|||
assert_eq!(
|
||||
Err(TokenError::AccountFrozen.into()),
|
||||
do_process_instruction(
|
||||
burn(&program_id, &account_key, &owner_key, &[], 100).unwrap(),
|
||||
vec![&mut account_account, &mut owner_account,],
|
||||
burn(&program_id, &account_key, &mint_key, &owner_key, &[], 100).unwrap(),
|
||||
vec![&mut account_account, &mut mint_account, &mut owner_account],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ pub struct Mint {
|
|||
/// mint creation. If no mint authority is present then the mint has a fixed supply and no
|
||||
/// further tokens may be minted.
|
||||
pub mint_authority: COption<Pubkey>,
|
||||
/// Total supply of tokens.
|
||||
pub supply: u64,
|
||||
/// Number of base 10 digits to the right of the decimal place.
|
||||
pub decimals: u8,
|
||||
/// Is `true` if this structure has been initialized
|
||||
|
|
Loading…
Reference in New Issue