1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use anchor_lang::prelude::*;

use crate::{
    config,
    errors::ErrorCode,
    event_merkle_tree::EventMerkleTree,
    transaction_merkle_tree::state::TransactionMerkleTree,
    utils::constants::{
        EVENT_MERKLE_TREE_SEED, MERKLE_TREE_AUTHORITY_SEED, TRANSACTION_MERKLE_TREE_SEED,
    },
};

/// Configures the authority of the merkle tree which can:
/// - register new verifiers
/// - register new asset pools
/// - register new asset pool types
/// - set permissions for new asset pool creation
/// - keeps current highest index for assets and merkle trees to enable lookups of these
#[account]
pub struct MerkleTreeAuthority {
    pub pubkey: Pubkey,
    pub transaction_merkle_tree_index: u64,
    pub event_merkle_tree_index: u64,
    pub registered_asset_index: u64,
    pub enable_permissionless_spl_tokens: bool,
    pub enable_permissionless_merkle_tree_registration: bool,
}

#[derive(Accounts)]
pub struct InitializeMerkleTreeAuthority<'info> {
    #[account(
        init,
        payer = authority,
        seeds = [MERKLE_TREE_AUTHORITY_SEED],
        bump,
        space = 8 + 32 + 8 + 8 + 8 + 8
    )]
    pub merkle_tree_authority_pda: Account<'info, MerkleTreeAuthority>,
    #[account(
        init,
        seeds = [
            TRANSACTION_MERKLE_TREE_SEED,
            0u64.to_le_bytes().as_ref(),
        ],
        bump,
        payer = authority,
        space = 8880
    )]
    pub transaction_merkle_tree: AccountLoader<'info, TransactionMerkleTree>,
    #[account(
        init,
        seeds = [
            EVENT_MERKLE_TREE_SEED,
            0u64.to_le_bytes().as_ref(),
        ],
        bump,
        payer=authority,
        // discriminator + height (u64) + filled subtrees ([[u8; 32]; 18]) +
        // roots ([[u8; 32]; 20]) + next_index (u64) + current_root_index (u64)
        // + hash_function (enum) + merkle_tree_nr (u64) + newest (u8) +
        // padding (7 * u8)
        // 8 + 8 + 18 * 32 + 20 * 32 + 8 + 8 + 8 + 8 + 8 + 1 + 7 = 1280
        space = 1280,
    )]
    pub event_merkle_tree: AccountLoader<'info, EventMerkleTree>,
    /// CHECK:` Signer is merkle tree init authority.
    #[account(mut, address=anchor_lang::prelude::Pubkey::try_from(config::INITIAL_MERKLE_TREE_AUTHORITY).map_err(|_| ErrorCode::PubkeyTryFromFailed)? @ErrorCode::InvalidAuthority)]
    pub authority: Signer<'info>,
    pub system_program: Program<'info, System>,
    pub rent: Sysvar<'info, Rent>,
}

#[derive(Accounts)]
pub struct UpdateMerkleTreeAuthority<'info> {
    #[account(mut, seeds = [MERKLE_TREE_AUTHORITY_SEED], bump)]
    pub merkle_tree_authority_pda: Account<'info, MerkleTreeAuthority>,
    /// CHECK:` Signer is merkle tree authority.
    #[account(address=merkle_tree_authority_pda.pubkey @ErrorCode::InvalidAuthority)]
    pub authority: Signer<'info>,
    /// CHECK:` New authority no need to be checked
    pub new_authority: UncheckedAccount<'info>,
}

#[derive(Accounts)]
pub struct UpdateMerkleTreeAuthorityConfig<'info> {
    #[account(mut, seeds = [MERKLE_TREE_AUTHORITY_SEED], bump)]
    pub merkle_tree_authority_pda: Account<'info, MerkleTreeAuthority>,
    /// CHECK:` Signer is merkle tree authority.
    #[account( address=merkle_tree_authority_pda.pubkey @ErrorCode::InvalidAuthority)]
    pub authority: Signer<'info>,
}

#[derive(Accounts)]
pub struct UpdateLockDuration<'info> {
    #[account(mut, seeds = [MERKLE_TREE_AUTHORITY_SEED], bump)]
    pub merkle_tree_authority_pda: Account<'info, MerkleTreeAuthority>,
    /// CHECK:` Signer is merkle tree authority.
    #[account( address=merkle_tree_authority_pda.pubkey @ErrorCode::InvalidAuthority)]
    pub authority: Signer<'info>,
    #[account(mut)]
    pub transaction_merkle_tree: AccountLoader<'info, TransactionMerkleTree>,
}