|
| 1 | +use crate::error::TokenHaverError; |
| 2 | +use crate::state::*; |
| 3 | +use anchor_lang::system_program::Transfer; |
| 4 | +use anchor_lang::{prelude::*, system_program}; |
| 5 | +use spl_governance::state::realm; |
| 6 | + |
| 7 | +/// Configures mints for Registrar |
| 8 | +#[derive(Accounts)] |
| 9 | +#[instruction(mints: Vec<Pubkey>)] |
| 10 | +pub struct ConfigureMints<'info> { |
| 11 | + /// The Registrar for the given realm and governing_token_mint |
| 12 | + #[account(mut)] |
| 13 | + pub registrar: Account<'info, Registrar>, |
| 14 | + |
| 15 | + #[account( |
| 16 | + address = registrar.realm @ TokenHaverError::InvalidRealmForRegistrar, |
| 17 | + owner = registrar.governance_program_id |
| 18 | + )] |
| 19 | + /// CHECK: Owned by spl-governance instance specified in registrar.governance_program_id |
| 20 | + pub realm: UncheckedAccount<'info>, |
| 21 | + |
| 22 | + // will pay in the event of a resize |
| 23 | + pub payer: Signer<'info>, |
| 24 | + |
| 25 | + /// Authority of the Realm must sign and match realm.authority |
| 26 | + pub realm_authority: Signer<'info>, |
| 27 | + |
| 28 | + pub system_program: Program<'info, System>, |
| 29 | +} |
| 30 | + |
| 31 | +pub fn configure_mints(ctx: Context<ConfigureMints>, mints: Vec<Pubkey>) -> Result<()> { |
| 32 | + let new_size = Registrar::get_space(mints.len() as u8); |
| 33 | + |
| 34 | + let rent = Rent::get()?; |
| 35 | + let new_minimum_balance = rent.minimum_balance(new_size); |
| 36 | + |
| 37 | + let lamports_diff = |
| 38 | + new_minimum_balance.saturating_sub(ctx.accounts.registrar.to_account_info().lamports()); |
| 39 | + |
| 40 | + // if lamports_diff is positive, we need to fund the account |
| 41 | + if lamports_diff > 0 { |
| 42 | + // Create a CPI context for the transfer |
| 43 | + let cpi_accounts = Transfer { |
| 44 | + from: ctx.accounts.payer.to_account_info().clone(), |
| 45 | + to: ctx.accounts.registrar.to_account_info().clone(), |
| 46 | + }; |
| 47 | + |
| 48 | + let cpi_program = ctx.accounts.system_program.to_account_info(); |
| 49 | + let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); |
| 50 | + |
| 51 | + // Perform the transfer |
| 52 | + system_program::transfer(cpi_ctx, lamports_diff)?; |
| 53 | + } |
| 54 | + |
| 55 | + let registrar = &mut ctx.accounts.registrar; |
| 56 | + registrar.to_account_info().realloc(new_size, false)?; |
| 57 | + |
| 58 | + registrar.mints = mints; |
| 59 | + |
| 60 | + let realm = realm::get_realm_data_for_governing_token_mint( |
| 61 | + ®istrar.governance_program_id, |
| 62 | + &ctx.accounts.realm, |
| 63 | + ®istrar.governing_token_mint, |
| 64 | + )?; |
| 65 | + |
| 66 | + require_eq!( |
| 67 | + realm.authority.unwrap(), |
| 68 | + ctx.accounts.realm_authority.key(), |
| 69 | + TokenHaverError::InvalidRealmAuthority |
| 70 | + ); |
| 71 | + |
| 72 | + Ok(()) |
| 73 | +} |
0 commit comments