Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MTG-758] [MTG-802] Rectify close_voter ix #41

Merged
merged 5 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defaults:
jobs:
lint:
name: Linter
runs-on: ubuntu-latest
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -50,13 +50,13 @@ jobs:

tests:
name: Tests
runs-on: ubuntu-latest
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4

- name: Install Linux dependencies
run: sudo apt-get update && sudo apt-get install -y pkg-config build-essential libudev-dev
run: sudo apt-get update && sudo apt-get install -y pkg-config build-essential libudev-dev libssl-dev

- name: Install stable Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
Expand Down Expand Up @@ -90,4 +90,4 @@ jobs:
echo "debug = 0" >> Cargo.toml

- name: Run tests
run: cargo test-bpf
run: cargo test-sbf
4 changes: 2 additions & 2 deletions program-states/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,6 @@ pub enum MplStakingError {
#[msg("Cannot deserialize an account")]
DeserializationError,
// 6042 / 0x179a
#[msg("Invalid governing token mint")]
InvalidGoverningTokenMint,
#[msg("Invalid associated token accounts, they should match the number mint configs of a registrar")]
InvalidAssoctiatedTokenAccounts,
}
4 changes: 3 additions & 1 deletion program-states/src/state/registrar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ impl Registrar {
if !voting_mint_config.in_use() {
return Ok(sum);
}

let mint_account = mint_accounts
.iter()
.find(|a| a.key() == voting_mint_config.mint)
.find(|mint_account| mint_account.key() == voting_mint_config.mint)
.ok_or_else(|| error!(MplStakingError::VotingMintNotFound))?;

let mint = Account::<Mint>::try_from(mint_account)?;
sum = sum
.checked_add(mint.supply)
Expand Down
53 changes: 33 additions & 20 deletions programs/voter-stake-registry/src/instructions/close_voter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::cpi_instructions;
use anchor_lang::prelude::*;
use anchor_lang::{prelude::*, system_program};
use anchor_spl::token::{self, CloseAccount, Token, TokenAccount};
use bytemuck::bytes_of_mut;
use mplx_staking_states::{
Expand Down Expand Up @@ -67,16 +67,24 @@ pub struct CloseVoter<'info> {
/// the length of those accounts should be equal to the number of mint configs in the registrar.
pub fn close_voter<'info>(ctx: Context<'_, '_, '_, 'info, CloseVoter<'info>>) -> Result<()> {
let registrar = ctx.accounts.registrar.load()?;
let filtered_mints = registrar
.voting_mints
.iter()
.filter(|mint_config| mint_config.mint != Pubkey::default())
.collect::<Vec<_>>();

require!(
ctx.accounts.rewards_program.key() == registrar.rewards_program,
MplStakingError::InvalidRewardsProgram
);

require!(
registrar.reward_pool == ctx.accounts.reward_pool.key(),
MplStakingError::InvalidRewardPool
);
require!(
ctx.remaining_accounts.len() >= filtered_mints.len(),
MplStakingError::InvalidAssoctiatedTokenAccounts
);

{
let voter = ctx.accounts.voter.load()?;
Expand All @@ -97,31 +105,36 @@ pub fn close_voter<'info>(ctx: Context<'_, '_, '_, 'info, CloseVoter<'info>>) ->

let voter_seeds = voter_seeds!(voter);

// will close all the token accounts owned by the voter
for deposit_vault_info in ctx.remaining_accounts {
let deposit_vault_ta = Account::<TokenAccount>::try_from(deposit_vault_info)
let calculated_atas_to_close = filtered_mints.into_iter().map(|voting_mint_config| {
get_associated_token_address(&ctx.accounts.voter.key(), &voting_mint_config.mint)
});

for calculated_ata_to_close in calculated_atas_to_close {
let ata_info_to_close = ctx
.remaining_accounts
.iter()
.find(|ata| *ata.key == calculated_ata_to_close)
.ok_or(MplStakingError::InvalidAssoctiatedTokenAccounts)?;

if ata_info_to_close.data_is_empty()
&& ata_info_to_close.owner == &system_program::ID
&& **ata_info_to_close.lamports.borrow() == 0
{
continue;
}

let ata = Account::<TokenAccount>::try_from(ata_info_to_close)
.map_err(|_| MplStakingError::DeserializationError)?;
registrar.voting_mint_config_index(deposit_vault_ta.mint)?;

require_keys_eq!(
*deposit_vault_info.key,
get_associated_token_address(&ctx.accounts.voter.key(), &deposit_vault_ta.mint),
);

require_keys_eq!(
deposit_vault_ta.owner,
ata.owner,
ctx.accounts.voter.key(),
MplStakingError::InvalidAuthority
);
require_eq!(
deposit_vault_ta.amount,
0,
MplStakingError::VaultTokenNonZero
);
require_eq!(ata.amount, 0, MplStakingError::VaultTokenNonZero);

// close vault
let cpi_close_accounts = CloseAccount {
account: deposit_vault_ta.to_account_info(),
account: ata.to_account_info(),
destination: ctx.accounts.sol_destination.to_account_info(),
authority: ctx.accounts.voter.to_account_info(),
};
Expand All @@ -131,7 +144,7 @@ pub fn close_voter<'info>(ctx: Context<'_, '_, '_, 'info, CloseVoter<'info>>) ->
&[voter_seeds],
))?;

deposit_vault_ta.exit(ctx.program_id)?;
ata.exit(ctx.program_id)?;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct ConfigureVotingMint<'info> {
/// exchange rate per mint.
///
/// * `idx`: index of the rate to be set
/// * `grand_authority`: The keypair that might be an authority for Grand/Clawback
/// * `grant_authority`: The keypair that might be an authority for Grant/Clawback
///
/// This instruction can be called several times for the same mint and index to
/// change the voting mint configuration.
Expand Down
Loading
Loading