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-482] using the delegated stake in the minimal requirement check #13

Merged
merged 12 commits into from
Aug 8, 2024
Merged
101 changes: 87 additions & 14 deletions programs/bubblegum/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions programs/bubblegum/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ solana-program = "~1.18.11"
spl-account-compression = {git = "https://github.com/StanChe/solana-program-library.git", branch = "feature/init_with_root", features = ["cpi"] }
spl-associated-token-account = { version = ">= 1.1.3, < 3.0", features = ["no-entrypoint"] }
spl-token = { version = ">= 3.5.0, < 5.0", features = ["no-entrypoint"] }
mplx-staking-states = {git = "https://github.com/adm-metaex/mplx-staking.git" }
mplx-staking-states = { git = "https://github.com/adm-metaex/mplx-staking.git" }
mplx-rewards = { git = "https://github.com/adm-metaex/mplx-rewards.git", features = ["no-entrypoint"] }

[dev-dependencies]
async-trait = "0.1.71"
mpl-token-auth-rules = { git = "https://github.com/metaplex-foundation/mpl-token-auth-rules.git", branch = "main", features = ["no-entrypoint"] }
mpl-token-auth-rules = { version = "1.5.1", features = ["no-entrypoint"] }
solana-program-test = "~1.18.11"
solana-sdk = "~1.18.11"
spl-concurrent-merkle-tree = { git = "https://github.com/StanChe/solana-program-library.git", branch = "feature/init_with_root" }
Expand Down
2 changes: 2 additions & 0 deletions programs/bubblegum/program/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub enum BubblegumError {
StakingVoterRegistrarMismatch,
#[msg("Staking voter authority mismatch")]
StakingVoterAuthorityMismatch,
#[msg("Invalid mining owner")]
MiningOwnerMismatch,
}

// Converts certain Token Metadata errors into Bubblegum equivalents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
},
};

const DISCRIMINATOR_LEN: usize = REGISTRAR_DISCRIMINATOR.len();
#[derive(Accounts)]
pub struct FinalizeTreeWithRoot<'info> {
#[account(
Expand All @@ -30,6 +31,8 @@ pub struct FinalizeTreeWithRoot<'info> {
/// CHECK:
pub voter: UncheckedAccount<'info>,
/// CHECK:
pub mining: UncheckedAccount<'info>,
/// CHECK:
#[account(mut)]
pub fee_receiver: UncheckedAccount<'info>,
pub log_wrapper: Program<'info, Noop>,
Expand Down Expand Up @@ -61,6 +64,7 @@ pub(crate) fn finalize_tree_with_root<'info>(
&ctx.accounts.staker.to_account_info(),
&ctx.accounts.registrar.to_account_info(),
&ctx.accounts.voter.to_account_info(),
&ctx.accounts.mining.to_account_info(),
)?;

let num_minted = (rightmost_index + 1) as u64;
Expand Down Expand Up @@ -107,6 +111,7 @@ pub(crate) fn check_stake<'info>(
staker_acc: &AccountInfo<'info>,
registrar_acc: &AccountInfo<'info>,
voter_acc: &AccountInfo<'info>,
mining_acc: &AccountInfo<'info>,
) -> Result<()> {
require!(
registrar_acc.owner == &mplx_staking_states::ID,
Expand All @@ -116,6 +121,10 @@ pub(crate) fn check_stake<'info>(
voter_acc.owner == &mplx_staking_states::ID,
BubblegumError::StakingVoterMismatch
);
require!(
mining_acc.owner == &mplx_rewards::ID,
BubblegumError::MiningOwnerMismatch
);

let generated_registrar = Pubkey::find_program_address(
&[
Expand Down Expand Up @@ -146,13 +155,13 @@ pub(crate) fn check_stake<'info>(
);

let registrar_bytes = registrar_acc.to_account_info().data;

let registrar_bytes = registrar_bytes.borrow();
require!(
(*registrar_bytes.borrow())[..8] == REGISTRAR_DISCRIMINATOR,
registrar_bytes[..DISCRIMINATOR_LEN] == REGISTRAR_DISCRIMINATOR,
BubblegumError::StakingRegistrarDiscriminatorMismatch
);

let registrar: Registrar = *bytemuck::from_bytes(&(*registrar_bytes.borrow())[8..]);
let registrar: &Registrar = bytemuck::from_bytes(&registrar_bytes[DISCRIMINATOR_LEN..]);

require!(
registrar.realm == REALM,
Expand All @@ -164,12 +173,12 @@ pub(crate) fn check_stake<'info>(
);
let voter_bytes = voter_acc.to_account_info().data;

let voter_bytes = voter_bytes.borrow();
require!(
(*voter_bytes.borrow())[..8] == VOTER_DISCRIMINATOR,
voter_bytes[..DISCRIMINATOR_LEN] == VOTER_DISCRIMINATOR,
BubblegumError::StakingVoterDiscriminatorMismatch
);

let voter: Voter = *bytemuck::from_bytes(&(*voter_bytes.borrow())[8..]);
let voter: &Voter = bytemuck::from_bytes(&voter_bytes[DISCRIMINATOR_LEN..]);

require!(
&voter.registrar == registrar_acc.key,
Expand All @@ -179,7 +188,12 @@ pub(crate) fn check_stake<'info>(
&voter.voter_authority == staker_acc.key,
BubblegumError::StakingVoterAuthorityMismatch
);

let mining_data = mining_acc.data.borrow();
let mining = mplx_rewards::state::WrappedImmutableMining::from_bytes(&mining_data)?;
require!(
&mining.mining.owner == staker_acc.key,
BubblegumError::MiningOwnerMismatch
);
let clock = Clock::get()?;
let curr_ts = clock.unix_timestamp as u64;
let weighted_sum: u64 = voter
Expand All @@ -188,7 +202,11 @@ pub(crate) fn check_stake<'info>(
.map(|d| d.weighted_stake(curr_ts))
.sum();

if weighted_sum < MINIMUM_WEIGHTED_STAKE {
if weighted_sum
.checked_add(mining.mining.stake_from_others)
.ok_or(BubblegumError::NumericalOverflowError)?
< MINIMUM_WEIGHTED_STAKE
{
return Err(BubblegumError::NotEnoughStakeForOperation.into());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub struct FinalizeTreeWithRootAndCollection<'info> {
/// CHECK:
pub voter: UncheckedAccount<'info>,
/// CHECK:
pub mining: UncheckedAccount<'info>,
/// CHECK:
#[account(mut)]
pub fee_receiver: UncheckedAccount<'info>,
/// CHECK: Optional collection authority record PDA.
Expand Down Expand Up @@ -95,6 +97,7 @@ impl<'info> From<&mut FinalizeTreeWithRootAndCollection<'info>> for FinalizeTree
staker: value.staker.to_owned(),
registrar: value.registrar.to_owned(),
voter: value.voter.to_owned(),
mining: value.mining.to_owned(),
fee_receiver: value.fee_receiver.to_owned(),
log_wrapper: value.log_wrapper.to_owned(),
compression_program: value.compression_program.to_owned(),
Expand Down
Loading
Loading