squads_multisig_program/
lib.rs

1#![allow(clippy::result_large_err)]
2#![deny(arithmetic_overflow)]
3#![deny(unused_must_use)]
4// #![deny(clippy::arithmetic_side_effects)]
5// #![deny(clippy::integer_arithmetic)]
6
7// Re-export anchor_lang for convenience.
8pub use anchor_lang;
9use anchor_lang::prelude::*;
10#[cfg(not(feature = "no-entrypoint"))]
11use solana_security_txt::security_txt;
12
13pub use instructions::ProgramConfig;
14pub use instructions::*;
15pub use state::*;
16pub use utils::SmallVec;
17
18pub mod errors;
19pub mod instructions;
20pub mod state;
21mod utils;
22
23#[cfg(not(feature = "no-entrypoint"))]
24security_txt! {
25    name: "Squads Multisig Program",
26    project_url: "https://squads.so",
27    contacts: "email:security@sqds.io,email:contact@osec.io",
28    policy: "https://github.com/Squads-Protocol/v4/blob/main/SECURITY.md",
29    preferred_languages: "en",
30    source_code: "https://github.com/squads-protocol/v4",
31    auditors: "OtterSec, Neodyme"
32}
33
34#[cfg(not(feature = "testing"))]
35declare_id!("SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf");
36
37#[cfg(feature = "testing")]
38declare_id!("GyhGAqjokLwF9UXdQ2dR5Zwiup242j4mX4J1tSMKyAmD");
39
40#[program]
41pub mod squads_multisig_program {
42    use super::*;
43
44    /// Initialize the program config.
45    pub fn program_config_init(
46        ctx: Context<ProgramConfigInit>,
47        args: ProgramConfigInitArgs,
48    ) -> Result<()> {
49        ProgramConfigInit::program_config_init(ctx, args)
50    }
51
52    /// Set the `authority` parameter of the program config.
53    pub fn program_config_set_authority(
54        ctx: Context<ProgramConfig>,
55        args: ProgramConfigSetAuthorityArgs,
56    ) -> Result<()> {
57        ProgramConfig::program_config_set_authority(ctx, args)
58    }
59
60    /// Set the `multisig_creation_fee` parameter of the program config.
61    pub fn program_config_set_multisig_creation_fee(
62        ctx: Context<ProgramConfig>,
63        args: ProgramConfigSetMultisigCreationFeeArgs,
64    ) -> Result<()> {
65        ProgramConfig::program_config_set_multisig_creation_fee(ctx, args)
66    }
67
68    /// Set the `treasury` parameter of the program config.
69    pub fn program_config_set_treasury(
70        ctx: Context<ProgramConfig>,
71        args: ProgramConfigSetTreasuryArgs,
72    ) -> Result<()> {
73        ProgramConfig::program_config_set_treasury(ctx, args)
74    }
75
76    /// Create a multisig.
77    #[allow(deprecated)]
78    pub fn multisig_create(ctx: Context<MultisigCreate>, args: MultisigCreateArgs) -> Result<()> {
79        MultisigCreate::multisig_create(ctx, args)
80    }
81
82    /// Create a multisig.
83    pub fn multisig_create_v2(
84        ctx: Context<MultisigCreateV2>,
85        args: MultisigCreateArgsV2,
86    ) -> Result<()> {
87        MultisigCreateV2::multisig_create(ctx, args)
88    }
89
90    /// Add a new member to the controlled multisig.
91    pub fn multisig_add_member(
92        ctx: Context<MultisigConfig>,
93        args: MultisigAddMemberArgs,
94    ) -> Result<()> {
95        MultisigConfig::multisig_add_member(ctx, args)
96    }
97
98    /// Remove a member/key from the controlled multisig.
99    pub fn multisig_remove_member(
100        ctx: Context<MultisigConfig>,
101        args: MultisigRemoveMemberArgs,
102    ) -> Result<()> {
103        MultisigConfig::multisig_remove_member(ctx, args)
104    }
105
106    /// Set the `time_lock` config parameter for the controlled multisig.
107    pub fn multisig_set_time_lock(
108        ctx: Context<MultisigConfig>,
109        args: MultisigSetTimeLockArgs,
110    ) -> Result<()> {
111        MultisigConfig::multisig_set_time_lock(ctx, args)
112    }
113
114    /// Set the `threshold` config parameter for the controlled multisig.
115    pub fn multisig_change_threshold(
116        ctx: Context<MultisigConfig>,
117        args: MultisigChangeThresholdArgs,
118    ) -> Result<()> {
119        MultisigConfig::multisig_change_threshold(ctx, args)
120    }
121
122    /// Set the multisig `config_authority`.
123    pub fn multisig_set_config_authority(
124        ctx: Context<MultisigConfig>,
125        args: MultisigSetConfigAuthorityArgs,
126    ) -> Result<()> {
127        MultisigConfig::multisig_set_config_authority(ctx, args)
128    }
129
130    /// Set the multisig `rent_collector`.
131    pub fn multisig_set_rent_collector(
132        ctx: Context<MultisigConfig>,
133        args: MultisigSetRentCollectorArgs,
134    ) -> Result<()> {
135        MultisigConfig::multisig_set_rent_collector(ctx, args)
136    }
137
138    /// Create a new spending limit for the controlled multisig.
139    pub fn multisig_add_spending_limit(
140        ctx: Context<MultisigAddSpendingLimit>,
141        args: MultisigAddSpendingLimitArgs,
142    ) -> Result<()> {
143        MultisigAddSpendingLimit::multisig_add_spending_limit(ctx, args)
144    }
145
146    /// Remove the spending limit from the controlled multisig.
147    pub fn multisig_remove_spending_limit(
148        ctx: Context<MultisigRemoveSpendingLimit>,
149        args: MultisigRemoveSpendingLimitArgs,
150    ) -> Result<()> {
151        MultisigRemoveSpendingLimit::multisig_remove_spending_limit(ctx, args)
152    }
153
154    /// Create a new config transaction.
155    pub fn config_transaction_create(
156        ctx: Context<ConfigTransactionCreate>,
157        args: ConfigTransactionCreateArgs,
158    ) -> Result<()> {
159        ConfigTransactionCreate::config_transaction_create(ctx, args)
160    }
161
162    /// Execute a config transaction.
163    /// The transaction must be `Approved`.
164    pub fn config_transaction_execute<'info>(
165        ctx: Context<'_, '_, 'info, 'info, ConfigTransactionExecute<'info>>,
166    ) -> Result<()> {
167        ConfigTransactionExecute::config_transaction_execute(ctx)
168    }
169
170    /// Create a new vault transaction.
171    pub fn vault_transaction_create(
172        ctx: Context<VaultTransactionCreate>,
173        args: VaultTransactionCreateArgs,
174    ) -> Result<()> {
175        VaultTransactionCreate::vault_transaction_create(ctx, args)
176    }
177
178    /// Execute a vault transaction.
179    /// The transaction must be `Approved`.
180    pub fn vault_transaction_execute(ctx: Context<VaultTransactionExecute>) -> Result<()> {
181        VaultTransactionExecute::vault_transaction_execute(ctx)
182    }
183
184    /// Create a new batch.
185    pub fn batch_create(ctx: Context<BatchCreate>, args: BatchCreateArgs) -> Result<()> {
186        BatchCreate::batch_create(ctx, args)
187    }
188
189    /// Add a transaction to the batch.
190    pub fn batch_add_transaction(
191        ctx: Context<BatchAddTransaction>,
192        args: BatchAddTransactionArgs,
193    ) -> Result<()> {
194        BatchAddTransaction::batch_add_transaction(ctx, args)
195    }
196
197    /// Execute a transaction from the batch.
198    pub fn batch_execute_transaction(ctx: Context<BatchExecuteTransaction>) -> Result<()> {
199        BatchExecuteTransaction::batch_execute_transaction(ctx)
200    }
201
202    /// Create a new multisig proposal.
203    pub fn proposal_create(ctx: Context<ProposalCreate>, args: ProposalCreateArgs) -> Result<()> {
204        ProposalCreate::proposal_create(ctx, args)
205    }
206
207    /// Update status of a multisig proposal from `Draft` to `Active`.
208    pub fn proposal_activate(ctx: Context<ProposalActivate>) -> Result<()> {
209        ProposalActivate::proposal_activate(ctx)
210    }
211
212    /// Approve a multisig proposal on behalf of the `member`.
213    /// The proposal must be `Active`.
214    pub fn proposal_approve(ctx: Context<ProposalVote>, args: ProposalVoteArgs) -> Result<()> {
215        ProposalVote::proposal_approve(ctx, args)
216    }
217
218    /// Reject a multisig proposal on behalf of the `member`.
219    /// The proposal must be `Active`.
220    pub fn proposal_reject(ctx: Context<ProposalVote>, args: ProposalVoteArgs) -> Result<()> {
221        ProposalVote::proposal_reject(ctx, args)
222    }
223
224    /// Cancel a multisig proposal on behalf of the `member`.
225    /// The proposal must be `Approved`.
226    pub fn proposal_cancel(ctx: Context<ProposalVote>, args: ProposalVoteArgs) -> Result<()> {
227        ProposalVote::proposal_cancel(ctx, args)
228    }
229
230    /// Use a spending limit to transfer tokens from a multisig vault to a destination account.
231    pub fn spending_limit_use(
232        ctx: Context<SpendingLimitUse>,
233        args: SpendingLimitUseArgs,
234    ) -> Result<()> {
235        SpendingLimitUse::spending_limit_use(ctx, args)
236    }
237
238    /// Closes a `ConfigTransaction` and the corresponding `Proposal`.
239    /// `transaction` can be closed if either:
240    /// - the `proposal` is in a terminal state: `Executed`, `Rejected`, or `Cancelled`.
241    /// - the `proposal` is stale.
242    pub fn config_transaction_accounts_close(
243        ctx: Context<ConfigTransactionAccountsClose>,
244    ) -> Result<()> {
245        ConfigTransactionAccountsClose::config_transaction_accounts_close(ctx)
246    }
247
248    /// Closes a `VaultTransaction` and the corresponding `Proposal`.
249    /// `transaction` can be closed if either:
250    /// - the `proposal` is in a terminal state: `Executed`, `Rejected`, or `Cancelled`.
251    /// - the `proposal` is stale and not `Approved`.
252    pub fn vault_transaction_accounts_close(
253        ctx: Context<VaultTransactionAccountsClose>,
254    ) -> Result<()> {
255        VaultTransactionAccountsClose::vault_transaction_accounts_close(ctx)
256    }
257
258    /// Closes a `VaultBatchTransaction` belonging to the `batch` and `proposal`.
259    /// `transaction` can be closed if either:
260    /// - it's marked as executed within the `batch`;
261    /// - the `proposal` is in a terminal state: `Executed`, `Rejected`, or `Cancelled`.
262    /// - the `proposal` is stale and not `Approved`.
263    pub fn vault_batch_transaction_account_close(
264        ctx: Context<VaultBatchTransactionAccountClose>,
265    ) -> Result<()> {
266        VaultBatchTransactionAccountClose::vault_batch_transaction_account_close(ctx)
267    }
268
269    /// Closes Batch and the corresponding Proposal accounts for proposals in terminal states:
270    /// `Executed`, `Rejected`, or `Cancelled` or stale proposals that aren't `Approved`.
271    ///
272    /// This instruction is only allowed to be executed when all `VaultBatchTransaction` accounts
273    /// in the `batch` are already closed: `batch.size == 0`.
274    pub fn batch_accounts_close(ctx: Context<BatchAccountsClose>) -> Result<()> {
275        BatchAccountsClose::batch_accounts_close(ctx)
276    }
277}