Skip to content

Commit

Permalink
Merge pull request #41 from adm-metaex/penalties/slashing
Browse files Browse the repository at this point in the history
[mtg-598] [mtg-576] Penalties/slashing
  • Loading branch information
kstepanovdev authored Sep 16, 2024
2 parents 4c2ff68 + 7d47fce commit 1e95f78
Show file tree
Hide file tree
Showing 17 changed files with 605 additions and 611 deletions.
46 changes: 14 additions & 32 deletions programs/rewards/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,74 +41,56 @@ pub enum MplxRewardsError {
#[error("Rewards: distribution_ends_at date is lower than current date")]
InvalidPrimitiveTypesConversion,

/// 11
/// 6
/// Impossible to close accounts while it has unclaimed rewards
#[error("Rewards: unclaimed rewards must be claimed")]
RewardsMustBeClaimed,

/// 12
/// 7
/// No need to transfer zero amount of rewards.
#[error("Rewards: rewards amount must be positive")]
RewardsMustBeGreaterThanZero,

/// 13
/// Delegate lack of tokens
#[error("Rewards: Delegate must have at least 15_000_000 of own weighted stake")]
InsufficientWeightedStake,

/// 14
/// 8
/// Stake from others must be zero
#[error("Rewards: Stake from others must be zero")]
StakeFromOthersMustBeZero,

/// 15
/// 9
/// No need to transfer zero amount of rewards.
#[error("No changes at the date in weighted stake modifiers while they're expected")]
NoWeightedStakeModifiersAtADate,

/// 16
/// 10
/// To change a delegate, the new delegate must differ from the current one
#[error("Passed delegates are the same")]
DelegatesAreTheSame,

/// 17
/// 11
/// Getting pointer to the data of the zero-copy account has failed
#[error("Getting pointer to the data of the zero-copy account has failed")]
RetreivingZeroCopyAccountFailire,

/// 18
/// 12
/// Account is already initialized
#[error("Account is already initialized")]
AlreadyInitialized,

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

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

/// 21
#[error("Mining already restricted")]
MiningAlreadyRestricted,

/// 22
/// Mining is not restricted
#[error("Mining is not restricted")]
MiningNotRestricted,

/// 23
/// Claiming is restricted
#[error("Claiming is restricted")]
ClaimingRestricted,

/// 24
/// Withdrawal is restricted while claiming is restricted
#[error("Withdrawal is restricted while claiming is restricted")]
WithdrawalRestricted,
/// 15
#[error(
"Rewards: Penalty is not apliable becase it's bigger than the mining's weighted stake"
)]
DecreaseRewardsTooBig,
}

impl PrintProgramError for MplxRewardsError {
Expand Down
70 changes: 27 additions & 43 deletions programs/rewards/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,27 +145,26 @@ pub enum RewardsInstruction {
new_delegate: Pubkey,
},

/// Prevents the mining account from rewards withdrawing
#[account(0, signer, name = "deposit_authority", desc = "The address of the Staking program's Registrar, which is PDA and is responsible for signing CPIs")]
#[account(1, name = "reward_pool", desc = "The address of the reward pool")]
#[account(1, writable, name = "reward_pool", desc = "The address of the reward pool")]
#[account(2, writable, name = "mining", desc = "The address of the mining account which belongs to the user and stores info about user's rewards")]
RestrictTokenFlow {
Slash {
mining_owner: Pubkey,
// number of tokens that had been slashed
slash_amount_in_native: u64,
// weighted stake part for the slashed number of tokens multiplied by the period
slash_amount_multiplied_by_period: u64,
// None if it's Flex period, because it's already expired
stake_expiration_date: Option<u64>,
},

#[account(0, signer, name = "deposit_authority", desc = "The address of the Staking program's Registrar, which is PDA and is responsible for signing CPIs")]
#[account(1, name = "reward_pool", desc = "The address of the reward pool")]
#[account(1, writable, name = "reward_pool", desc = "The address of the reward pool")]
#[account(2, writable, name = "mining", desc = "The address of the mining account which belongs to the user and stores info about user's rewards")]
AllowTokenFlow {
mining_owner: Pubkey,
},

#[account(0, signer, name = "deposit_authority", desc = "The address of the Staking program's Registrar, which is PDA and is responsible for signing CPIs")]
#[account(1, name = "reward_pool", desc = "The address of the reward pool")]
#[account(2, writable, name = "mining", desc = "The address of the mining account which belongs to the user and stores info about user's rewards")]
RestrictBatchMinting {
restrict_batch_minting_until_ts: u64,
DecreaseRewards {
mining_owner: Pubkey,
// The number by which weighted stake should be decreased
decreased_weighted_stake_number: u64,
},
}

Expand Down Expand Up @@ -455,69 +454,54 @@ pub fn change_delegate(
)
}

pub fn restrict_tokenflow(
program_id: &Pubkey,
deposit_authority: &Pubkey,
reward_pool: &Pubkey,
mining: &Pubkey,
mining_owner: &Pubkey,
) -> Instruction {
let accounts = vec![
AccountMeta::new_readonly(*deposit_authority, true),
AccountMeta::new_readonly(*reward_pool, false),
AccountMeta::new(*mining, false),
];

Instruction::new_with_borsh(
*program_id,
&RewardsInstruction::RestrictTokenFlow {
mining_owner: *mining_owner,
},
accounts,
)
}

pub fn allow_tokenflow(
#[allow(clippy::too_many_arguments)]
pub fn slash(
program_id: &Pubkey,
deposit_authority: &Pubkey,
reward_pool: &Pubkey,
mining: &Pubkey,
mining_owner: &Pubkey,
slash_amount_in_native: u64,
slash_amount_multiplied_by_period: u64,
stake_expiration_date: Option<u64>,
) -> Instruction {
let accounts = vec![
AccountMeta::new_readonly(*deposit_authority, true),
AccountMeta::new_readonly(*reward_pool, false),
AccountMeta::new(*reward_pool, false),
AccountMeta::new(*mining, false),
];

Instruction::new_with_borsh(
*program_id,
&RewardsInstruction::AllowTokenFlow {
&RewardsInstruction::Slash {
mining_owner: *mining_owner,
slash_amount_in_native,
slash_amount_multiplied_by_period,
stake_expiration_date,
},
accounts,
)
}

pub fn restrict_batch_minting(
pub fn decrease_rewards(
program_id: &Pubkey,
deposit_authority: &Pubkey,
reward_pool: &Pubkey,
mining: &Pubkey,
mining_owner: &Pubkey,
restrict_batch_minting_until_ts: u64,
decreased_weighted_stake_number: u64,
) -> Instruction {
let accounts = vec![
AccountMeta::new_readonly(*deposit_authority, true),
AccountMeta::new_readonly(*reward_pool, false),
AccountMeta::new(*reward_pool, false),
AccountMeta::new(*mining, false),
];

Instruction::new_with_borsh(
*program_id,
&RewardsInstruction::RestrictBatchMinting {
restrict_batch_minting_until_ts,
&RewardsInstruction::DecreaseRewards {
mining_owner: *mining_owner,
decreased_weighted_stake_number,
},
accounts,
)
Expand Down
5 changes: 0 additions & 5 deletions programs/rewards/src/instructions/claim.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
asserts::{assert_account_key, assert_account_owner},
error::MplxRewardsError,
state::{WrappedMining, WrappedRewardPool},
utils::{spl_transfer, AccountLoader},
};
Expand Down Expand Up @@ -43,10 +42,6 @@ pub fn process_claim<'a>(program_id: &Pubkey, accounts: &'a [AccountInfo<'a>]) -
let mining_data = &mut mining.data.borrow_mut();
let mut wrapped_mining = WrappedMining::from_bytes_mut(mining_data)?;

if wrapped_mining.mining.is_tokenflow_restricted() {
return Err(MplxRewardsError::ClaimingRestricted.into());
}

assert_account_owner(reward_pool, program_id)?;
assert_account_key(mining_owner, &wrapped_mining.mining.owner)?;
assert_account_key(reward_pool, &wrapped_mining.mining.reward_pool)?;
Expand Down
32 changes: 20 additions & 12 deletions programs/rewards/src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,32 @@ pub fn process_instruction<'a>(
msg!("RewardsInstruction: ChangeDelegate");
process_change_delegate(program_id, accounts, staked_amount, &new_delegate)
}
RewardsInstruction::RestrictTokenFlow { mining_owner } => {
msg!("RewardsInstruction: RestrictClaiming");
process_restrict_tokenflow(program_id, accounts, &mining_owner)
}
RewardsInstruction::AllowTokenFlow { mining_owner } => {
msg!("RewardsInstruction: AllowClaiming");
process_allow_tokenflow(program_id, accounts, &mining_owner)
RewardsInstruction::Slash {
mining_owner,
slash_amount_in_native,
slash_amount_multiplied_by_period,
stake_expiration_date,
} => {
msg!("RewardsInstruction: Slash");
process_slash(
program_id,
accounts,
&mining_owner,
slash_amount_in_native,
slash_amount_multiplied_by_period,
stake_expiration_date,
)
}
RewardsInstruction::RestrictBatchMinting {
restrict_batch_minting_until_ts,
RewardsInstruction::DecreaseRewards {
mining_owner,
decreased_weighted_stake_number,
} => {
msg!("RewardsInstruction: RestrictBatchMinting");
process_restrict_batch_minting(
msg!("RewardsInstruction: DecreaseRewards");
process_decrease_rewards(
program_id,
accounts,
restrict_batch_minting_until_ts,
&mining_owner,
decreased_weighted_stake_number,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::{asserts::assert_and_get_pool_and_mining, utils::AccountLoader};
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};

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

Expand All @@ -15,7 +16,7 @@ pub fn process_allow_tokenflow<'a>(
let reward_pool_data = &mut reward_pool.data.borrow_mut();
let mining_data = &mut mining.data.borrow_mut();

let (_, wrapped_mining) = assert_and_get_pool_and_mining(
let (_, mut wrapped_mining) = assert_and_get_pool_and_mining(
program_id,
mining_owner,
mining,
Expand All @@ -25,7 +26,7 @@ pub fn process_allow_tokenflow<'a>(
mining_data,
)?;

wrapped_mining.mining.allow_tokenflow()?;
wrapped_mining.decrease_rewards(decreased_weighted_stake_number)?;

Ok(())
}
12 changes: 4 additions & 8 deletions programs/rewards/src/instructions/penalties/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
pub(crate) use allow_tokenflow::*;
pub(crate) use restrict_tokenflow::*;
mod decrease_rewards;
mod slash;

mod allow_tokenflow;
mod restrict_tokenflow;

pub(crate) use restrict_batch_minting::*;

mod restrict_batch_minting;
pub(crate) use decrease_rewards::*;
pub(crate) use slash::*;
31 changes: 0 additions & 31 deletions programs/rewards/src/instructions/penalties/restrict_tokenflow.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::{asserts::assert_and_get_pool_and_mining, utils::AccountLoader};
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};

pub fn process_restrict_batch_minting<'a>(
pub fn process_slash<'a>(
program_id: &Pubkey,
accounts: &'a [AccountInfo<'a>],
restrict_batch_minting_until_ts: u64,
mining_owner: &Pubkey,
slash_amount_in_native: u64,
slash_amount_multiplied_by_period: u64,
stake_expiration_date: Option<u64>,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter().enumerate();

Expand All @@ -16,7 +18,7 @@ pub fn process_restrict_batch_minting<'a>(
let reward_pool_data = &mut reward_pool.data.borrow_mut();
let mining_data = &mut mining.data.borrow_mut();

let (_, wrapped_mining) = assert_and_get_pool_and_mining(
let (mut wrapped_reward_pool, mut wrapped_mining) = assert_and_get_pool_and_mining(
program_id,
mining_owner,
mining,
Expand All @@ -26,7 +28,12 @@ pub fn process_restrict_batch_minting<'a>(
mining_data,
)?;

wrapped_mining.mining.batch_minting_restricted_until = restrict_batch_minting_until_ts;
wrapped_reward_pool.slash(
&mut wrapped_mining,
slash_amount_in_native,
slash_amount_multiplied_by_period,
stake_expiration_date,
)?;

Ok(())
}
Loading

0 comments on commit 1e95f78

Please sign in to comment.