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-739] Audit fixes round 3 #40

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 13 additions & 3 deletions programs/voter-stake-registry/src/instructions/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,26 @@ pub struct Claim<'info> {
/// CHECK: Rewards mint addr will be checked in the rewards contract
pub reward_mint: UncheckedAccount<'info>,

#[account(mut)]
#[account(
mut,
seeds = [b"vault", reward_pool.key().as_ref(), reward_mint.key().as_ref()],
seeds::program = rewards_program.key(),
bump,
)]
/// CHECK: Rewards vault is used as a source of rewards and
/// is checked on the rewards contract
/// PDA(["vault", reward_pool, reward_mint], reward_program)
pub vault: UncheckedAccount<'info>,

/// CHECK: mining PDA will be checked in the rewards contract
/// PDA(["mining", mining owner <aka voter_authority in our case>, reward_pool],
/// PDA(["mining", mining owner <aka mining_owner in our case>, reward_pool],
/// reward_program)
#[account(mut)]
#[account(
mut,
seeds = [b"mining", mining_owner.key().as_ref(), reward_pool.key().as_ref()],
seeds::program = rewards_program.key(),
bump,
)]
pub deposit_mining: UncheckedAccount<'info>,

pub mining_owner: Signer<'info>,
Expand Down
34 changes: 17 additions & 17 deletions programs/voter-stake-registry/src/instructions/close_voter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::cpi_instructions;
use anchor_lang::prelude::*;
use anchor_spl::token::{self, CloseAccount, Mint, Token, TokenAccount};
use anchor_spl::token::{self, CloseAccount, Token, TokenAccount};
use bytemuck::bytes_of_mut;
use mplx_staking_states::{
error::MplStakingError,
Expand All @@ -21,7 +21,7 @@ pub struct CloseVoter<'info> {
// the other constraints must be exhaustive
#[account(
mut,
seeds = [voter.load()?.registrar.key().as_ref(), b"voter".as_ref(), voter_authority.key().as_ref()],
seeds = [registrar.key().as_ref(), b"voter".as_ref(), voter_authority.key().as_ref()],
bump = voter.load()?.voter_bump,
has_one = voter_authority,
close = sol_destination
Expand All @@ -34,7 +34,12 @@ pub struct CloseVoter<'info> {
/// CHECK: mining PDA will be checked in the rewards contract
/// PDA(["mining", mining owner <aka voter_authority in our case>, reward_pool],
/// reward_program)
#[account(mut)]
#[account(
mut,
seeds = [b"mining", voter_authority.key().as_ref(), reward_pool.key().as_ref()],
seeds::program = rewards_program.key(),
bump,
)]
pub deposit_mining: UncheckedAccount<'info>,

/// CHECK:
Expand All @@ -43,8 +48,6 @@ pub struct CloseVoter<'info> {
/// keep track of all rewards and staking logic.
pub reward_pool: UncheckedAccount<'info>,

pub deposit_mint: Account<'info, Mint>,

#[account(mut)]
/// CHECK: Destination may be any address.
pub sol_destination: UncheckedAccount<'info>,
Expand All @@ -56,17 +59,15 @@ pub struct CloseVoter<'info> {
pub rewards_program: UncheckedAccount<'info>,
}

/// Closes the voter account, and specified token vault if any provided,
/// Closes the voter account, and specified token vaults if provided in the remaining accounts,
/// allowing to retrieve rent examption SOL.
/// Only accounts with no remaining stakes can be closed.
///
/// Remaining accounts should containt the complete list of ATA that must be closed,
/// 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()?;

require!(
ctx.accounts.deposit_mint.key() == registrar.realm_governing_token_mint,
MplStakingError::InvalidGoverningTokenMint,
);

require!(
ctx.accounts.rewards_program.key() == registrar.rewards_program,
MplStakingError::InvalidRewardsProgram
Expand Down Expand Up @@ -98,16 +99,15 @@ pub fn close_voter<'info>(ctx: Context<'_, '_, '_, 'info, CloseVoter<'info>>) ->

// 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)
.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(),
&ctx.accounts.deposit_mint.key()
),
get_associated_token_address(&ctx.accounts.voter.key(), &deposit_vault_ta.mint),
);

let deposit_vault_ta = Account::<TokenAccount>::try_from(&deposit_vault_info)
.map_err(|_| MplStakingError::DeserializationError)?;
require_keys_eq!(
deposit_vault_ta.owner,
ctx.accounts.voter.key(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ pub struct CreateRegistrar<'info> {
/// CHECK: any address is allowed
/// This account is responsible for storing money for rewards
/// PDA(["vault", reward_pool, reward_mint], reward_program)
#[account(mut)]
#[account(
mut,
seeds = [b"vault", reward_pool.key().as_ref(), realm_governing_token_mint.key().as_ref()],
seeds::program = rewards_program.key(),
bump,
)]
reward_vault: UncheckedAccount<'info>,

#[account(mut)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ pub struct CreateVoter<'info> {
/// CHECK: mining PDA will be checked in the rewards contract
/// PDA(["mining", mining owner <aka voter_authority in our case>, reward_pool],
/// reward_program)
#[account(mut)]
#[account(
mut,
seeds = [b"mining", voter_authority.key().as_ref(), reward_pool.key().as_ref()],
seeds::program = rewards_program.key(),
bump,
)]
pub deposit_mining: UncheckedAccount<'info>,

/// CHECK: Rewards program ID
Expand Down
Binary file modified programs/voter-stake-registry/tests/fixtures/mplx_rewards.so
Binary file not shown.
1 change: 0 additions & 1 deletion programs/voter-stake-registry/tests/program_test/addin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,6 @@ impl AddinCookie {
voter_authority: voter_authority.pubkey(),
deposit_mining,
reward_pool: registrar.reward_pool,
deposit_mint: voting_mint.mint.pubkey.unwrap(),
sol_destination: voter_authority.pubkey(),
token_program: spl_token::id(),
rewards_program: *rewards_program,
Expand Down
Loading