Skip to content

Commit

Permalink
added delegate_mining check (#38)
Browse files Browse the repository at this point in the history
added `delegate_mining` check
  • Loading branch information
rwwwx authored Aug 28, 2024
1 parent 406078f commit bf0127c
Show file tree
Hide file tree
Showing 19 changed files with 193 additions and 13 deletions.
10 changes: 10 additions & 0 deletions programs/rewards/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ pub enum MplxRewardsError {
/// Account is already initialized
#[error("Account is already initialized")]
AlreadyInitialized,

/// 19
/// Incorrect mining address.
#[error("Invalid mining")]
InvalidMining,

/// 20
/// Failed to derive PDA.
#[error("Failed to derive PDA")]
DerivationError,
}

impl PrintProgramError for MplxRewardsError {
Expand Down
18 changes: 17 additions & 1 deletion programs/rewards/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub enum RewardsInstruction {
lockup_period: LockupPeriod,
/// Specifies the owner of the Mining Account
mining_owner: Pubkey,
delegate: Pubkey,
},

/// Withdraws amount of supply to the mining account
Expand All @@ -77,6 +78,7 @@ pub enum RewardsInstruction {
amount: u64,
/// Specifies the owner of the Mining Account
mining_owner: Pubkey,
delegate: Pubkey,
},

/// Claims amount of rewards
Expand Down Expand Up @@ -113,6 +115,8 @@ pub enum RewardsInstruction {
additional_amount: u64,
/// The wallet who owns the mining account
mining_owner: Pubkey,
/// Wallet addres of delegate
delegate: Pubkey,
},

/// Distributes tokens among mining owners
Expand All @@ -138,6 +142,7 @@ pub enum RewardsInstruction {
ChangeDelegate {
/// Amount of staked tokens
staked_amount: u64,
new_delegate: Pubkey,
},
}

Expand Down Expand Up @@ -240,6 +245,7 @@ pub fn deposit_mining(
amount: u64,
lockup_period: LockupPeriod,
mining_owner: &Pubkey,
delegate: &Pubkey,
) -> Instruction {
let accounts = vec![
AccountMeta::new(*reward_pool, false),
Expand All @@ -254,12 +260,14 @@ pub fn deposit_mining(
amount,
lockup_period,
mining_owner: *mining_owner,
delegate: *delegate,
},
accounts,
)
}

/// Creates 'WithdrawMining' instruction.
#[allow(clippy::too_many_arguments)]
pub fn withdraw_mining(
program_id: &Pubkey,
reward_pool: &Pubkey,
Expand All @@ -268,6 +276,7 @@ pub fn withdraw_mining(
delegate_mining: &Pubkey,
amount: u64,
mining_owner: &Pubkey,
delegate: &Pubkey,
) -> Instruction {
let accounts = vec![
AccountMeta::new(*reward_pool, false),
Expand All @@ -281,6 +290,7 @@ pub fn withdraw_mining(
&RewardsInstruction::WithdrawMining {
amount,
mining_owner: *mining_owner,
delegate: *delegate,
},
accounts,
)
Expand Down Expand Up @@ -326,6 +336,7 @@ pub fn extend_stake(
base_amount: u64,
additional_amount: u64,
mining_owner: &Pubkey,
delegate: &Pubkey,
) -> Instruction {
let accounts = vec![
AccountMeta::new(*reward_pool, false),
Expand All @@ -343,6 +354,7 @@ pub fn extend_stake(
base_amount,
additional_amount,
mining_owner: *mining_owner,
delegate: *delegate,
},
accounts,
)
Expand Down Expand Up @@ -398,6 +410,7 @@ pub fn change_delegate(
mining_owner: &Pubkey,
old_delegate_mining: &Pubkey,
new_delegate_mining: &Pubkey,
new_delegate: &Pubkey,
staked_amount: u64,
) -> Instruction {
let accounts = vec![
Expand All @@ -411,7 +424,10 @@ pub fn change_delegate(

Instruction::new_with_borsh(
*program_id,
&RewardsInstruction::ChangeDelegate { staked_amount },
&RewardsInstruction::ChangeDelegate {
staked_amount,
new_delegate: *new_delegate,
},
accounts,
)
}
12 changes: 11 additions & 1 deletion programs/rewards/src/instructions/change_delegate.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::{
asserts::assert_and_get_pool_and_mining,
error::MplxRewardsError,
utils::{get_delegate_mining, AccountLoader},
utils::{get_delegate_mining, verify_delegate_mining_address, AccountLoader},
};
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};

pub fn process_change_delegate<'a>(
program_id: &Pubkey,
accounts: &'a [AccountInfo<'a>],
staked_amount: u64,
new_delegate: &Pubkey,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter().enumerate();

Expand Down Expand Up @@ -37,6 +38,15 @@ pub fn process_change_delegate<'a>(
)?;

let new_delegate_mining = get_delegate_mining(new_delegate_mining, mining)?;
if let Some(new_delegate_mining) = new_delegate_mining {
verify_delegate_mining_address(
program_id,
new_delegate_mining,
new_delegate,
reward_pool.key,
)?
}

let old_delegate_mining = get_delegate_mining(old_delegate_mining, mining)?;

wrapped_reward_pool.change_delegate(
Expand Down
6 changes: 5 additions & 1 deletion programs/rewards/src/instructions/deposit_mining.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
asserts::assert_and_get_pool_and_mining,
utils::{get_delegate_mining, AccountLoader, LockupPeriod},
utils::{get_delegate_mining, verify_delegate_mining_address, AccountLoader, LockupPeriod},
};
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};

Expand All @@ -10,6 +10,7 @@ pub fn process_deposit_mining<'a>(
amount: u64,
lockup_period: LockupPeriod,
mining_owner: &Pubkey,
delegate: &Pubkey,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter().enumerate();

Expand All @@ -32,6 +33,9 @@ pub fn process_deposit_mining<'a>(
)?;

let delegate_mining = get_delegate_mining(delegate_mining, mining)?;
if let Some(delegate_mining) = delegate_mining {
verify_delegate_mining_address(program_id, delegate_mining, delegate, reward_pool.key)?
}

wrapped_reward_pool.deposit(&mut wrapped_mining, amount, lockup_period, delegate_mining)?;

Expand Down
7 changes: 6 additions & 1 deletion programs/rewards/src/instructions/extend_stake.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
asserts::assert_and_get_pool_and_mining,
utils::{get_delegate_mining, AccountLoader, LockupPeriod},
utils::{get_delegate_mining, verify_delegate_mining_address, AccountLoader, LockupPeriod},
};
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};

Expand All @@ -14,6 +14,7 @@ pub fn process_extend_stake<'a>(
base_amount: u64,
additional_amount: u64,
mining_owner: &Pubkey,
delegate: &Pubkey,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter().enumerate();

Expand All @@ -37,6 +38,10 @@ pub fn process_extend_stake<'a>(

let delegate_mining = get_delegate_mining(delegate_mining, mining)?;

if let Some(delegate_mining) = delegate_mining {
verify_delegate_mining_address(program_id, delegate_mining, delegate, reward_pool.key)?
}

wrapped_reward_pool.extend(
&mut wrapped_mining,
old_lockup_period,
Expand Down
22 changes: 18 additions & 4 deletions programs/rewards/src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,25 @@ pub fn process_instruction<'a>(
amount,
lockup_period,
mining_owner,
delegate,
} => {
msg!("RewardsInstruction: DepositMining");
process_deposit_mining(program_id, accounts, amount, lockup_period, &mining_owner)
process_deposit_mining(
program_id,
accounts,
amount,
lockup_period,
&mining_owner,
&delegate,
)
}
RewardsInstruction::WithdrawMining {
amount,
mining_owner,
delegate,
} => {
msg!("RewardsInstruction: WithdrawMining");
process_withdraw_mining(program_id, accounts, amount, &mining_owner)
process_withdraw_mining(program_id, accounts, amount, &mining_owner, &delegate)
}
RewardsInstruction::Claim => {
msg!("RewardsInstruction: Claim");
Expand All @@ -77,6 +86,7 @@ pub fn process_instruction<'a>(
base_amount,
additional_amount,
mining_owner,
delegate,
} => {
msg!("RewardsInstruction: ExtendStake");
process_extend_stake(
Expand All @@ -88,6 +98,7 @@ pub fn process_instruction<'a>(
base_amount,
additional_amount,
&mining_owner,
&delegate,
)
}
RewardsInstruction::DistributeRewards => {
Expand All @@ -98,9 +109,12 @@ pub fn process_instruction<'a>(
msg!("RewardsInstruction: CloseAccount");
process_close_mining(program_id, accounts)
}
RewardsInstruction::ChangeDelegate { staked_amount } => {
RewardsInstruction::ChangeDelegate {
staked_amount,
new_delegate,
} => {
msg!("RewardsInstruction: ChangeDelegate");
process_change_delegate(program_id, accounts, staked_amount)
process_change_delegate(program_id, accounts, staked_amount, &new_delegate)
}
}
}
5 changes: 5 additions & 0 deletions programs/rewards/src/instructions/withdraw_mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ use crate::{
utils::{get_delegate_mining, AccountLoader},
};

use crate::utils::verify_delegate_mining_address;
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};

pub fn process_withdraw_mining<'a>(
program_id: &Pubkey,
accounts: &'a [AccountInfo<'a>],
amount: u64,
mining_owner: &Pubkey,
delegate: &Pubkey,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter().enumerate();

Expand All @@ -32,6 +34,9 @@ pub fn process_withdraw_mining<'a>(
)?;

let delegate_mining = get_delegate_mining(delegate_mining, mining)?;
if let Some(delegate_mining) = delegate_mining {
verify_delegate_mining_address(program_id, delegate_mining, delegate, reward_pool.key)?
}

wrapped_reward_pool.withdraw(&mut wrapped_mining, amount, delegate_mining)?;

Expand Down
44 changes: 42 additions & 2 deletions programs/rewards/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Arbitrary auxilliary functions
use std::iter::Enumerate;

use crate::error::MplxRewardsError;
use crate::{error::MplxRewardsError, state::WrappedImmutableMining};
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::AccountInfo,
Expand All @@ -11,7 +11,7 @@ use solana_program::{
program::{invoke, invoke_signed},
program_error::ProgramError,
program_pack::Pack,
pubkey::Pubkey,
pubkey::{Pubkey, PubkeyError},
rent::Rent,
system_instruction,
sysvar::Sysvar,
Expand Down Expand Up @@ -118,6 +118,29 @@ pub fn get_delegate_mining<'a, 'b>(
}
}

pub fn verify_delegate_mining_address(
program_id: &Pubkey,
delegate_mining: &AccountInfo<'_>,
delegate: &Pubkey,
reward_pool_key: &Pubkey,
) -> Result<(), ProgramError> {
if *delegate_mining.key
!= create_mining_address(
program_id,
delegate,
reward_pool_key,
WrappedImmutableMining::from_bytes(&delegate_mining.data.borrow())?
.mining
.bump,
)
.map_err(|_| MplxRewardsError::DerivationError)?
{
return Err(MplxRewardsError::InvalidMining.into());
}

Ok(())
}

/// Helper for parsing accounts with arbitrary input conditions
pub struct AccountLoader {}

Expand Down Expand Up @@ -321,3 +344,20 @@ impl SafeArithmeticOperations for u128 {
.ok_or(MplxRewardsError::MathOverflow)
}
}

pub fn create_mining_address(
program_id: &Pubkey,
mining_owner: &Pubkey,
reward_pool: &Pubkey,
bump: u8,
) -> Result<Pubkey, PubkeyError> {
Pubkey::create_program_address(
&[
"mining".as_bytes(),
&mining_owner.to_bytes(),
&reward_pool.to_bytes(),
&[bump],
],
program_id,
)
}
Loading

0 comments on commit bf0127c

Please sign in to comment.