Skip to content

Commit 697aa06

Browse files
committed
solana: Refactor out constraint from struct and function
1 parent 15f5a4f commit 697aa06

File tree

3 files changed

+48
-84
lines changed

3 files changed

+48
-84
lines changed

solana/programs/example-native-token-transfers/src/instructions/initialize.rs

+8-15
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use crate::{
1313
};
1414

1515
#[derive(Accounts)]
16-
#[instruction(args: InitializeArgs)]
1716
pub struct Initialize<'info> {
1817
#[account(mut)]
1918
pub payer: Signer<'info>,
@@ -90,22 +89,16 @@ pub struct InitializeArgs {
9089
pub mode: ntt_messages::mode::Mode,
9190
}
9291

93-
#[derive(Accounts)]
94-
#[instruction(args: InitializeArgs)]
95-
pub struct InitializeDefault<'info> {
96-
#[account(
97-
constraint =
98-
args.mode == Mode::Locking
99-
|| common.mint.mint_authority.unwrap() == common.token_authority.key()
100-
@ NTTError::InvalidMintAuthority,
101-
)]
102-
pub common: Initialize<'info>,
103-
}
92+
pub fn initialize(ctx: Context<Initialize>, args: InitializeArgs) -> Result<()> {
93+
if !(args.mode == Mode::Locking
94+
|| ctx.accounts.mint.mint_authority.unwrap() == ctx.accounts.token_authority.key())
95+
{
96+
return Err(NTTError::InvalidMintAuthority.into());
97+
}
10498

105-
pub fn initialize(ctx: Context<InitializeDefault>, args: InitializeArgs) -> Result<()> {
10699
initialize_config_and_rate_limit(
107-
&mut ctx.accounts.common,
108-
ctx.bumps.common.config,
100+
ctx.accounts,
101+
ctx.bumps.config,
109102
args.chain_id,
110103
args.limit,
111104
args.mode,

solana/programs/example-native-token-transfers/src/instructions/release_inbound.rs

+38-67
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::ops::{Deref, DerefMut};
2-
31
use anchor_lang::prelude::*;
42
use anchor_spl::token_interface;
53
use ntt_messages::mode::Mode;
@@ -68,34 +66,6 @@ pub struct ReleaseInboundMint<'info> {
6866
common: ReleaseInbound<'info>,
6967
}
7068

71-
impl<'info> Deref for ReleaseInboundMint<'info> {
72-
type Target = ReleaseInbound<'info>;
73-
74-
fn deref(&self) -> &Self::Target {
75-
&self.common
76-
}
77-
}
78-
79-
impl Deref for ReleaseInboundMintBumps {
80-
type Target = ReleaseInboundBumps;
81-
82-
fn deref(&self) -> &Self::Target {
83-
&self.common
84-
}
85-
}
86-
87-
impl<'info> DerefMut for ReleaseInboundMint<'info> {
88-
fn deref_mut(&mut self) -> &mut Self::Target {
89-
&mut self.common
90-
}
91-
}
92-
93-
#[derive(Accounts)]
94-
pub struct ReleaseInboundMintDefault<'info> {
95-
#[account(constraint = common.mint.mint_authority.unwrap() == common.token_authority.key())]
96-
common: ReleaseInboundMint<'info>,
97-
}
98-
9969
/// Release an inbound transfer and mint the tokens to the recipient.
10070
/// When `revert_on_error` is true, the transaction will revert if the
10171
/// release timestamp has not been reached. When `revert_on_error` is false, the
@@ -104,9 +74,16 @@ pub struct ReleaseInboundMintDefault<'info> {
10474
/// together with [`crate::instructions::redeem`] in a transaction, so that the minting
10575
/// is attempted optimistically.
10676
pub fn release_inbound_mint<'info>(
107-
ctx: Context<'_, '_, '_, 'info, ReleaseInboundMintDefault<'info>>,
77+
ctx: Context<'_, '_, '_, 'info, ReleaseInboundMint<'info>>,
10878
args: ReleaseInboundArgs,
10979
) -> Result<()> {
80+
if ctx.accounts.common.mint.mint_authority.unwrap() != ctx.accounts.common.token_authority.key()
81+
{
82+
return Err(NTTError::InvalidMintAuthority.into());
83+
}
84+
85+
let inbox_item = release_inbox_item(&mut ctx.accounts.common.inbox_item, args.revert_on_delay)?;
86+
11087
// NOTE: minting tokens is a two-step process:
11188
// 1. Mint tokens to the custody account
11289
// 2. Transfer the tokens from the custody account to the recipient
@@ -136,7 +113,7 @@ pub fn release_inbound_mint<'info>(
136113
&[ctx.bumps.common.token_authority],
137114
]],
138115
),
139-
ctx.accounts.common.inbox_item.amount,
116+
inbox_item.amount,
140117
)?;
141118

142119
// Step 2: transfer the tokens from the custody account to the recipient
@@ -147,21 +124,23 @@ pub fn release_inbound_mint<'info>(
147124
ctx.accounts.common.recipient.to_account_info(),
148125
ctx.accounts.common.token_authority.to_account_info(),
149126
ctx.remaining_accounts,
150-
ctx.accounts.common.inbox_item.amount,
127+
inbox_item.amount,
151128
ctx.accounts.common.mint.decimals,
152129
&[&[
153130
crate::TOKEN_AUTHORITY_SEED,
154131
&[ctx.bumps.common.token_authority],
155132
]],
156133
)?;
157-
158-
release_inbox_item(&mut ctx.accounts.common.inbox_item, args.revert_on_delay)
134+
Ok(())
159135
}
160136

161137
#[derive(Accounts)]
162138
pub struct ReleaseInboundMintMultisig<'info> {
163-
#[account(constraint = common.mint.mint_authority.unwrap() == multisig.key())]
164-
common: ReleaseInboundMint<'info>,
139+
#[account(
140+
constraint = common.config.mode == Mode::Burning @ NTTError::InvalidMode,
141+
constraint = common.mint.mint_authority.unwrap() == multisig.key()
142+
)]
143+
common: ReleaseInbound<'info>,
165144

166145
/// CHECK: multisig account should be mint authority
167146
pub multisig: UncheckedAccount<'info>,
@@ -171,6 +150,8 @@ pub fn release_inbound_mint_multisig<'info>(
171150
ctx: Context<'_, '_, '_, 'info, ReleaseInboundMintMultisig<'info>>,
172151
args: ReleaseInboundArgs,
173152
) -> Result<()> {
153+
let inbox_item = release_inbox_item(&mut ctx.accounts.common.inbox_item, args.revert_on_delay)?;
154+
174155
// NOTE: minting tokens is a two-step process:
175156
// 1. Mint tokens to the custody account
176157
// 2. Transfer the tokens from the custody account to the recipient
@@ -193,7 +174,7 @@ pub fn release_inbound_mint_multisig<'info>(
193174
&ctx.accounts.common.custody.key(),
194175
&ctx.accounts.multisig.key(),
195176
&[&ctx.accounts.common.token_authority.key()],
196-
ctx.accounts.common.inbox_item.amount,
177+
inbox_item.amount,
197178
)?;
198179
solana_program::program::invoke_signed(
199180
&ix,
@@ -217,30 +198,13 @@ pub fn release_inbound_mint_multisig<'info>(
217198
ctx.accounts.common.recipient.to_account_info(),
218199
ctx.accounts.common.token_authority.to_account_info(),
219200
ctx.remaining_accounts,
220-
ctx.accounts.common.inbox_item.amount,
201+
inbox_item.amount,
221202
ctx.accounts.common.mint.decimals,
222203
&[&[
223204
crate::TOKEN_AUTHORITY_SEED,
224205
&[ctx.bumps.common.token_authority],
225206
]],
226207
)?;
227-
228-
release_inbox_item(&mut ctx.accounts.common.inbox_item, args.revert_on_delay)
229-
}
230-
231-
fn release_inbox_item(inbox_item: &mut InboxItem, revert_on_delay: bool) -> Result<()> {
232-
let released = inbox_item.try_release()?;
233-
234-
if !released {
235-
if revert_on_delay {
236-
return Err(NTTError::CantReleaseYet.into());
237-
} else {
238-
return Ok(());
239-
}
240-
}
241-
242-
assert!(inbox_item.release_status == ReleaseStatus::Released);
243-
244208
Ok(())
245209
}
246210

@@ -250,6 +214,7 @@ fn release_inbox_item(inbox_item: &mut InboxItem, revert_on_delay: bool) -> Resu
250214
pub struct ReleaseInboundUnlock<'info> {
251215
#[account(
252216
constraint = common.config.mode == Mode::Locking @ NTTError::InvalidMode,
217+
constraint = common.mint.mint_authority.unwrap() == common.token_authority.key()
253218
)]
254219
common: ReleaseInbound<'info>,
255220
}
@@ -265,17 +230,7 @@ pub fn release_inbound_unlock<'info>(
265230
ctx: Context<'_, '_, '_, 'info, ReleaseInboundUnlock<'info>>,
266231
args: ReleaseInboundArgs,
267232
) -> Result<()> {
268-
let inbox_item = &mut ctx.accounts.common.inbox_item;
269-
270-
let released = inbox_item.try_release()?;
271-
272-
if !released {
273-
if args.revert_on_delay {
274-
return Err(NTTError::CantReleaseYet.into());
275-
} else {
276-
return Ok(());
277-
}
278-
}
233+
let inbox_item = release_inbox_item(&mut ctx.accounts.common.inbox_item, args.revert_on_delay)?;
279234

280235
onchain::invoke_transfer_checked(
281236
&ctx.accounts.common.token_program.key(),
@@ -293,3 +248,19 @@ pub fn release_inbound_unlock<'info>(
293248
)?;
294249
Ok(())
295250
}
251+
252+
fn release_inbox_item(inbox_item: &mut InboxItem, revert_on_delay: bool) -> Result<&mut InboxItem> {
253+
let released = inbox_item.try_release()?;
254+
255+
if !released {
256+
if revert_on_delay {
257+
return Err(NTTError::CantReleaseYet.into());
258+
} else {
259+
return Ok(inbox_item);
260+
}
261+
}
262+
263+
assert!(inbox_item.release_status == ReleaseStatus::Released);
264+
265+
Ok(inbox_item)
266+
}

solana/programs/example-native-token-transfers/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub mod example_native_token_transfers {
7070

7171
use super::*;
7272

73-
pub fn initialize(ctx: Context<InitializeDefault>, args: InitializeArgs) -> Result<()> {
73+
pub fn initialize(ctx: Context<Initialize>, args: InitializeArgs) -> Result<()> {
7474
instructions::initialize(ctx, args)
7575
}
7676

@@ -108,7 +108,7 @@ pub mod example_native_token_transfers {
108108
}
109109

110110
pub fn release_inbound_mint<'info>(
111-
ctx: Context<'_, '_, '_, 'info, ReleaseInboundMintDefault<'info>>,
111+
ctx: Context<'_, '_, '_, 'info, ReleaseInboundMint<'info>>,
112112
args: ReleaseInboundArgs,
113113
) -> Result<()> {
114114
instructions::release_inbound_mint(ctx, args)

0 commit comments

Comments
 (0)