2021-12-02 07:28:12 -08:00
|
|
|
use crate::error::*;
|
2021-12-03 00:52:48 -08:00
|
|
|
use crate::state::*;
|
2021-12-02 07:28:12 -08:00
|
|
|
use anchor_lang::prelude::*;
|
2021-12-16 23:02:14 -08:00
|
|
|
use anchor_spl::associated_token::AssociatedToken;
|
|
|
|
use anchor_spl::token::{Mint, Token, TokenAccount};
|
2021-12-16 05:34:11 -08:00
|
|
|
use std::convert::TryFrom;
|
2021-12-02 07:28:12 -08:00
|
|
|
|
|
|
|
#[derive(Accounts)]
|
|
|
|
pub struct CreateDepositEntry<'info> {
|
2021-12-08 23:22:22 -08:00
|
|
|
pub registrar: AccountLoader<'info, Registrar>,
|
2021-12-02 07:28:12 -08:00
|
|
|
|
2021-12-04 00:02:20 -08:00
|
|
|
// checking the PDA address it just an extra precaution,
|
|
|
|
// the other constraints must be exhaustive
|
|
|
|
#[account(
|
|
|
|
mut,
|
2021-12-04 00:22:22 -08:00
|
|
|
seeds = [registrar.key().as_ref(), b"voter".as_ref(), voter_authority.key().as_ref()],
|
2021-12-04 00:02:20 -08:00
|
|
|
bump = voter.load()?.voter_bump,
|
|
|
|
has_one = registrar,
|
|
|
|
has_one = voter_authority)]
|
2021-12-02 07:28:12 -08:00
|
|
|
pub voter: AccountLoader<'info, Voter>,
|
2021-12-16 23:02:14 -08:00
|
|
|
|
|
|
|
#[account(
|
|
|
|
init_if_needed,
|
|
|
|
associated_token::authority = voter,
|
|
|
|
associated_token::mint = deposit_mint,
|
|
|
|
payer = payer
|
|
|
|
)]
|
|
|
|
pub vault: Box<Account<'info, TokenAccount>>,
|
|
|
|
|
2021-12-02 07:28:12 -08:00
|
|
|
pub voter_authority: Signer<'info>,
|
|
|
|
|
2021-12-16 23:02:14 -08:00
|
|
|
#[account(mut)]
|
|
|
|
pub payer: Signer<'info>,
|
|
|
|
|
2021-12-02 07:28:12 -08:00
|
|
|
pub deposit_mint: Box<Account<'info, Mint>>,
|
2021-12-16 23:02:14 -08:00
|
|
|
|
|
|
|
pub system_program: Program<'info, System>,
|
|
|
|
pub token_program: Program<'info, Token>,
|
|
|
|
pub associated_token_program: Program<'info, AssociatedToken>,
|
|
|
|
pub rent: Sysvar<'info, Rent>,
|
2021-12-02 07:28:12 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a new deposit entry.
|
2021-12-02 12:30:15 -08:00
|
|
|
///
|
2021-12-03 00:48:10 -08:00
|
|
|
/// Initializes a deposit entry with the requested settings.
|
|
|
|
/// Will error if the deposit entry is already in use.
|
2021-12-02 12:30:15 -08:00
|
|
|
///
|
2021-12-16 05:34:11 -08:00
|
|
|
/// - `deposit_entry_index`: deposit entry to use
|
|
|
|
/// - `kind`: Type of lockup to use.
|
2022-01-20 23:15:33 -08:00
|
|
|
/// - `start_ts`: Start timestamp in seconds, defaults to current clock.
|
2021-12-16 05:34:11 -08:00
|
|
|
/// The lockup will end after `start + periods * period_secs()`.
|
|
|
|
///
|
|
|
|
/// Note that tokens will already be locked before start_ts, it only defines
|
|
|
|
/// the vesting start time and the anchor for the periods computation.
|
|
|
|
///
|
|
|
|
/// - `periods`: How long to lock up, depending on `kind`. See LockupKind::period_secs()
|
2021-12-20 02:01:23 -08:00
|
|
|
/// - `allow_clawback`: When enabled, the the realm_authority is allowed to
|
2021-12-16 05:34:11 -08:00
|
|
|
/// unilaterally claim locked tokens.
|
2021-12-02 07:28:12 -08:00
|
|
|
pub fn create_deposit_entry(
|
|
|
|
ctx: Context<CreateDepositEntry>,
|
2021-12-03 00:48:10 -08:00
|
|
|
deposit_entry_index: u8,
|
2021-12-02 07:28:12 -08: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-02 07:28:12 -08:00
|
|
|
allow_clawback: bool,
|
|
|
|
) -> Result<()> {
|
|
|
|
// Load accounts.
|
2021-12-08 23:22:22 -08:00
|
|
|
let registrar = &ctx.accounts.registrar.load()?;
|
2021-12-02 07:28:12 -08:00
|
|
|
let voter = &mut ctx.accounts.voter.load_mut()?;
|
|
|
|
|
|
|
|
// Get the exchange rate entry associated with this deposit.
|
2021-12-03 11:36:42 -08:00
|
|
|
let mint_idx = registrar.voting_mint_config_index(ctx.accounts.deposit_mint.key())?;
|
2021-12-02 07:28:12 -08:00
|
|
|
|
2021-12-03 00:48:10 -08:00
|
|
|
// Get and set up the deposit entry.
|
|
|
|
require!(
|
|
|
|
voter.deposits.len() > deposit_entry_index as usize,
|
2021-12-03 07:06:44 -08:00
|
|
|
OutOfBoundsDepositEntryIndex
|
2021-12-03 00:48:10 -08:00
|
|
|
);
|
|
|
|
let d_entry = &mut voter.deposits[deposit_entry_index as usize];
|
2021-12-03 07:06:44 -08:00
|
|
|
require!(!d_entry.is_used, UnusedDepositEntryIndex);
|
2021-12-03 00:48:10 -08:00
|
|
|
|
2022-01-20 23:15:33 -08:00
|
|
|
let curr_ts = registrar.clock_unix_timestamp();
|
2021-12-16 05:34:11 -08:00
|
|
|
let start_ts = if let Some(v) = start_ts {
|
|
|
|
i64::try_from(v).unwrap()
|
|
|
|
} else {
|
2022-01-20 23:15:33 -08:00
|
|
|
curr_ts
|
2021-12-16 05:34:11 -08:00
|
|
|
};
|
|
|
|
|
2021-12-03 00:48:10 -08:00
|
|
|
*d_entry = DepositEntry::default();
|
2021-12-02 07:28:12 -08:00
|
|
|
d_entry.is_used = true;
|
2021-12-03 11:36:42 -08:00
|
|
|
d_entry.voting_mint_config_idx = mint_idx as u8;
|
2021-12-02 07:28:12 -08:00
|
|
|
d_entry.amount_deposited_native = 0;
|
|
|
|
d_entry.amount_initially_locked_native = 0;
|
|
|
|
d_entry.allow_clawback = allow_clawback;
|
2022-01-20 23:15:33 -08:00
|
|
|
d_entry.lockup = Lockup::new_from_periods(kind, curr_ts, start_ts, periods)?;
|
2021-12-02 07:28:12 -08:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|