Skip to content
5 changes: 4 additions & 1 deletion interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use swig::actions::{
pub use swig_compact_instructions::*;
use swig_state::{
action::{
all::All, all_but_manage_authority::AllButManageAuthority,
all::All, all_but_manage_authority::AllButManageAuthority, blacklist::Blacklist,
manage_authority::ManageAuthority, program::Program, program_all::ProgramAll,
program_curated::ProgramCurated, program_scope::ProgramScope,
sol_destination_limit::SolDestinationLimit, sol_limit::SolLimit,
Expand Down Expand Up @@ -61,6 +61,7 @@ pub enum ClientAction {
StakeLimit(StakeLimit),
StakeRecurringLimit(StakeRecurringLimit),
StakeAll(StakeAll),
Blacklist(Blacklist),
}

impl ClientAction {
Expand Down Expand Up @@ -105,6 +106,7 @@ impl ClientAction {
(Permission::StakeRecurringLimit, StakeRecurringLimit::LEN)
},
ClientAction::StakeAll(_) => (Permission::StakeAll, StakeAll::LEN),
ClientAction::Blacklist(_) => (Permission::Blacklist, Blacklist::LEN),
};
let offset = data.len() as u32;
let header = Action::new(
Expand Down Expand Up @@ -136,6 +138,7 @@ impl ClientAction {
ClientAction::StakeLimit(action) => action.into_bytes(),
ClientAction::StakeRecurringLimit(action) => action.into_bytes(),
ClientAction::StakeAll(action) => action.into_bytes(),
ClientAction::Blacklist(action) => action.into_bytes(),
};
data.extend_from_slice(
bytes_res.map_err(|e| anyhow::anyhow!("Failed to serialize action {:?}", e))?,
Expand Down
20 changes: 20 additions & 0 deletions program/src/actions/sign_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use swig_state::{
action::{
all::All,
all_but_manage_authority::AllButManageAuthority,
blacklist::Blacklist,
program::Program,
program_all::ProgramAll,
program_curated::ProgramCurated,
Expand Down Expand Up @@ -250,6 +251,16 @@ pub fn sign_v1(
for (index, account_classifier) in account_classifiers.iter().enumerate() {
let account = unsafe { all_accounts.get_unchecked(index) };

// Check if the account is blacklisted
let account_key = unsafe { account.key().as_ref() };
if let Some(blacklist_action) =
RoleMut::get_action_mut::<Blacklist>(role.actions, account_key)?
{
if blacklist_action.is_wallet() {
return Err(SwigAuthenticateError::PermissionDeniedBlacklisted.into());
}
}

// Only check writable accounts as read-only accounts won't modify data
if !account.is_writable() {
continue;
Expand Down Expand Up @@ -321,6 +332,15 @@ pub fn sign_v1(
// This is a CPI call where swig is signing - check Program permissions
let program_id_bytes = instruction.program_id.as_ref();

// First check if the program is blacklisted
if let Some(blacklist_action) =
RoleMut::get_action_mut::<Blacklist>(role.actions, program_id_bytes)?
{
if blacklist_action.is_program() {
return Err(SwigAuthenticateError::PermissionDeniedBlacklisted.into());
}
}

// Check if we have any program permission that allows this program
let has_permission =
// Check for ProgramAll permission (allows any program)
Expand Down
20 changes: 20 additions & 0 deletions program/src/actions/sign_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use swig_state::{
action::{
all::All,
all_but_manage_authority::AllButManageAuthority,
blacklist::Blacklist,
program::Program,
program_all::ProgramAll,
program_curated::ProgramCurated,
Expand Down Expand Up @@ -249,6 +250,16 @@ pub fn sign_v2(
for (index, account_classifier) in account_classifiers.iter().enumerate() {
let account = unsafe { all_accounts.get_unchecked(index) };

// Check if the account is blacklisted
let account_key = unsafe { account.key().as_ref() };
if let Some(blacklist_action) =
RoleMut::get_action_mut::<Blacklist>(role.actions, account_key)?
{
if blacklist_action.is_wallet() {
return Err(SwigAuthenticateError::PermissionDeniedBlacklisted.into());
}
}

// Only check writable accounts as read-only accounts won't modify data
if !account.is_writable() {
continue;
Expand Down Expand Up @@ -324,6 +335,15 @@ pub fn sign_v2(
// permissions
let program_id_bytes = instruction.program_id.as_ref();

// First check if the program is blacklisted
if let Some(blacklist_action) =
RoleMut::get_action_mut::<Blacklist>(role.actions, program_id_bytes)?
{
if blacklist_action.is_program() {
return Err(SwigAuthenticateError::PermissionDeniedBlacklisted.into());
}
}

// Check if we have any program permission that allows this program
let has_permission =
// Check for ProgramAll permission (allows any program)
Expand Down
Loading
Loading