2021-10-05 13:40:01 -07:00
|
|
|
use anchor_lang::prelude::*;
|
2021-10-19 15:51:13 -07:00
|
|
|
use error::*;
|
2021-12-02 07:28:12 -08:00
|
|
|
use instructions::*;
|
2021-12-03 00:52:48 -08:00
|
|
|
use state::*;
|
2021-10-18 12:17:39 -07:00
|
|
|
|
2021-10-19 15:51:13 -07:00
|
|
|
mod error;
|
2021-12-02 07:28:12 -08:00
|
|
|
mod instructions;
|
2021-12-02 11:05:36 -08:00
|
|
|
pub mod state;
|
2021-10-05 13:40:01 -07:00
|
|
|
|
2021-12-08 23:22:22 -08:00
|
|
|
#[macro_use]
|
|
|
|
extern crate static_assertions;
|
|
|
|
|
2021-10-20 12:38:47 -07:00
|
|
|
// The program address.
|
2021-12-14 03:47:12 -08:00
|
|
|
declare_id!("4Q6WW2ouZ6V3iaNm56MTd5n2tnTm4C5fiH8miFHnAFHo");
|
2021-10-05 13:40:01 -07:00
|
|
|
|
2021-10-16 09:47:57 -07:00
|
|
|
/// # Introduction
|
|
|
|
///
|
|
|
|
/// The governance registry is an "addin" to the SPL governance program that
|
2021-10-20 12:38:47 -07:00
|
|
|
/// 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.
|
2021-10-16 09:47:57 -07:00
|
|
|
///
|
2021-10-20 12:38:47 -07:00
|
|
|
/// The flow for voting with this program is as follows:
|
2021-10-16 09:47:57 -07:00
|
|
|
///
|
|
|
|
/// - 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.
|
2021-10-20 12:38:47 -07:00
|
|
|
///
|
|
|
|
/// # 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.
|
2021-10-05 13:40:01 -07:00
|
|
|
#[program]
|
2021-12-01 04:28:38 -08:00
|
|
|
pub mod voter_stake_registry {
|
2021-10-05 13:40:01 -07:00
|
|
|
use super::*;
|
|
|
|
|
2021-12-09 02:58:15 -08:00
|
|
|
pub fn create_registrar(ctx: Context<CreateRegistrar>, registrar_bump: u8) -> Result<()> {
|
|
|
|
instructions::create_registrar(ctx, registrar_bump)
|
2021-10-05 13:40:01 -07:00
|
|
|
}
|
|
|
|
|
2021-12-03 11:36:42 -08:00
|
|
|
pub fn configure_voting_mint(
|
|
|
|
ctx: Context<ConfigureVotingMint>,
|
2021-10-20 12:38:47 -07:00
|
|
|
idx: u16,
|
2021-12-09 02:58:15 -08:00
|
|
|
digit_shift: i8,
|
|
|
|
deposit_scaled_factor: u64,
|
|
|
|
lockup_scaled_factor: u64,
|
|
|
|
lockup_saturation_secs: u64,
|
2021-12-05 07:59:22 -08:00
|
|
|
grant_authority: Option<Pubkey>,
|
2021-10-16 09:47:57 -07:00
|
|
|
) -> Result<()> {
|
2021-12-09 02:58:15 -08:00
|
|
|
instructions::configure_voting_mint(
|
|
|
|
ctx,
|
|
|
|
idx,
|
|
|
|
digit_shift,
|
|
|
|
deposit_scaled_factor,
|
|
|
|
lockup_scaled_factor,
|
|
|
|
lockup_saturation_secs,
|
|
|
|
grant_authority,
|
|
|
|
)
|
2021-10-20 12:38:47 -07:00
|
|
|
}
|
|
|
|
|
2021-10-21 19:16:32 -07:00
|
|
|
pub fn create_voter(
|
|
|
|
ctx: Context<CreateVoter>,
|
|
|
|
voter_bump: u8,
|
|
|
|
voter_weight_record_bump: u8,
|
|
|
|
) -> Result<()> {
|
2021-12-02 07:28:12 -08:00
|
|
|
instructions::create_voter(ctx, voter_bump, voter_weight_record_bump)
|
2021-10-05 13:40:01 -07:00
|
|
|
}
|
|
|
|
|
2021-12-02 02:01:14 -08:00
|
|
|
pub fn create_deposit_entry(
|
|
|
|
ctx: Context<CreateDepositEntry>,
|
2021-12-03 00:48:10 -08:00
|
|
|
deposit_entry_index: u8,
|
2021-10-19 15:08:05 -07:00
|
|
|
kind: LockupKind,
|
2021-12-16 05:34:11 -08:00
|
|
|
start_ts: Option<u64>,
|
2021-12-03 02:38:45 -08:00
|
|
|
periods: u32,
|
2021-12-01 01:20:39 -08:00
|
|
|
allow_clawback: bool,
|
2021-10-19 15:08:05 -07:00
|
|
|
) -> Result<()> {
|
2021-12-16 05:34:11 -08:00
|
|
|
instructions::create_deposit_entry(
|
|
|
|
ctx,
|
|
|
|
deposit_entry_index,
|
|
|
|
kind,
|
|
|
|
start_ts,
|
|
|
|
periods,
|
|
|
|
allow_clawback,
|
|
|
|
)
|
2021-10-16 09:47:57 -07:00
|
|
|
}
|
|
|
|
|
2021-12-03 00:07:54 -08:00
|
|
|
pub fn deposit(ctx: Context<Deposit>, deposit_entry_index: u8, amount: u64) -> Result<()> {
|
|
|
|
instructions::deposit(ctx, deposit_entry_index, amount)
|
2021-10-05 13:40:01 -07:00
|
|
|
}
|
|
|
|
|
2021-12-04 00:22:22 -08:00
|
|
|
pub fn withdraw(ctx: Context<Withdraw>, deposit_entry_index: u8, amount: u64) -> Result<()> {
|
2021-12-03 00:07:54 -08:00
|
|
|
instructions::withdraw(ctx, deposit_entry_index, amount)
|
2021-12-02 07:28:12 -08:00
|
|
|
}
|
2021-10-16 09:47:57 -07:00
|
|
|
|
2021-12-05 07:59:22 -08:00
|
|
|
pub fn grant(
|
|
|
|
ctx: Context<Grant>,
|
|
|
|
voter_bump: u8,
|
|
|
|
voter_weight_record_bump: u8,
|
|
|
|
kind: LockupKind,
|
2021-12-16 05:34:11 -08:00
|
|
|
start_ts: Option<u64>,
|
2021-12-05 07:59:22 -08:00
|
|
|
periods: u32,
|
|
|
|
allow_clawback: bool,
|
|
|
|
amount: u64,
|
|
|
|
) -> Result<()> {
|
|
|
|
instructions::grant(
|
|
|
|
ctx,
|
|
|
|
voter_bump,
|
|
|
|
voter_weight_record_bump,
|
|
|
|
kind,
|
2021-12-16 05:34:11 -08:00
|
|
|
start_ts,
|
2021-12-05 07:59:22 -08:00
|
|
|
periods,
|
|
|
|
allow_clawback,
|
|
|
|
amount,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-12-04 00:22:22 -08:00
|
|
|
pub fn clawback(ctx: Context<Clawback>, deposit_entry_index: u8) -> Result<()> {
|
2021-12-03 00:07:54 -08:00
|
|
|
instructions::clawback(ctx, deposit_entry_index)
|
2021-10-12 12:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-12-03 00:07:54 -08:00
|
|
|
pub fn close_deposit_entry(
|
|
|
|
ctx: Context<CloseDepositEntry>,
|
|
|
|
deposit_entry_index: u8,
|
|
|
|
) -> Result<()> {
|
|
|
|
instructions::close_deposit_entry(ctx, deposit_entry_index)
|
2021-11-30 02:49:59 -08:00
|
|
|
}
|
|
|
|
|
2021-12-03 00:07:54 -08:00
|
|
|
pub fn reset_lockup(
|
|
|
|
ctx: Context<ResetLockup>,
|
|
|
|
deposit_entry_index: u8,
|
2021-12-10 03:46:45 -08:00
|
|
|
kind: LockupKind,
|
2021-12-03 02:38:45 -08:00
|
|
|
periods: u32,
|
2021-12-03 00:07:54 -08:00
|
|
|
) -> Result<()> {
|
2021-12-10 03:46:45 -08:00
|
|
|
instructions::reset_lockup(ctx, deposit_entry_index, kind, periods)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn internal_transfer(
|
|
|
|
ctx: Context<InternalTransfer>,
|
|
|
|
source_deposit_entry_index: u8,
|
|
|
|
target_deposit_entry_index: u8,
|
|
|
|
amount: u64,
|
|
|
|
) -> Result<()> {
|
|
|
|
instructions::internal_transfer(
|
|
|
|
ctx,
|
|
|
|
source_deposit_entry_index,
|
|
|
|
target_deposit_entry_index,
|
|
|
|
amount,
|
|
|
|
)
|
2021-10-05 13:40:01 -07:00
|
|
|
}
|
2021-10-14 11:31:52 -07:00
|
|
|
|
2021-10-21 19:16:32 -07:00
|
|
|
pub fn update_voter_weight_record(ctx: Context<UpdateVoterWeightRecord>) -> Result<()> {
|
2021-12-02 07:28:12 -08:00
|
|
|
instructions::update_voter_weight_record(ctx)
|
2021-10-14 11:31:52 -07:00
|
|
|
}
|
|
|
|
|
2021-12-02 07:28:12 -08:00
|
|
|
pub fn update_max_vote_weight<'info>(ctx: Context<UpdateMaxVoteWeight>) -> Result<()> {
|
|
|
|
instructions::update_max_vote_weight(ctx)
|
2021-10-23 16:05:21 -07:00
|
|
|
}
|
|
|
|
|
2021-10-14 11:31:52 -07:00
|
|
|
pub fn close_voter(ctx: Context<CloseVoter>) -> Result<()> {
|
2021-12-02 07:28:12 -08:00
|
|
|
instructions::close_voter(ctx)
|
2021-10-14 11:31:52 -07:00
|
|
|
}
|
2021-11-29 06:56:45 -08:00
|
|
|
|
|
|
|
pub fn set_time_offset(ctx: Context<SetTimeOffset>, time_offset: i64) -> Result<()> {
|
2021-12-02 07:28:12 -08:00
|
|
|
instructions::set_time_offset(ctx, time_offset)
|
2021-11-29 06:56:45 -08:00
|
|
|
}
|
2021-10-05 13:40:01 -07:00
|
|
|
}
|