Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 4bd421b

Browse files
authored
token-2022: [L-01] Check for all possible self-auth with CPI guard (#6863)
token-2022: Check for all possible self-auth with CPI guard
1 parent 1c1819f commit 4bd421b

File tree

2 files changed

+46
-21
lines changed

2 files changed

+46
-21
lines changed

token/program-2022-test/tests/cpi_guard.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,27 @@ async fn test_cpi_guard_burn() {
420420
let alice_state = token_obj.get_account_info(&alice.pubkey()).await.unwrap();
421421
assert_eq!(alice_state.base.amount, amount);
422422

423+
// delegate-auth cpi burn by self does not work
424+
token_obj
425+
.approve(
426+
&alice.pubkey(),
427+
&alice.pubkey(),
428+
&alice.pubkey(),
429+
1,
430+
&[&alice],
431+
)
432+
.await
433+
.unwrap();
434+
435+
let error = token_obj
436+
.process_ixs(&[mk_burn(alice.pubkey(), do_checked)], &[&alice])
437+
.await
438+
.unwrap_err();
439+
assert_eq!(error, client_error(TokenError::CpiGuardBurnBlocked));
440+
441+
let alice_state = token_obj.get_account_info(&alice.pubkey()).await.unwrap();
442+
assert_eq!(alice_state.base.amount, amount);
443+
423444
// delegate-auth cpi burn with cpi guard works
424445
token_obj
425446
.approve(

token/program-2022/src/processor.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,18 @@ impl Processor {
381381
}
382382

383383
let self_transfer = source_account_info.key == destination_account_info.key;
384+
if let Ok(cpi_guard) = source_account.get_extension::<CpiGuard>() {
385+
// Blocks all cases where the authority has signed if CPI Guard is
386+
// enabled, including:
387+
// * the account is delegated to the owner
388+
// * the account owner is the permanent delegate
389+
if *authority_info.key == source_account.base.owner
390+
&& cpi_guard.lock_cpi.into()
391+
&& in_cpi()
392+
{
393+
return Err(TokenError::CpiGuardTransferBlocked.into());
394+
}
395+
}
384396
match (source_account.base.delegate, maybe_permanent_delegate) {
385397
(_, Some(ref delegate)) if authority_info.key == delegate => Self::validate_owner(
386398
program_id,
@@ -403,15 +415,6 @@ impl Processor {
403415
authority_info_data_len,
404416
account_info_iter.as_slice(),
405417
)?;
406-
if let Ok(cpi_guard) = source_account.get_extension::<CpiGuard>() {
407-
// If delegated to self, don't allow a transfer with CPI Guard
408-
if delegate == source_account.base.owner
409-
&& cpi_guard.lock_cpi.into()
410-
&& in_cpi()
411-
{
412-
return Err(TokenError::CpiGuardTransferBlocked.into());
413-
}
414-
}
415418
let delegated_amount = u64::from(source_account.base.delegated_amount);
416419
if delegated_amount < amount {
417420
return Err(TokenError::InsufficientFunds.into());
@@ -434,12 +437,6 @@ impl Processor {
434437
authority_info_data_len,
435438
account_info_iter.as_slice(),
436439
)?;
437-
438-
if let Ok(cpi_guard) = source_account.get_extension::<CpiGuard>() {
439-
if cpi_guard.lock_cpi.into() && in_cpi() {
440-
return Err(TokenError::CpiGuardTransferBlocked.into());
441-
}
442-
}
443440
}
444441
}
445442

@@ -1033,6 +1030,19 @@ impl Processor {
10331030
}
10341031
let maybe_permanent_delegate = get_permanent_delegate(&mint);
10351032

1033+
if let Ok(cpi_guard) = source_account.get_extension::<CpiGuard>() {
1034+
// Blocks all cases where the authority has signed if CPI Guard is
1035+
// enabled, including:
1036+
// * the account is delegated to the owner
1037+
// * the account owner is the permanent delegate
1038+
if *authority_info.key == source_account.base.owner
1039+
&& cpi_guard.lock_cpi.into()
1040+
&& in_cpi()
1041+
{
1042+
return Err(TokenError::CpiGuardBurnBlocked.into());
1043+
}
1044+
}
1045+
10361046
if !source_account
10371047
.base
10381048
.is_owned_by_system_program_or_incinerator()
@@ -1080,12 +1090,6 @@ impl Processor {
10801090
authority_info_data_len,
10811091
account_info_iter.as_slice(),
10821092
)?;
1083-
1084-
if let Ok(cpi_guard) = source_account.get_extension::<CpiGuard>() {
1085-
if cpi_guard.lock_cpi.into() && in_cpi() {
1086-
return Err(TokenError::CpiGuardBurnBlocked.into());
1087-
}
1088-
}
10891093
}
10901094
}
10911095
}

0 commit comments

Comments
 (0)