#![allow(clippy::result_large_err)] use anchor_lang::prelude::*; use instructions::*; use state::*; mod error; pub mod events; mod governance; mod instructions; pub mod state; #[macro_use] extern crate static_assertions; // The program address. declare_id!("4Q6WW2ouZ6V3iaNm56MTd5n2tnTm4C5fiH8miFHnAFHo"); /// # Introduction /// /// The governance registry is an "addin" to the SPL governance program that /// allows one to both vote with many different ypes of tokens for voting and to /// scale voting power as a linear function of time locked--subject to some /// maximum upper bound. /// /// The flow for voting with this program is as follows: /// /// - Create a SPL governance realm. /// - Create a governance registry account. /// - Add exchange rates for any tokens one wants to deposit. For example, /// if one wants to vote with tokens A and B, where token B has twice the /// voting power of token A, then the exchange rate of B would be 2 and the /// exchange rate of A would be 1. /// - Create a voter account. /// - Deposit tokens into this program, with an optional lockup period. /// - Vote. /// /// Upon voting with SPL governance, a client is expected to call /// `decay_voting_power` to get an up to date measurement of a given `Voter`'s /// voting power for the given slot. If this is not done, then the transaction /// will fail (since the SPL governance program will require the measurement /// to be active for the current slot). /// /// # Interacting with SPL Governance /// /// This program does not directly interact with SPL governance via CPI. /// Instead, it simply writes a `VoterWeightRecord` account with a well defined /// format, which is then used by SPL governance as the voting power measurement /// for a given user. /// /// # Max Vote Weight /// /// Given that one can use multiple tokens to vote, the max vote weight needs /// to be a function of the total supply of all tokens, converted into a common /// currency. For example, if you have Token A and Token B, where 1 Token B = /// 10 Token A, then the `max_vote_weight` should be `supply(A) + supply(B)*10` /// where both are converted into common decimals. Then, when calculating the /// weight of an individual voter, one can convert B into A via the given /// exchange rate, which must be fixed. /// /// Note that the above also implies that the `max_vote_weight` must fit into /// a u64. #[program] pub mod voter_stake_registry { use super::*; pub fn create_registrar(ctx: Context, registrar_bump: u8) -> Result<()> { instructions::create_registrar(ctx, registrar_bump) } pub fn configure_voting_mint( ctx: Context, idx: u16, digit_shift: i8, baseline_vote_weight_scaled_factor: u64, max_extra_lockup_vote_weight_scaled_factor: u64, lockup_saturation_secs: u64, grant_authority: Option, ) -> Result<()> { instructions::configure_voting_mint( ctx, idx, digit_shift, baseline_vote_weight_scaled_factor, max_extra_lockup_vote_weight_scaled_factor, lockup_saturation_secs, grant_authority, ) } pub fn create_voter( ctx: Context, voter_bump: u8, voter_weight_record_bump: u8, ) -> Result<()> { instructions::create_voter(ctx, voter_bump, voter_weight_record_bump) } pub fn create_deposit_entry( ctx: Context, deposit_entry_index: u8, kind: LockupKind, start_ts: Option, periods: u32, allow_clawback: bool, ) -> Result<()> { instructions::create_deposit_entry( ctx, deposit_entry_index, kind, start_ts, periods, allow_clawback, ) } pub fn deposit(ctx: Context, deposit_entry_index: u8, amount: u64) -> Result<()> { instructions::deposit(ctx, deposit_entry_index, amount) } pub fn withdraw(ctx: Context, deposit_entry_index: u8, amount: u64) -> Result<()> { instructions::withdraw(ctx, deposit_entry_index, amount) } #[allow(clippy::too_many_arguments)] pub fn grant( ctx: Context, voter_bump: u8, voter_weight_record_bump: u8, kind: LockupKind, start_ts: Option, periods: u32, allow_clawback: bool, amount: u64, ) -> Result<()> { instructions::grant( ctx, voter_bump, voter_weight_record_bump, kind, start_ts, periods, allow_clawback, amount, ) } pub fn clawback(ctx: Context, deposit_entry_index: u8) -> Result<()> { instructions::clawback(ctx, deposit_entry_index) } pub fn close_deposit_entry( ctx: Context, deposit_entry_index: u8, ) -> Result<()> { instructions::close_deposit_entry(ctx, deposit_entry_index) } pub fn reset_lockup( ctx: Context, deposit_entry_index: u8, kind: LockupKind, periods: u32, ) -> Result<()> { instructions::reset_lockup(ctx, deposit_entry_index, kind, periods) } pub fn internal_transfer_locked( ctx: Context, source_deposit_entry_index: u8, target_deposit_entry_index: u8, amount: u64, ) -> Result<()> { instructions::internal_transfer_locked( ctx, source_deposit_entry_index, target_deposit_entry_index, amount, ) } pub fn internal_transfer_unlocked( ctx: Context, source_deposit_entry_index: u8, target_deposit_entry_index: u8, amount: u64, ) -> Result<()> { instructions::internal_transfer_unlocked( ctx, source_deposit_entry_index, target_deposit_entry_index, amount, ) } pub fn update_voter_weight_record(ctx: Context) -> Result<()> { instructions::update_voter_weight_record(ctx) } pub fn update_max_vote_weight(ctx: Context) -> Result<()> { instructions::update_max_vote_weight(ctx) } pub fn close_voter<'key, 'accounts, 'remaining, 'info>( ctx: Context<'key, 'accounts, 'remaining, 'info, CloseVoter<'info>>, ) -> Result<()> { instructions::close_voter(ctx) } pub fn log_voter_info( ctx: Context, deposit_entry_begin: u8, deposit_entry_count: u8, ) -> Result<()> { instructions::log_voter_info(ctx, deposit_entry_begin, deposit_entry_count) } pub fn set_time_offset(ctx: Context, time_offset: i64) -> Result<()> { instructions::set_time_offset(ctx, time_offset) } }