pinocchio_token/instructions/
burn_checked.rs

1use core::slice::from_raw_parts;
2
3use solana_account_view::AccountView;
4use solana_instruction_view::{
5    cpi::{invoke_signed, Signer},
6    InstructionAccount, InstructionView,
7};
8use solana_program_error::ProgramResult;
9
10use crate::{write_bytes, UNINIT_BYTE};
11
12/// Burns tokens by removing them from an account.
13///
14/// ### Accounts:
15///   0. `[WRITE]` The account to burn from.
16///   1. `[WRITE]` The token mint.
17///   2. `[SIGNER]` The account's owner/delegate.
18pub struct BurnChecked<'a> {
19    /// Source of the Burn Account
20    pub account: &'a AccountView,
21    /// Mint Account
22    pub mint: &'a AccountView,
23    /// Owner of the Token Account
24    pub authority: &'a AccountView,
25    /// Amount
26    pub amount: u64,
27    /// Decimals
28    pub decimals: u8,
29}
30
31impl BurnChecked<'_> {
32    #[inline(always)]
33    pub fn invoke(&self) -> ProgramResult {
34        self.invoke_signed(&[])
35    }
36
37    #[inline(always)]
38    pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
39        // Instruction accounts
40        let instruction_accounts: [InstructionAccount; 3] = [
41            InstructionAccount::writable(self.account.address()),
42            InstructionAccount::writable(self.mint.address()),
43            InstructionAccount::readonly_signer(self.authority.address()),
44        ];
45
46        // Instruction data
47        // -  [0]: instruction discriminator (1 byte, u8)
48        // -  [1..9]: amount (8 bytes, u64)
49        // -  [9]: decimals (1 byte, u8)
50        let mut instruction_data = [UNINIT_BYTE; 10];
51
52        // Set discriminator as u8 at offset [0]
53        write_bytes(&mut instruction_data, &[15]);
54        // Set amount as u64 at offset [1..9]
55        write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes());
56        // Set decimals as u8 at offset [9]
57        write_bytes(&mut instruction_data[9..], &[self.decimals]);
58
59        let instruction = InstructionView {
60            program_id: &crate::ID,
61            accounts: &instruction_accounts,
62            data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) },
63        };
64
65        invoke_signed(
66            &instruction,
67            &[self.account, self.mint, self.authority],
68            signers,
69        )
70    }
71}