squads_multisig_program/instructions/
proposal_activate.rs1use anchor_lang::prelude::*;
2
3use crate::errors::*;
4use crate::state::*;
5
6#[derive(Accounts)]
7pub struct ProposalActivate<'info> {
8 #[account(
9 seeds = [SEED_PREFIX, SEED_MULTISIG, multisig.create_key.as_ref()],
10 bump = multisig.bump,
11 )]
12 pub multisig: Account<'info, Multisig>,
13
14 #[account(mut)]
15 pub member: Signer<'info>,
16
17 #[account(
18 mut,
19 seeds = [
20 SEED_PREFIX,
21 multisig.key().as_ref(),
22 SEED_TRANSACTION,
23 &proposal.transaction_index.to_le_bytes(),
24 SEED_PROPOSAL,
25 ],
26 bump = proposal.bump,
27 )]
28 pub proposal: Account<'info, Proposal>,
29}
30
31impl ProposalActivate<'_> {
32 fn validate(&self) -> Result<()> {
33 let Self {
34 multisig,
35 proposal,
36 member,
37 ..
38 } = self;
39
40 require!(
42 multisig.is_member(member.key()).is_some(),
43 MultisigError::NotAMember
44 );
45 require!(
46 multisig.member_has_permission(member.key(), Permission::Initiate),
48 MultisigError::Unauthorized
49 );
50
51 require!(
53 matches!(proposal.status, ProposalStatus::Draft { .. }),
54 MultisigError::InvalidProposalStatus
55 );
56 require!(
57 proposal.transaction_index > multisig.stale_transaction_index,
58 MultisigError::StaleProposal
59 );
60
61 Ok(())
62 }
63
64 #[access_control(ctx.accounts.validate())]
66 pub fn proposal_activate(ctx: Context<Self>) -> Result<()> {
67 ctx.accounts.proposal.status = ProposalStatus::Active {
68 timestamp: Clock::get()?.unix_timestamp,
69 };
70
71 Ok(())
72 }
73}