Skip to content

Commit

Permalink
feat(spending_limit): verify members are non-empty and contain no dup…
Browse files Browse the repository at this point in the history
…licates
  • Loading branch information
vovacodes committed Aug 2, 2023
1 parent 3906ce9 commit 13240af
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
16 changes: 12 additions & 4 deletions programs/multisig/src/instructions/config_transaction_execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,12 @@ impl<'info> ConfigTransactionExecute<'info> {
],
)?;

let mut members = members.to_vec();
// Make sure members are sorted.
members.sort();

// Serialize the SpendingLimit data into the account info.
SpendingLimit {
let spending_limit = SpendingLimit {
multisig: multisig.key().to_owned(),
create_key: create_key.to_owned(),
vault_index: *vault_index,
Expand All @@ -227,10 +231,14 @@ impl<'info> ConfigTransactionExecute<'info> {
remaining_amount: *amount,
last_reset: Clock::get()?.unix_timestamp,
bump: spending_limit_bump,
members: members.to_vec(),
members,
destinations: destinations.to_vec(),
}
.try_serialize(&mut &mut spending_limit_info.data.borrow_mut()[..])?;
};

spending_limit.invariant()?;

spending_limit
.try_serialize(&mut &mut spending_limit_info.data.borrow_mut()[..])?;
}

ConfigAction::RemoveSpendingLimit {
Expand Down
12 changes: 12 additions & 0 deletions programs/multisig/src/state/spending_limit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use anchor_lang::prelude::*;

use crate::errors::*;

#[account]
pub struct SpendingLimit {
/// The multisig this belongs to.
Expand Down Expand Up @@ -62,6 +64,16 @@ impl SpendingLimit {
4 + // destinations vector length
destinations_length * 32 // destinations
}

pub fn invariant(&self) -> Result<()> {
require!(!self.members.is_empty(), MultisigError::EmptyMembers);

// There must be no duplicate members, we make sure members are sorted when creating a SpendingLimit.
let has_duplicates = self.members.windows(2).any(|win| win[0] == win[1]);
require!(!has_duplicates, MultisigError::DuplicateMember);

Ok(())
}
}

/// The reset period of the spending limit.
Expand Down

0 comments on commit 13240af

Please sign in to comment.