Skip to content

Commit 49d9546

Browse files
committed
solana: add two negative transfer tests
1 parent c1921d9 commit 49d9546

File tree

3 files changed

+157
-5
lines changed

3 files changed

+157
-5
lines changed

solana/programs/example-native-token-transfers/tests/common/setup.rs

+59-1
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,23 @@ pub const OUTBOUND_LIMIT: u64 = 10000;
4242
pub const INBOUND_LIMIT: u64 = 50000;
4343

4444
pub const OTHER_TRANSCEIVER: [u8; 32] = [7u8; 32];
45+
pub const ANOTHER_TRANSCEIVER: [u8; 32] = [8u8; 32];
4546
pub const OTHER_MANAGER: [u8; 32] = [9u8; 32];
47+
pub const ANOTHER_MANAGER: [u8; 32] = [5u8; 32];
4648

4749
pub const THIS_CHAIN: u16 = 1;
4850
pub const OTHER_CHAIN: u16 = 2;
51+
pub const ANOTHER_CHAIN: u16 = 3;
4952

5053
pub struct TestData {
5154
pub governance: Governance,
5255
pub program_owner: Keypair,
5356
pub mint_authority: Keypair,
5457
pub mint: Pubkey,
58+
pub bad_mint: Pubkey,
5559
pub user: Keypair,
5660
pub user_token_account: Pubkey,
61+
pub bad_user_token_account: Pubkey,
5762
}
5863

5964
pub async fn setup_with_extra_accounts(
@@ -197,7 +202,6 @@ pub async fn setup_ntt(ctx: &mut ProgramTestContext, test_data: &TestData, mode:
197202
SetPeer {
198203
payer: ctx.payer.pubkey(),
199204
owner: test_data.program_owner.pubkey(),
200-
mint: test_data.mint,
201205
},
202206
SetPeerArgs {
203207
chain_id: ChainId { id: OTHER_CHAIN },
@@ -209,13 +213,32 @@ pub async fn setup_ntt(ctx: &mut ProgramTestContext, test_data: &TestData, mode:
209213
.submit_with_signers(&[&test_data.program_owner], ctx)
210214
.await
211215
.unwrap();
216+
217+
set_peer(
218+
&GoodNTT {},
219+
SetPeer {
220+
payer: ctx.payer.pubkey(),
221+
owner: test_data.program_owner.pubkey(),
222+
},
223+
SetPeerArgs {
224+
chain_id: ChainId { id: ANOTHER_CHAIN },
225+
address: ANOTHER_MANAGER,
226+
limit: INBOUND_LIMIT,
227+
token_decimals: 7,
228+
},
229+
)
230+
.submit_with_signers(&[&test_data.program_owner], ctx)
231+
.await
232+
.unwrap();
212233
}
213234

214235
pub async fn setup_accounts(ctx: &mut ProgramTestContext, program_owner: Keypair) -> TestData {
215236
// create mint
216237
let mint = Keypair::new();
217238
let mint_authority = Keypair::new();
218239

240+
let bad_mint = Keypair::new();
241+
219242
let user = Keypair::new();
220243
let payer = ctx.payer.pubkey();
221244

@@ -225,6 +248,12 @@ pub async fn setup_accounts(ctx: &mut ProgramTestContext, program_owner: Keypair
225248
.await
226249
.unwrap();
227250

251+
create_mint(ctx, &bad_mint, &mint_authority.pubkey(), 9)
252+
.await
253+
.submit(ctx)
254+
.await
255+
.unwrap();
256+
228257
// create associated token account for user
229258
let user_token_account =
230259
get_associated_token_address_with_program_id(&user.pubkey(), &mint.pubkey(), &Token::id());
@@ -239,6 +268,20 @@ pub async fn setup_accounts(ctx: &mut ProgramTestContext, program_owner: Keypair
239268
.await
240269
.unwrap();
241270

271+
let bad_user_token_account =
272+
get_associated_token_address_with_program_id(&user.pubkey(), &bad_mint.pubkey(), &Token::id());
273+
274+
spl_associated_token_account::instruction::create_associated_token_account(
275+
&payer,
276+
&user.pubkey(),
277+
&bad_mint.pubkey(),
278+
&Token::id(),
279+
)
280+
.submit(ctx)
281+
.await
282+
.unwrap();
283+
284+
242285
spl_token::instruction::mint_to(
243286
&Token::id(),
244287
&mint.pubkey(),
@@ -252,15 +295,30 @@ pub async fn setup_accounts(ctx: &mut ProgramTestContext, program_owner: Keypair
252295
.await
253296
.unwrap();
254297

298+
spl_token::instruction::mint_to(
299+
&Token::id(),
300+
&bad_mint.pubkey(),
301+
&bad_user_token_account,
302+
&mint_authority.pubkey(),
303+
&[],
304+
MINT_AMOUNT,
305+
)
306+
.unwrap()
307+
.submit_with_signers(&[&mint_authority], ctx)
308+
.await
309+
.unwrap();
310+
255311
TestData {
256312
governance: Governance {
257313
program: wormhole_governance::ID,
258314
},
259315
program_owner,
260316
mint_authority,
261317
mint: mint.pubkey(),
318+
bad_mint: bad_mint.pubkey(),
262319
user,
263320
user_token_account,
321+
bad_user_token_account,
264322
}
265323
}
266324

solana/programs/example-native-token-transfers/tests/sdk/instructions/admin.rs

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use crate::sdk::accounts::NTT;
77
pub struct SetPeer {
88
pub payer: Pubkey,
99
pub owner: Pubkey,
10-
pub mint: Pubkey,
1110
}
1211

1312
pub fn set_peer(ntt: &NTT, accounts: SetPeer, args: SetPeerArgs) -> Instruction {

solana/programs/example-native-token-transfers/tests/transfer.rs

+98-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#![cfg(feature = "test-sbf")]
1+
// #![cfg(feature = "test-sbf")]
22
#![feature(type_changing_struct_update)]
33

4-
use anchor_lang::prelude::{Clock, Pubkey};
4+
use anchor_lang::prelude::{Clock, ErrorCode, Pubkey};
55
use anchor_spl::token::{Mint, TokenAccount};
66
use common::setup::{TestData, OTHER_CHAIN};
77
use example_native_token_transfers::{
@@ -25,7 +25,10 @@ use solana_sdk::{
2525
use wormhole_anchor_sdk::wormhole::PostedVaa;
2626

2727
use crate::{
28-
common::{query::GetAccountDataAnchor, setup::OUTBOUND_LIMIT},
28+
common::{
29+
query::GetAccountDataAnchor,
30+
setup::{ANOTHER_CHAIN, OUTBOUND_LIMIT},
31+
},
2932
sdk::{
3033
accounts::{good_ntt, NTTAccounts},
3134
instructions::transfer::Transfer,
@@ -316,6 +319,98 @@ async fn locking_mode_locks_tokens() {
316319
assert_eq!(mint_before.supply, mint_after.supply);
317320
}
318321

322+
#[tokio::test]
323+
async fn test_bad_mint() {
324+
let (mut ctx, test_data) = setup(Mode::Locking).await;
325+
326+
let outbox_item = Keypair::new();
327+
328+
let (mut accs, args) = init_accs_args(
329+
&GoodNTT {},
330+
&mut ctx,
331+
&test_data,
332+
outbox_item.pubkey(),
333+
1050,
334+
false,
335+
);
336+
337+
// use the wrong mint here
338+
accs.mint = test_data.bad_mint;
339+
340+
approve_token_authority(
341+
&GoodNTT {},
342+
&test_data.bad_user_token_account,
343+
&test_data.user.pubkey(),
344+
args.amount,
345+
)
346+
.submit_with_signers(&[&test_data.user], &mut ctx)
347+
.await
348+
.unwrap();
349+
350+
let err = transfer(&GoodNTT {}, accs, args, Mode::Locking)
351+
.submit_with_signers(&[&test_data.user, &outbox_item], &mut ctx)
352+
.await
353+
.unwrap_err();
354+
355+
assert_eq!(
356+
err.unwrap(),
357+
TransactionError::InstructionError(
358+
0,
359+
InstructionError::Custom(ErrorCode::ConstraintAddress.into())
360+
)
361+
);
362+
}
363+
364+
#[tokio::test]
365+
async fn test_invalid_peer() {
366+
// in this test we send to 'OTHER_CHAIN' but use the peer account for
367+
// 'ANOTHER_CHAIN'.
368+
struct BadNTT {}
369+
370+
impl NTTAccounts for BadNTT {
371+
fn peer(&self, _chain_id: u16) -> Pubkey {
372+
// return 'ANOTHER_CHAIN' peer account
373+
GoodNTT {}.peer(ANOTHER_CHAIN)
374+
}
375+
}
376+
377+
let (mut ctx, test_data) = setup(Mode::Locking).await;
378+
379+
let outbox_item = Keypair::new();
380+
381+
let (accs, args) = init_accs_args(
382+
&BadNTT {},
383+
&mut ctx,
384+
&test_data,
385+
outbox_item.pubkey(),
386+
1050,
387+
false,
388+
);
389+
390+
approve_token_authority(
391+
&GoodNTT {},
392+
&test_data.bad_user_token_account,
393+
&test_data.user.pubkey(),
394+
args.amount,
395+
)
396+
.submit_with_signers(&[&test_data.user], &mut ctx)
397+
.await
398+
.unwrap();
399+
400+
let err = transfer(&BadNTT {}, accs, args, Mode::Locking)
401+
.submit_with_signers(&[&test_data.user, &outbox_item], &mut ctx)
402+
.await
403+
.unwrap_err();
404+
405+
assert_eq!(
406+
err.unwrap(),
407+
TransactionError::InstructionError(
408+
0,
409+
InstructionError::Custom(ErrorCode::ConstraintSeeds.into())
410+
)
411+
);
412+
}
413+
319414
#[tokio::test]
320415
async fn test_rate_limit() {
321416
let (mut ctx, test_data) = setup(Mode::Locking).await;

0 commit comments

Comments
 (0)