Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

solana: add more tests #219

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
solana: add two negative transfer tests
kcsongor authored and johnsaigle committed Mar 22, 2024
commit bc6cb5f4a5aa09580e7b07cf4481ae34e004cb5e
Original file line number Diff line number Diff line change
@@ -42,18 +42,23 @@ pub const OUTBOUND_LIMIT: u64 = 10000;
pub const INBOUND_LIMIT: u64 = 50000;

pub const OTHER_TRANSCEIVER: [u8; 32] = [7u8; 32];
pub const ANOTHER_TRANSCEIVER: [u8; 32] = [8u8; 32];
pub const OTHER_MANAGER: [u8; 32] = [9u8; 32];
pub const ANOTHER_MANAGER: [u8; 32] = [5u8; 32];

pub const THIS_CHAIN: u16 = 1;
pub const OTHER_CHAIN: u16 = 2;
pub const ANOTHER_CHAIN: u16 = 3;

pub struct TestData {
pub governance: Governance,
pub program_owner: Keypair,
pub mint_authority: Keypair,
pub mint: Pubkey,
pub bad_mint: Pubkey,
pub user: Keypair,
pub user_token_account: Pubkey,
pub bad_user_token_account: Pubkey,
}

pub async fn setup_with_extra_accounts(
@@ -197,7 +202,6 @@ pub async fn setup_ntt(ctx: &mut ProgramTestContext, test_data: &TestData, mode:
SetPeer {
payer: ctx.payer.pubkey(),
owner: test_data.program_owner.pubkey(),
mint: test_data.mint,
},
SetPeerArgs {
chain_id: ChainId { id: OTHER_CHAIN },
@@ -209,13 +213,32 @@ pub async fn setup_ntt(ctx: &mut ProgramTestContext, test_data: &TestData, mode:
.submit_with_signers(&[&test_data.program_owner], ctx)
.await
.unwrap();

set_peer(
&GoodNTT {},
SetPeer {
payer: ctx.payer.pubkey(),
owner: test_data.program_owner.pubkey(),
},
SetPeerArgs {
chain_id: ChainId { id: ANOTHER_CHAIN },
address: ANOTHER_MANAGER,
limit: INBOUND_LIMIT,
token_decimals: 7,
},
)
.submit_with_signers(&[&test_data.program_owner], ctx)
.await
.unwrap();
}

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

let bad_mint = Keypair::new();

let user = Keypair::new();
let payer = ctx.payer.pubkey();

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

create_mint(ctx, &bad_mint, &mint_authority.pubkey(), 9)
.await
.submit(ctx)
.await
.unwrap();

// create associated token account for user
let user_token_account =
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
.await
.unwrap();

let bad_user_token_account =
get_associated_token_address_with_program_id(&user.pubkey(), &bad_mint.pubkey(), &Token::id());

spl_associated_token_account::instruction::create_associated_token_account(
&payer,
&user.pubkey(),
&bad_mint.pubkey(),
&Token::id(),
)
.submit(ctx)
.await
.unwrap();


spl_token::instruction::mint_to(
&Token::id(),
&mint.pubkey(),
@@ -252,15 +295,30 @@ pub async fn setup_accounts(ctx: &mut ProgramTestContext, program_owner: Keypair
.await
.unwrap();

spl_token::instruction::mint_to(
&Token::id(),
&bad_mint.pubkey(),
&bad_user_token_account,
&mint_authority.pubkey(),
&[],
MINT_AMOUNT,
)
.unwrap()
.submit_with_signers(&[&mint_authority], ctx)
.await
.unwrap();

TestData {
governance: Governance {
program: wormhole_governance::ID,
},
program_owner,
mint_authority,
mint: mint.pubkey(),
bad_mint: bad_mint.pubkey(),
user,
user_token_account,
bad_user_token_account,
}
}

Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@ use crate::sdk::accounts::NTT;
pub struct SetPeer {
pub payer: Pubkey,
pub owner: Pubkey,
pub mint: Pubkey,
}

pub fn set_peer(ntt: &NTT, accounts: SetPeer, args: SetPeerArgs) -> Instruction {
101 changes: 98 additions & 3 deletions solana/programs/example-native-token-transfers/tests/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg(feature = "test-sbf")]
// #![cfg(feature = "test-sbf")]
#![feature(type_changing_struct_update)]

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

use crate::{
common::{query::GetAccountDataAnchor, setup::OUTBOUND_LIMIT},
common::{
query::GetAccountDataAnchor,
setup::{ANOTHER_CHAIN, OUTBOUND_LIMIT},
},
sdk::{
accounts::{good_ntt, NTTAccounts},
instructions::transfer::Transfer,
@@ -316,6 +319,98 @@ async fn locking_mode_locks_tokens() {
assert_eq!(mint_before.supply, mint_after.supply);
}

#[tokio::test]
async fn test_bad_mint() {
let (mut ctx, test_data) = setup(Mode::Locking).await;

let outbox_item = Keypair::new();

let (mut accs, args) = init_accs_args(
&GoodNTT {},
&mut ctx,
&test_data,
outbox_item.pubkey(),
1050,
false,
);

// use the wrong mint here
accs.mint = test_data.bad_mint;

approve_token_authority(
&GoodNTT {},
&test_data.bad_user_token_account,
&test_data.user.pubkey(),
args.amount,
)
.submit_with_signers(&[&test_data.user], &mut ctx)
.await
.unwrap();

let err = transfer(&GoodNTT {}, accs, args, Mode::Locking)
.submit_with_signers(&[&test_data.user, &outbox_item], &mut ctx)
.await
.unwrap_err();

assert_eq!(
err.unwrap(),
TransactionError::InstructionError(
0,
InstructionError::Custom(ErrorCode::ConstraintAddress.into())
)
);
}

#[tokio::test]
async fn test_invalid_peer() {
// in this test we send to 'OTHER_CHAIN' but use the peer account for
// 'ANOTHER_CHAIN'.
struct BadNTT {}

impl NTTAccounts for BadNTT {
fn peer(&self, _chain_id: u16) -> Pubkey {
// return 'ANOTHER_CHAIN' peer account
GoodNTT {}.peer(ANOTHER_CHAIN)
}
}

let (mut ctx, test_data) = setup(Mode::Locking).await;

let outbox_item = Keypair::new();

let (accs, args) = init_accs_args(
&BadNTT {},
&mut ctx,
&test_data,
outbox_item.pubkey(),
1050,
false,
);

approve_token_authority(
&GoodNTT {},
&test_data.bad_user_token_account,
&test_data.user.pubkey(),
args.amount,
)
.submit_with_signers(&[&test_data.user], &mut ctx)
.await
.unwrap();

let err = transfer(&BadNTT {}, accs, args, Mode::Locking)
.submit_with_signers(&[&test_data.user, &outbox_item], &mut ctx)
.await
.unwrap_err();

assert_eq!(
err.unwrap(),
TransactionError::InstructionError(
0,
InstructionError::Custom(ErrorCode::ConstraintSeeds.into())
)
);
}

#[tokio::test]
async fn test_rate_limit() {
let (mut ctx, test_data) = setup(Mode::Locking).await;