-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathinitialize.rs
146 lines (128 loc) · 4.64 KB
/
initialize.rs
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use anchor_lang::prelude::*;
use anchor_spl::{associated_token::AssociatedToken, token_interface};
use ntt_messages::{chain_id::ChainId, mode::Mode};
use wormhole_solana_utils::cpi::bpf_loader_upgradeable::BpfLoaderUpgradeable;
#[cfg(feature = "idl-build")]
use crate::messages::Hack;
use crate::{
bitmap::Bitmap,
config::Config,
error::NTTError,
queue::{outbox::OutboxRateLimit, rate_limit::RateLimitState},
spl_multisig::SplMultisig,
};
#[derive(Accounts)]
#[instruction(args: InitializeArgs)]
pub struct Initialize<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(address = program_data.upgrade_authority_address.unwrap_or_default())]
pub deployer: Signer<'info>,
#[account(
seeds = [crate::ID.as_ref()],
bump,
seeds::program = bpf_loader_upgradeable_program,
)]
program_data: Account<'info, ProgramData>,
#[account(
init,
space = 8 + Config::INIT_SPACE,
payer = payer,
seeds = [Config::SEED_PREFIX],
bump
)]
pub config: Box<Account<'info, Config>>,
#[account(
constraint = args.mode == Mode::Locking
|| mint.mint_authority.unwrap() == multisig_token_authority.as_ref().map_or(
token_authority.key(),
|multisig_token_authority| multisig_token_authority.key()
) @ NTTError::InvalidMintAuthority
)]
pub mint: Box<InterfaceAccount<'info, token_interface::Mint>>,
#[account(
init,
payer = payer,
space = 8 + OutboxRateLimit::INIT_SPACE,
seeds = [OutboxRateLimit::SEED_PREFIX],
bump,
)]
pub rate_limit: Account<'info, OutboxRateLimit>,
#[account(
seeds = [crate::TOKEN_AUTHORITY_SEED],
bump,
)]
/// CHECK: [`token_authority`] is checked against the custody account and the [`mint`]'s mint_authority
/// In any case, this function is used to set the Config and initialize the program so we
/// assume the caller of this function will have total control over the program.
///
/// TODO: Using `UncheckedAccount` here leads to "Access violation in stack frame ...".
/// Could refactor code to use `Box<_>` to reduce stack size.
pub token_authority: AccountInfo<'info>,
#[account(
constraint = multisig_token_authority.m == 1
&& multisig_token_authority.signers.contains(&token_authority.key())
@ NTTError::InvalidMultisig,
)]
pub multisig_token_authority: Option<Box<InterfaceAccount<'info, SplMultisig>>>,
#[account(
init_if_needed,
payer = payer,
associated_token::mint = mint,
associated_token::authority = token_authority,
associated_token::token_program = token_program,
)]
/// The custody account that holds tokens in locking mode and temporarily
/// holds tokens in burning mode.
/// CHECK: Use init_if_needed here to prevent a denial-of-service of the [`initialize`]
/// function if the token account has already been created.
pub custody: InterfaceAccount<'info, token_interface::TokenAccount>,
/// CHECK: checked to be the appropriate token program when initialising the
/// associated token account for the given mint.
pub token_program: Interface<'info, token_interface::TokenInterface>,
pub associated_token_program: Program<'info, AssociatedToken>,
bpf_loader_upgradeable_program: Program<'info, BpfLoaderUpgradeable>,
system_program: Program<'info, System>,
}
#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct InitializeArgs {
pub chain_id: u16,
pub limit: u64,
pub mode: ntt_messages::mode::Mode,
}
pub fn initialize(ctx: Context<Initialize>, args: InitializeArgs) -> Result<()> {
initialize_config_and_rate_limit(
ctx.accounts,
ctx.bumps.config,
args.chain_id,
args.limit,
args.mode,
)
}
fn initialize_config_and_rate_limit(
common: &mut Initialize<'_>,
config_bump: u8,
chain_id: u16,
limit: u64,
mode: ntt_messages::mode::Mode,
) -> Result<()> {
common.config.set_inner(crate::config::Config {
bump: config_bump,
mint: common.mint.key(),
token_program: common.token_program.key(),
mode,
chain_id: ChainId { id: chain_id },
owner: common.deployer.key(),
pending_owner: None,
paused: false,
next_transceiver_id: 0,
// NOTE: can be changed via `set_threshold` ix
threshold: 1,
enabled_transceivers: Bitmap::new(),
custody: common.custody.key(),
});
common.rate_limit.set_inner(OutboxRateLimit {
rate_limit: RateLimitState::new(limit),
});
Ok(())
}