@@ -57,6 +57,26 @@ pub fn check_valid_funding_account(account: &AccountInfo) -> Result<(), ProgramE
57
57
)
58
58
}
59
59
60
+ pub fn valid_signable_account (
61
+ program_id : & Pubkey ,
62
+ account : & AccountInfo ,
63
+ ) -> Result < bool , ProgramError > {
64
+ Ok ( account. is_signer
65
+ && account. is_writable
66
+ && account. owner == program_id
67
+ && get_rent ( ) ?. is_exempt ( account. lamports ( ) , account. data_len ( ) ) )
68
+ }
69
+
70
+ pub fn check_valid_signable_account (
71
+ program_id : & Pubkey ,
72
+ account : & AccountInfo ,
73
+ ) -> Result < ( ) , ProgramError > {
74
+ pyth_assert (
75
+ valid_signable_account ( program_id, account) ?,
76
+ OracleError :: InvalidSignableAccount . into ( ) ,
77
+ )
78
+ }
79
+
60
80
/// Check that `account` is a valid signable pyth account or
61
81
/// that `funding_account` is a signer and is permissioned by the `permission_account`
62
82
pub fn check_permissioned_funding_account (
@@ -80,6 +100,34 @@ pub fn check_permissioned_funding_account(
80
100
check_valid_writable_account ( program_id, account)
81
101
}
82
102
103
+ /// Check that `account` is a valid signable pyth account or
104
+ /// that `funding_account` is a signer and is permissioned by the `permission_account`
105
+ pub fn check_valid_signable_account_or_permissioned_funding_account (
106
+ program_id : & Pubkey ,
107
+ account : & AccountInfo ,
108
+ funding_account : & AccountInfo ,
109
+ permissions_account_option : Option < & AccountInfo > ,
110
+ cmd_hdr : & CommandHeader ,
111
+ ) -> Result < ( ) , ProgramError > {
112
+ if let Some ( permissions_account) = permissions_account_option {
113
+ check_valid_permissions_account ( program_id, permissions_account) ?;
114
+ let permissions_account_data =
115
+ load_checked :: < PermissionAccount > ( permissions_account, cmd_hdr. version ) ?;
116
+ check_valid_funding_account ( funding_account) ?;
117
+ pyth_assert (
118
+ permissions_account_data. is_authorized (
119
+ funding_account. key ,
120
+ OracleCommand :: from_i32 ( cmd_hdr. command )
121
+ . ok_or ( OracleError :: UnrecognizedInstruction ) ?,
122
+ ) ,
123
+ OracleError :: PermissionViolation . into ( ) ,
124
+ ) ?;
125
+ check_valid_writable_account ( program_id, account)
126
+ } else {
127
+ check_valid_signable_account ( program_id, account)
128
+ }
129
+ }
130
+
83
131
/// Returns `true` if the `account` is fresh, i.e., its data can be overwritten.
84
132
/// Use this check to prevent accidentally overwriting accounts whose data is already populated.
85
133
pub fn valid_fresh_account ( account : & AccountInfo ) -> bool {
0 commit comments