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
10 changes: 5 additions & 5 deletions programs/earn/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ pub mod earn {

// Admin instructions

#[cfg(not(feature = "migrate"))]
pub fn initialize(ctx: Context<Initialize>, current_index: u64) -> Result<()> {
Initialize::handler(ctx, current_index)
}

#[cfg(feature = "migrate")]
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
Initialize::handler(ctx, 0)
}

#[cfg(not(feature = "migrate"))]
pub fn initialize(ctx: Context<Initialize>, current_index: u64) -> Result<()> {
Initialize::handler(ctx, current_index)
}

// TODO add admin instructions for updating global values

// Portal instrutions
Expand Down
7 changes: 5 additions & 2 deletions programs/portal/src/bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ impl Bitmap {
.expect("Bitmap length must not exceed the bounds of u8")
}

pub fn len(self) -> usize {
BM::<128>::from_value(self.map).len()
pub fn len(self) -> u8 {
BM::<128>::from_value(self.map)
.len()
.try_into()
.expect("Bitmap length must not exceed the bounds of u8")
}

pub fn is_empty(self) -> bool {
Expand Down
6 changes: 4 additions & 2 deletions programs/portal/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ pub enum NTTError {
InvalidPendingTokenAuthority,
#[msg("IncorrectRentPayer")]
IncorrectRentPayer,
#[msg("InvalidMultisig")]
InvalidMultisig,
#[msg("ThresholdTooHigh")]
ThresholdTooHigh,
#[msg("InvalidTransceiverProgram")]
InvalidTransceiverProgram,
}

impl From<ScalingError> for NTTError {
Expand Down
147 changes: 116 additions & 31 deletions programs/portal/src/instructions/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,26 @@ pub struct TransferOwnership<'info> {
pub fn transfer_ownership(ctx: Context<TransferOwnership>) -> Result<()> {
ctx.accounts.config.pending_owner = Some(ctx.accounts.new_owner.key());

// TODO: only transfer authority when the authority is not already the upgrade lock
bpf_loader_upgradeable::set_upgrade_authority_checked(
CpiContext::new_with_signer(
ctx.accounts
.bpf_loader_upgradeable_program
.to_account_info(),
bpf_loader_upgradeable::SetUpgradeAuthorityChecked {
program_data: ctx.accounts.program_data.to_account_info(),
current_authority: ctx.accounts.owner.to_account_info(),
new_authority: ctx.accounts.upgrade_lock.to_account_info(),
},
&[&[b"upgrade_lock", &[ctx.bumps.upgrade_lock]]],
),
&crate::ID,
)
// only transfer authority when the authority is not already the upgrade lock
if ctx.accounts.program_data.upgrade_authority_address != Some(ctx.accounts.upgrade_lock.key())
{
return bpf_loader_upgradeable::set_upgrade_authority_checked(
CpiContext::new_with_signer(
ctx.accounts
.bpf_loader_upgradeable_program
.to_account_info(),
bpf_loader_upgradeable::SetUpgradeAuthorityChecked {
program_data: ctx.accounts.program_data.to_account_info(),
current_authority: ctx.accounts.owner.to_account_info(),
new_authority: ctx.accounts.upgrade_lock.to_account_info(),
},
&[&[b"upgrade_lock", &[ctx.bumps.upgrade_lock]]],
),
&crate::ID,
);
}

Ok(())
}

pub fn transfer_ownership_one_step_unchecked(ctx: Context<TransferOwnership>) -> Result<()> {
Expand Down Expand Up @@ -244,7 +249,12 @@ pub fn set_token_authority(ctx: Context<SetTokenAuthorityChecked>) -> Result<()>
.set_inner(PendingTokenAuthority {
bump: ctx.bumps.pending_token_authority,
pending_authority: ctx.accounts.common.new_authority.key(),
rent_payer: ctx.accounts.rent_payer.key(),
rent_payer: if ctx.accounts.pending_token_authority.rent_payer != Pubkey::default() {
// do not update rent_payer if already initialized
ctx.accounts.pending_token_authority.rent_payer
} else {
ctx.accounts.rent_payer.key()
},
});
Ok(())
}
Expand Down Expand Up @@ -368,6 +378,7 @@ pub struct SetPeer<'info> {

#[account(
has_one = owner,
constraint = args.chain_id != config.chain_id @ NTTError::InvalidChainId
)]
pub config: Account<'info, Config>,

Expand Down Expand Up @@ -411,10 +422,18 @@ pub fn set_peer(ctx: Context<SetPeer>, args: SetPeerArgs) -> Result<()> {
token_decimals: args.token_decimals,
});

ctx.accounts.inbox_rate_limit.set_inner(InboxRateLimit {
bump: ctx.bumps.inbox_rate_limit,
rate_limit: RateLimitState::new(args.limit),
});
// if rate limit is uninitialized/unused, set new rate limit
if ctx.accounts.inbox_rate_limit.rate_limit.last_tx_timestamp == 0 {
ctx.accounts.inbox_rate_limit.set_inner(InboxRateLimit {
bump: ctx.bumps.inbox_rate_limit,
rate_limit: RateLimitState::new(args.limit),
});
}
// else update rate limit
else {
ctx.accounts.inbox_rate_limit.set_limit(args.limit);
}

Ok(())
}

Expand All @@ -433,13 +452,16 @@ pub struct RegisterTransceiver<'info> {
#[account(mut)]
pub payer: Signer<'info>,

#[account(executable)]
#[account(
executable,
constraint = transceiver.key() != Pubkey::default() @ NTTError::InvalidTransceiverProgram
)]
/// CHECK: transceiver is meant to be a transceiver program. Arguably a `Program` constraint could be
/// used here that wraps the Transceiver account type.
pub transceiver: UncheckedAccount<'info>,

#[account(
init,
init_if_needed,
space = 8 + RegisteredTransceiver::INIT_SPACE,
payer = payer,
seeds = [RegisteredTransceiver::SEED_PREFIX, transceiver.key().as_ref()],
Expand All @@ -451,17 +473,58 @@ pub struct RegisterTransceiver<'info> {
}

pub fn register_transceiver(ctx: Context<RegisterTransceiver>) -> Result<()> {
let id = ctx.accounts.config.next_transceiver_id;
ctx.accounts.config.next_transceiver_id += 1;
// initialize registered transceiver with new id on init
if ctx.accounts.registered_transceiver.transceiver_address == Pubkey::default() {
let id = ctx.accounts.config.next_transceiver_id;
ctx.accounts.config.next_transceiver_id += 1;
ctx.accounts
.registered_transceiver
.set_inner(RegisteredTransceiver {
bump: ctx.bumps.registered_transceiver,
id,
transceiver_address: ctx.accounts.transceiver.key(),
});
}

ctx.accounts
.registered_transceiver
.set_inner(RegisteredTransceiver {
bump: ctx.bumps.registered_transceiver,
id,
transceiver_address: ctx.accounts.transceiver.key(),
});
.config
.enabled_transceivers
.set(ctx.accounts.registered_transceiver.id, true)?;

ctx.accounts.config.enabled_transceivers.set(id, true)?;
Ok(())
}

#[derive(Accounts)]
pub struct DeregisterTransceiver<'info> {
#[account(
mut,
has_one = owner,
)]
pub config: Account<'info, Config>,

#[account(mut)]
pub owner: Signer<'info>,

#[account(
seeds = [RegisteredTransceiver::SEED_PREFIX, registered_transceiver.transceiver_address.as_ref()],
bump,
constraint = config.enabled_transceivers.get(registered_transceiver.id)? @ NTTError::DisabledTransceiver,
)]
pub registered_transceiver: Account<'info, RegisteredTransceiver>,
}

pub fn deregister_transceiver(ctx: Context<DeregisterTransceiver>) -> Result<()> {
ctx.accounts
.config
.enabled_transceivers
.set(ctx.accounts.registered_transceiver.id, false)?;

// decrement threshold if too high
let num_enabled_transceivers = ctx.accounts.config.enabled_transceivers.len();
if num_enabled_transceivers < ctx.accounts.config.threshold {
// threshold should be at least 1
ctx.accounts.config.threshold = num_enabled_transceivers.max(1);
}
Ok(())
}

Expand Down Expand Up @@ -540,3 +603,25 @@ pub fn set_paused(ctx: Context<SetPaused>, paused: bool) -> Result<()> {
ctx.accounts.config.paused = paused;
Ok(())
}

// * Set Threshold
#[derive(Accounts)]
#[instruction(threshold: u8)]
pub struct SetThreshold<'info> {
pub owner: Signer<'info>,

#[account(
mut,
has_one = owner,
constraint = threshold <= config.enabled_transceivers.len() @ NTTError::ThresholdTooHigh
)]
pub config: Account<'info, Config>,
}

pub fn set_threshold(ctx: Context<SetThreshold>, threshold: u8) -> Result<()> {
if threshold == 0 {
return Err(NTTError::ZeroThreshold.into());
}
ctx.accounts.config.threshold = threshold;
Ok(())
}
52 changes: 16 additions & 36 deletions programs/portal/src/instructions/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use crate::{
error::NTTError,
ntt_messages::{BpfLoaderUpgradeable, ChainId, Mode},
queue::{outbox::OutboxRateLimit, rate_limit::RateLimitState},
spl_multisig::SplMultisig,
};

#[derive(Accounts)]
#[instruction(args: InitializeArgs)]
pub struct Initialize<'info> {
#[account(mut)]
pub payer: Signer<'info>,
Expand All @@ -27,15 +27,16 @@ pub struct Initialize<'info> {

#[account(
init,
space = 8 + crate::config::Config::INIT_SPACE,
space = 8 + Config::INIT_SPACE,
payer = payer,
seeds = [crate::config::Config::SEED_PREFIX],
seeds = [Config::SEED_PREFIX],
bump
)]
pub config: Box<Account<'info, crate::config::Config>>,
pub config: Box<Account<'info, Config>>,

// NOTE: this account is unconstrained and is the responsibility of the
// handler to constrain it
#[account(
constraint = mint.mint_authority.unwrap() == token_authority.key() @ NTTError::InvalidMintAuthority
)]
pub mint: Box<InterfaceAccount<'info, token_interface::Mint>>,

#[account(
Expand Down Expand Up @@ -88,42 +89,21 @@ pub struct InitializeArgs {
pub mode: Mode,
}

#[derive(Accounts)]
#[instruction(args: InitializeArgs)]
pub struct InitializeMultisig<'info> {
#[account(
constraint =
args.mode == Mode::Locking
|| common.mint.mint_authority.unwrap() == multisig.key()
@ NTTError::InvalidMintAuthority,
)]
pub common: Initialize<'info>,

#[account(
constraint =
multisig.m == 1 && multisig.signers.contains(&common.token_authority.key())
@ NTTError::InvalidMultisig,
)]
pub multisig: InterfaceAccount<'info, SplMultisig>,
}

pub fn initialize_multisig(ctx: Context<InitializeMultisig>, args: InitializeArgs) -> Result<()> {
let common = &mut ctx.accounts.common;

common.config.set_inner(crate::config::Config {
bump: ctx.bumps.common.config,
mint: common.mint.key(),
token_program: common.token_program.key(),
pub fn initialize(ctx: Context<Initialize>, args: InitializeArgs) -> Result<()> {
ctx.accounts.config.set_inner(crate::config::Config {
bump: ctx.bumps.config,
mint: ctx.accounts.mint.key(),
token_program: ctx.accounts.token_program.key(),
mode: args.mode,
chain_id: ChainId { id: args.chain_id },
owner: common.deployer.key(),
owner: ctx.accounts.deployer.key(),
pending_owner: None,
paused: false,
next_transceiver_id: 0,
// NOTE: can't be changed for now
// NOTE: can be changed via `set_threshold` ix
threshold: 1,
enabled_transceivers: Bitmap::new(),
custody: common.custody.key(),
custody: ctx.accounts.custody.key(),
release_inbound_remaining_accounts: [
RemainingAccount::new(earn::ID, false),
RemainingAccount::new(
Expand All @@ -135,7 +115,7 @@ pub fn initialize_multisig(ctx: Context<InitializeMultisig>, args: InitializeArg
evm_wrapped_token: [0; 32],
});

common.rate_limit.set_inner(OutboxRateLimit {
ctx.accounts.rate_limit.set_inner(OutboxRateLimit {
rate_limit: RateLimitState::new(args.limit),
});

Expand Down
Loading