1#![deny(rustdoc::all)]
3#![allow(rustdoc::missing_doc_code_examples)]
4#![deny(clippy::unwrap_used)]
5
6pub mod macros;
7
8use anchor_lang::prelude::*;
9use anchor_spl::token::{Mint, Token, TokenAccount};
10use govern::{Governor, Proposal, Vote};
11use vipers::prelude::*;
12
13mod instructions;
14pub mod locker;
15mod state;
16
17pub use instructions::*;
18pub use state::*;
19
20declare_id!("LocktDzaV1W2Bm9DeZeiyz4J9zs4fRqNiYqQyracRXw");
21
22#[deny(missing_docs)]
24#[program]
25pub mod locked_voter {
26 use super::*;
27
28 #[access_control(ctx.accounts.validate())]
30 pub fn new_locker(ctx: Context<NewLocker>, _bump: u8, params: LockerParams) -> Result<()> {
31 ctx.accounts.new_locker(unwrap_bump!(ctx, "locker"), params)
32 }
33
34 #[access_control(ctx.accounts.validate())]
40 pub fn new_escrow(ctx: Context<NewEscrow>, _bump: u8) -> Result<()> {
41 ctx.accounts.new_escrow(unwrap_bump!(ctx, "escrow"))
42 }
43
44 #[access_control(ctx.accounts.validate())]
48 pub fn lock<'info>(
49 ctx: Context<'_, '_, '_, 'info, Lock<'info>>,
50 amount: u64,
51 duration: i64,
52 ) -> Result<()> {
53 msg!("Warning: this instruction is deprecated in favor of `lock_with_whitelist`, `lock_with_whitelist_entry`, or `lock_permissionless`. Please update your Tribeca SDK.");
54 if ctx.accounts.locker.params.whitelist_enabled {
55 ctx.accounts.check_whitelisted(ctx.remaining_accounts)?;
56 }
57 ctx.accounts.lock(amount, duration)
58 }
59
60 #[access_control(ctx.accounts.validate())]
62 pub fn lock_with_whitelist<'info>(
63 ctx: Context<'_, '_, '_, 'info, LockWithWhitelist<'info>>,
64 amount: u64,
65 duration: i64,
66 ) -> Result<()> {
67 instructions::lock_with_whitelist::handler(ctx, amount, duration)
68 }
69
70 #[access_control(ctx.accounts.validate())]
72 pub fn lock_with_whitelist_entry<'info>(
73 ctx: Context<'_, '_, '_, 'info, LockWithWhitelistEntry<'info>>,
74 amount: u64,
75 duration: i64,
76 ) -> Result<()> {
77 instructions::lock_with_whitelist_entry::handler(ctx, amount, duration)
78 }
79
80 #[access_control(ctx.accounts.validate())]
82 pub fn lock_permissionless<'info>(
83 ctx: Context<'_, '_, '_, 'info, Lock<'info>>,
84 amount: u64,
85 duration: i64,
86 ) -> Result<()> {
87 instructions::lock_permissionless::handler(ctx, amount, duration)
88 }
89
90 #[access_control(ctx.accounts.validate())]
92 pub fn exit(ctx: Context<Exit>) -> Result<()> {
93 ctx.accounts.exit()
94 }
95
96 #[access_control(ctx.accounts.validate())]
98 pub fn activate_proposal(ctx: Context<ActivateProposal>) -> Result<()> {
99 ctx.accounts.activate_proposal()
100 }
101
102 #[access_control(ctx.accounts.validate())]
104 pub fn cast_vote(ctx: Context<CastVote>, side: u8) -> Result<()> {
105 ctx.accounts.cast_vote(side)
106 }
107
108 #[access_control(ctx.accounts.validate())]
110 pub fn set_vote_delegate(ctx: Context<SetVoteDelegate>, new_delegate: Pubkey) -> Result<()> {
111 ctx.accounts.set_vote_delegate(new_delegate)
112 }
113
114 #[access_control(ctx.accounts.validate())]
116 pub fn set_locker_params(ctx: Context<SetLockerParams>, params: LockerParams) -> Result<()> {
117 ctx.accounts.set_locker_params(params)
118 }
119
120 #[access_control(ctx.accounts.validate())]
122 pub fn approve_program_lock_privilege(
123 ctx: Context<ApproveProgramLockPrivilege>,
124 _bump: u8,
125 ) -> Result<()> {
126 ctx.accounts
127 .approve_program_lock_privilege(unwrap_bump!(ctx, "whitelist_entry"))
128 }
129
130 #[access_control(ctx.accounts.validate())]
132 pub fn revoke_program_lock_privilege(ctx: Context<RevokeProgramLockPrivilege>) -> Result<()> {
133 ctx.accounts.revoke_program_lock_privilege()
134 }
135}
136
137#[error_code]
139pub enum ErrorCode {
140 #[msg("CPI caller not whitelisted to invoke lock instruction.")]
141 ProgramNotWhitelisted,
142 #[msg("Lockup duration must at least be the min stake duration.")]
143 LockupDurationTooShort,
144 #[msg("Lockup duration must at most be the max stake duration.")]
145 LockupDurationTooLong,
146 #[msg("A voting escrow refresh cannot shorten the escrow time remaining.")]
147 RefreshCannotShorten,
148 #[msg("Escrow has not ended.")]
149 EscrowNotEnded,
150 #[msg("Program whitelist enabled; please provide whitelist entry and instructions sysvar or use the 'lock_with_whitelist' instruction.")]
151 MustProvideWhitelist,
152 #[msg("CPI caller not whitelisted for escrow owner to invoke lock instruction.")]
153 EscrowOwnerNotWhitelisted,
154 #[msg("Must call `lock_with_whitelist_entry` to lock via CPI.")]
155 MustCallLockWithWhitelistEntry,
156 #[msg("Must call `lock_permissionless` since this DAO does not have a CPI whitelist.")]
157 MustCallLockPermissionless,
158}