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

Commit 126fb93

Browse files
authored
token-2022: implement CpiGuard (#3712)
token-2022: implement CPI Guard CPI Guard is an extension to block certain unsafe token operations from being done by programs through CPI
1 parent 17b63e9 commit 126fb93

File tree

13 files changed

+1208
-30
lines changed

13 files changed

+1208
-30
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

token/client/src/token.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use {
2020
},
2121
spl_token_2022::{
2222
extension::{
23-
confidential_transfer, default_account_state, interest_bearing_mint, memo_transfer,
24-
transfer_fee, ExtensionType, StateWithExtensionsOwned,
23+
confidential_transfer, cpi_guard, default_account_state, interest_bearing_mint,
24+
memo_transfer, transfer_fee, ExtensionType, StateWithExtensionsOwned,
2525
},
2626
instruction,
2727
solana_zk_token_sdk::{
@@ -1388,6 +1388,50 @@ where
13881388
.await
13891389
}
13901390

1391+
/// Prevent unsafe usage of token account through CPI
1392+
pub async fn enable_cpi_guard<S: Signers>(
1393+
&self,
1394+
account: &Pubkey,
1395+
authority: &Pubkey,
1396+
signing_keypairs: &S,
1397+
) -> TokenResult<T::Output> {
1398+
let signing_pubkeys = signing_keypairs.pubkeys();
1399+
let multisig_signers = self.get_multisig_signers(authority, &signing_pubkeys);
1400+
1401+
self.process_ixs(
1402+
&[cpi_guard::instruction::enable_cpi_guard(
1403+
&self.program_id,
1404+
account,
1405+
authority,
1406+
&multisig_signers,
1407+
)?],
1408+
signing_keypairs,
1409+
)
1410+
.await
1411+
}
1412+
1413+
/// Stop preventing unsafe usage of token account through CPI
1414+
pub async fn disable_cpi_guard<S: Signers>(
1415+
&self,
1416+
account: &Pubkey,
1417+
authority: &Pubkey,
1418+
signing_keypairs: &S,
1419+
) -> TokenResult<T::Output> {
1420+
let signing_pubkeys = signing_keypairs.pubkeys();
1421+
let multisig_signers = self.get_multisig_signers(authority, &signing_pubkeys);
1422+
1423+
self.process_ixs(
1424+
&[cpi_guard::instruction::disable_cpi_guard(
1425+
&self.program_id,
1426+
account,
1427+
authority,
1428+
&multisig_signers,
1429+
)?],
1430+
signing_keypairs,
1431+
)
1432+
.await
1433+
}
1434+
13911435
/// Update interest rate
13921436
pub async fn update_interest_rate<S: Signers>(
13931437
&self,

token/program-2022-test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ solana-sdk = "=1.14.4"
2121
spl-associated-token-account = { version = "1.1", path = "../../associated-token-account/program" }
2222
spl-memo = { version = "3.0.1", path = "../../memo/program", features = ["no-entrypoint"] }
2323
spl-token-2022 = { version = "0.4", path="../program-2022", features = ["no-entrypoint"] }
24+
spl-instruction-padding = { version = "0.1.0", path="../../instruction-padding/program", features = ["no-entrypoint"] }
2425
spl-token-client = { version = "0.2.1", path = "../client" }

token/program-2022-test/build.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,37 @@ fn rerun_if_changed(directory: &Path) {
3131

3232
fn main() {
3333
let cwd = env::current_dir().expect("Unable to get current working directory");
34+
3435
let spl_token_2022_dir = cwd
3536
.parent()
3637
.expect("Unable to get parent directory of current working dir")
3738
.join("program-2022");
3839
rerun_if_changed(&spl_token_2022_dir);
40+
41+
let instruction_padding_dir = cwd
42+
.parent()
43+
.expect("Unable to get parent directory of current working dir")
44+
.parent()
45+
.expect("Unable to get grandparent directory of current working dir")
46+
.join("instruction-padding")
47+
.join("program");
48+
rerun_if_changed(&instruction_padding_dir);
49+
3950
println!("cargo:rerun-if-changed=build.rs");
4051

41-
let spl_token_2022_toml = spl_token_2022_dir.join("Cargo.toml");
42-
let spl_token_2022_toml = format!("{}", spl_token_2022_toml.display());
43-
let args = vec!["build-sbf", "--manifest-path", &spl_token_2022_toml];
44-
let output = Command::new("cargo")
45-
.args(&args)
46-
.output()
47-
.expect("Error running cargo build-sbf");
48-
if let Ok(output_str) = std::str::from_utf8(&output.stdout) {
49-
let subs = output_str.split('\n');
50-
for sub in subs {
51-
println!("cargo:warning=(not a warning) {}", sub);
52+
for program_dir in [spl_token_2022_dir, instruction_padding_dir] {
53+
let program_toml = program_dir.join("Cargo.toml");
54+
let program_toml = format!("{}", program_toml.display());
55+
let args = vec!["build-sbf", "--manifest-path", &program_toml];
56+
let output = Command::new("cargo")
57+
.args(&args)
58+
.output()
59+
.expect("Error running cargo build-sbf");
60+
if let Ok(output_str) = std::str::from_utf8(&output.stdout) {
61+
let subs = output_str.split('\n');
62+
for sub in subs {
63+
println!("cargo:warning=(not a warning) {}", sub);
64+
}
5265
}
5366
}
5467

0 commit comments

Comments
 (0)