Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ pub fn register_transceiver(ctx: Context<RegisterTransceiver>) -> Result<()> {
Ok(())
}

// TODO: Rename to DisableTransceiver
#[derive(Accounts)]
pub struct DeregisterTransceiver<'info> {
#[account(
Expand All @@ -166,11 +167,14 @@ pub fn deregister_transceiver(ctx: Context<DeregisterTransceiver>) -> Result<()>
.enabled_transceivers
.set(ctx.accounts.registered_transceiver.id, false)?;

// decrement threshold if too high
let num_enabled_transceivers = ctx.accounts.config.enabled_transceivers.len();
// at least one transceiver should be enabled
if num_enabled_transceivers == 0 {
return Err(NTTError::ZeroThreshold.into());
}
// decrement threshold if too high
if num_enabled_transceivers < ctx.accounts.config.threshold {
// threshold should be at least 1
ctx.accounts.config.threshold = num_enabled_transceivers.max(1);
ctx.accounts.config.threshold = num_enabled_transceivers;
}
Ok(())
}
Expand Down
87 changes: 73 additions & 14 deletions solana/programs/example-native-token-transfers/tests/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,23 +118,11 @@ async fn test_reregister_all_transceivers() {
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap();
// assert threshold decreases
assert_threshold(&mut ctx, num_dummy_transceivers - idx as u8).await;
}

// deregister baked-in transceiver
deregister_transceiver(
&good_ntt,
DeregisterTransceiver {
owner: test_data.program_owner.pubkey(),
transceiver: example_native_token_transfers::ID,
},
)
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap();
assert_threshold(&mut ctx, 1).await;

// reregister dummy transceiver
// reregister dummy transceivers
for (idx, transceiver) in dummy_transceivers.iter().enumerate() {
register_transceiver(
&good_ntt,
Expand All @@ -147,6 +135,7 @@ async fn test_reregister_all_transceivers() {
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap();
// assert transceiver_id and threshold are retained
assert_transceiver_id(&mut ctx, transceiver, idx as u8 + 1).await;
assert_threshold(&mut ctx, 1).await;
}
Expand All @@ -163,10 +152,80 @@ async fn test_reregister_all_transceivers() {
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap();
// assert transceiver_id and threshold are retained
assert_transceiver_id(&mut ctx, &example_native_token_transfers::ID, 0).await;
assert_threshold(&mut ctx, 1).await;
}

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

// attempt to deregister only enabled transceiver (baked-in transceiver)
let err = deregister_transceiver(
&good_ntt,
DeregisterTransceiver {
owner: test_data.program_owner.pubkey(),
transceiver: example_native_token_transfers::ID,
},
)
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap_err();
assert_eq!(
err.unwrap(),
TransactionError::InstructionError(
0,
InstructionError::Custom(NTTError::ZeroThreshold.into())
)
);

// register arbitrary executable program as dummy transceiver
let dummy_transceiver = wormhole_anchor_sdk::wormhole::program::Wormhole::id();
register_transceiver(
&good_ntt,
RegisterTransceiver {
payer: ctx.payer.pubkey(),
owner: test_data.program_owner.pubkey(),
transceiver: dummy_transceiver,
},
)
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap();

// deregister baked-in transceiver
deregister_transceiver(
&good_ntt,
DeregisterTransceiver {
owner: test_data.program_owner.pubkey(),
transceiver: example_native_token_transfers::ID,
},
)
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap();

// attempt to deregister last enabled transceiver (dummy transceiver)
let err = deregister_transceiver(
&good_ntt,
DeregisterTransceiver {
owner: test_data.program_owner.pubkey(),
transceiver: dummy_transceiver,
},
)
.submit_with_signers(&[&test_data.program_owner], &mut ctx)
.await
.unwrap_err();
assert_eq!(
err.unwrap(),
TransactionError::InstructionError(
0,
InstructionError::Custom(NTTError::ZeroThreshold.into())
)
);
}

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