Skip to content

Commit cf136e7

Browse files
authored
p-token: Add explicitly ownership checks in batch (#80)
* Add transfer account owner checks * Add batch transfer tests * Update dependencies * Fix lint * Add more ownership checks * More tests * Typos
1 parent beeb441 commit cf136e7

File tree

6 files changed

+608
-4
lines changed

6 files changed

+608
-4
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ tag-message = "Publish {{crate_name}} v{{version}}"
3333
consolidate-commits = false
3434

3535
[workspace.dependencies]
36+
mollusk-svm = "0.4.0"
37+
mollusk-svm-fuzz-fixture = "0.4.0"
3638
num-traits = "0.2"
3739
pinocchio = "0.9"
3840
solana-instruction = "2.3.0"

p-token/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,21 @@ pinocchio-log = { version = "0.5", default-features = false }
2020
pinocchio-token-interface = { version = "^0", path = "../p-interface" }
2121

2222
[dev-dependencies]
23+
agave-feature-set = "2.2.20"
2324
assert_matches = "1.5.0"
25+
mollusk-svm = { workspace = true }
26+
mollusk-svm-fuzz-fixture = { workspace = true }
2427
num-traits = { workspace = true }
28+
solana-account = "2.2.1"
2529
solana-instruction = { workspace = true }
2630
solana-keypair = "2.2.3"
2731
solana-program-error = { workspace = true }
2832
solana-program-option = { workspace = true }
2933
solana-program-pack = { workspace = true }
3034
solana-program-test = "2.3.4"
3135
solana-pubkey = { workspace = true }
36+
solana-rent = "2.2.1"
37+
solana-sdk-ids = "2.2.1"
3238
solana-signature = "2.3.0"
3339
solana-signer = "2.2.1"
3440
solana-transaction = "2.2.3"

p-token/src/processor/batch.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use {
2-
crate::entrypoint::inner_process_instruction,
2+
crate::{entrypoint::inner_process_instruction, processor::check_account_owner},
33
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
44
pinocchio_token_interface::error::TokenError,
55
};
@@ -46,6 +46,54 @@ pub fn process_batch(mut accounts: &[AccountInfo], mut instruction_data: &[u8])
4646
)
4747
};
4848

49+
// Few Instructions require specific account ownership checks when executed
50+
// in a batch since ownership is only enforced by the runtime at the end of
51+
// the batch processing.
52+
//
53+
// Instructions that do not appear in the list below do not require
54+
// ownership checks since they either do not modify accounts or the ownership
55+
// is already checked explicitly.
56+
if let Some(&discriminator) = ix_data.first() {
57+
match discriminator {
58+
// 3 - Transfer
59+
// 7 - MintTo
60+
// 8 - Burn
61+
// 14 - MintToChecked
62+
// 15 - BurnChecked
63+
3 | 7 | 8 | 14 | 15 => {
64+
let [a0, a1, ..] = ix_accounts else {
65+
return Err(ProgramError::NotEnoughAccountKeys);
66+
};
67+
check_account_owner(a0)?;
68+
check_account_owner(a1)?;
69+
}
70+
// 12 - TransferChecked
71+
12 => {
72+
let [a0, _, a2, ..] = ix_accounts else {
73+
return Err(ProgramError::NotEnoughAccountKeys);
74+
};
75+
check_account_owner(a0)?;
76+
check_account_owner(a2)?;
77+
}
78+
// 4 - Approve
79+
// 5 - Revoke
80+
// 6 - SetAuthority
81+
// 9 - CloseAccount
82+
// 10 - FreezeAccount
83+
// 11 - ThawAccount
84+
// 13 - ApproveChecked
85+
// 22 - InitializeImmutableOwner
86+
// 38 - WithdrawExcessLamports
87+
4..=13 | 22 | 38 => {
88+
let [a0, ..] = ix_accounts else {
89+
return Err(ProgramError::NotEnoughAccountKeys);
90+
};
91+
check_account_owner(a0)?;
92+
}
93+
_ => {}
94+
}
95+
}
96+
4997
inner_process_instruction(ix_accounts, ix_data)?;
5098

5199
if data_offset == instruction_data.len() {

0 commit comments

Comments
 (0)