forked from blockworks-foundation/voter-stake-registry
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_voter.rs
88 lines (76 loc) · 3.2 KB
/
create_voter.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use crate::error::*;
use crate::state::*;
use anchor_lang::prelude::*;
use anchor_lang::solana_program::sysvar::instructions as tx_instructions;
use std::mem::size_of;
#[derive(Accounts)]
#[instruction(voter_bump: u8, voter_weight_record_bump: u8)]
pub struct CreateVoter<'info> {
pub registrar: AccountLoader<'info, Registrar>,
#[account(
init,
seeds = [registrar.key().as_ref(), b"voter".as_ref(), voter_authority.key().as_ref()],
bump = voter_bump,
payer = payer,
space = 8 + size_of::<Voter>(),
)]
pub voter: AccountLoader<'info, Voter>,
/// The authority controling the voter. Must be the same as the
/// `governing_token_owner` in the token owner record used with
/// spl-governance.
pub voter_authority: Signer<'info>,
/// The voter weight record is the account that will be shown to spl-governance
/// to prove how much vote weight the voter has. See update_voter_weight_record.
#[account(
init,
seeds = [registrar.key().as_ref(), b"voter-weight-record".as_ref(), voter_authority.key().as_ref()],
bump = voter_weight_record_bump,
payer = payer,
space = size_of::<VoterWeightRecord>(),
)]
pub voter_weight_record: Box<Account<'info, VoterWeightRecord>>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
pub rent: Sysvar<'info, Rent>,
#[account(address = tx_instructions::ID)]
pub instructions: UncheckedAccount<'info>,
}
/// Creates a new voter account. There can only be a single voter per
/// voter_authority.
///
/// The user must register with spl-governance using the same voter_authority.
/// Their token owner record will be required for withdrawing funds later.
pub fn create_voter(
ctx: Context<CreateVoter>,
voter_bump: u8,
voter_weight_record_bump: u8,
) -> Result<()> {
// Forbid creating voter accounts from CPI. The goal is to make automation
// impossible that weakens some of the limitations intentionally imposed on
// locked tokens.
{
let ixns = ctx.accounts.instructions.to_account_info();
let current_index = tx_instructions::load_current_index_checked(&ixns)? as usize;
let current_ixn = tx_instructions::load_instruction_at_checked(current_index, &ixns)?;
require!(
current_ixn.program_id == *ctx.program_id,
ErrorCode::ForbiddenCpi
);
}
// Load accounts.
let registrar = &ctx.accounts.registrar.load()?;
let voter_authority = ctx.accounts.voter_authority.key();
let voter = &mut ctx.accounts.voter.load_init()?;
voter.voter_bump = voter_bump;
voter.voter_weight_record_bump = voter_weight_record_bump;
voter.voter_authority = voter_authority;
voter.registrar = ctx.accounts.registrar.key();
let voter_weight_record = &mut ctx.accounts.voter_weight_record;
voter_weight_record.account_discriminator =
spl_governance_addin_api::voter_weight::VoterWeightRecord::ACCOUNT_DISCRIMINATOR;
voter_weight_record.realm = registrar.realm;
voter_weight_record.governing_token_mint = registrar.realm_governing_token_mint;
voter_weight_record.governing_token_owner = voter_authority;
Ok(())
}