Skip to content

Commit

Permalink
fix bug with switching back from a delegate to an own wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
kstepanovdev committed Jul 25, 2024
1 parent 1d7709c commit 9725ee3
Show file tree
Hide file tree
Showing 2 changed files with 283 additions and 46 deletions.
92 changes: 46 additions & 46 deletions programs/voter-stake-registry/src/instructions/change_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,56 +63,56 @@ pub struct ChangeDelegate<'info> {
/// The old delegate will stop receiving rewards.
/// It might be done once per five days.
pub fn change_delegate(ctx: Context<ChangeDelegate>, deposit_entry_index: u8) -> Result<()> {
require!(
&ctx.accounts.voter.key() != &ctx.accounts.delegate_voter.key(),
VsrError::SameDelegate
);

let registrar = &ctx.accounts.registrar.load()?;
let voter = &mut ctx.accounts.voter.load_mut()?;
let delegate_voter = &ctx.accounts.delegate_voter.load()?;
let voter_authority = voter.voter_authority;
let target = voter.active_deposit_mut(deposit_entry_index)?;

require!(
delegate_voter.voter_authority != target.delegate,
VsrError::SameDelegate
);

let curr_ts = clock_unix_timestamp();
let delegate_voter_weighted_stake = delegate_voter
.deposits
.iter()
.fold(0, |acc, d| acc + d.weighted_stake(curr_ts));
require!(
delegate_voter_weighted_stake >= Voter::MIN_OWN_WEIGHTED_STAKE,
VsrError::InsufficientWeightedStake
);

let delegate_last_update_diff = curr_ts
.checked_sub(target.delegate_last_update_ts)
.ok_or(VsrError::ArithmeticOverflow)?;

require!(
delegate_last_update_diff > DELEGATE_UPDATE_DIFF_THRESHOLD,
VsrError::DelegateUpdateIsTooSoon
);

let (reward_pool, _) = find_reward_pool_address(
&ctx.accounts.rewards_program.key(),
&ctx.accounts.registrar.key(),
);
let (delegate_mining, _) = find_mining_address(
&ctx.accounts.rewards_program.key(),
&delegate_voter.voter_authority,
&reward_pool,
);

require!(
delegate_mining == ctx.accounts.new_delegate_mining.key(),
VsrError::InvalidMining
);

target.delegate = delegate_voter.voter_authority;
if &ctx.accounts.voter.key() == &ctx.accounts.delegate_voter.key() {

Check failure on line 71 in programs/voter-stake-registry/src/instructions/change_delegate.rs

View workflow job for this annotation

GitHub Actions / Linter

needlessly taken reference of both operands
require!(target.delegate != voter_authority, VsrError::SameDelegate);
target.delegate = voter_authority;
} else {
let delegate_voter = &ctx.accounts.delegate_voter.load()?;
require!(
&ctx.accounts.voter.key() != &ctx.accounts.delegate_voter.key()

Check failure on line 77 in programs/voter-stake-registry/src/instructions/change_delegate.rs

View workflow job for this annotation

GitHub Actions / Linter

needlessly taken reference of both operands
&& delegate_voter.voter_authority != target.delegate,
VsrError::SameDelegate
);

let curr_ts = clock_unix_timestamp();
let delegate_voter_weighted_stake = delegate_voter
.deposits
.iter()
.fold(0, |acc, d| acc + d.weighted_stake(curr_ts));
require!(
delegate_voter_weighted_stake >= Voter::MIN_OWN_WEIGHTED_STAKE,
VsrError::InsufficientWeightedStake
);
let delegate_last_update_diff = curr_ts
.checked_sub(target.delegate_last_update_ts)
.ok_or(VsrError::ArithmeticOverflow)?;

require!(
delegate_last_update_diff > DELEGATE_UPDATE_DIFF_THRESHOLD,
VsrError::DelegateUpdateIsTooSoon
);

let (reward_pool, _) = find_reward_pool_address(
&ctx.accounts.rewards_program.key(),
&ctx.accounts.registrar.key(),
);
let (delegate_mining, _) = find_mining_address(
&ctx.accounts.rewards_program.key(),
&delegate_voter.voter_authority,
&reward_pool,
);

require!(
delegate_mining == ctx.accounts.new_delegate_mining.key(),
VsrError::InvalidMining
);
target.delegate = delegate_voter.voter_authority;
}

let reward_pool = ctx.accounts.reward_pool.to_account_info();
let mining = ctx.accounts.deposit_mining.to_account_info();
Expand Down
237 changes: 237 additions & 0 deletions programs/voter-stake-registry/tests/test_change_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,3 +609,240 @@ async fn delegate_is_the_same() -> Result<(), TransportError> {

Ok(())
}

#[tokio::test]
async fn change_from_own_delegate_to_new_delegate_and_back() -> Result<(), TransportError> {
let context = TestContext::new().await;

let payer = &context.users[0].key;
let realm_authority = Keypair::new();
let realm = context
.governance
.create_realm(
"testrealm",
realm_authority.pubkey(),
&context.mints[0],
payer,
&context.addin.program_id,
)
.await;

let voter_authority = &context.users[1].key;
let token_owner_record = realm
.create_token_owner_record(voter_authority.pubkey(), payer)
.await;

let fill_authority = Keypair::from_bytes(&context.users[3].key.to_bytes()).unwrap();
let distribution_authority = Keypair::new();
let (registrar, rewards_pool) = context
.addin
.create_registrar(
&realm,
&realm_authority,
payer,
&fill_authority.pubkey(),
&distribution_authority.pubkey(),
&context.rewards.program_id,
)
.await;
context
.addin
.configure_voting_mint(
&registrar,
&realm_authority,
payer,
0,
&context.mints[0],
None,
None,
)
.await;
let mngo_voting_mint = context
.addin
.configure_voting_mint(
&registrar,
&realm_authority,
payer,
0,
&context.mints[0],
None,
None,
)
.await;

let (deposit_mining, _) = find_deposit_mining_addr(
&context.rewards.program_id,
&voter_authority.pubkey(),
&rewards_pool,
);

// CREATE DELEGATE
let delegate_authority = &context.users[2].key;
let delegate_token_account = context.users[2].token_accounts[0];

let (delegate_mining, _) = find_deposit_mining_addr(
&context.rewards.program_id,
&delegate_authority.pubkey(),
&rewards_pool,
);

let delegate_voter = context
.addin
.create_voter(
&registrar,
&token_owner_record,
delegate_authority,
payer,
&rewards_pool,
&delegate_mining,
&context.rewards.program_id,
)
.await;
context
.addin
.create_deposit_entry(
&registrar,
&delegate_voter,
&delegate_voter,
&mngo_voting_mint,
0,
LockupKind::None,
LockupPeriod::None,
)
.await?;
context
.addin
.create_deposit_entry(
&registrar,
&delegate_voter,
&delegate_voter,
&mngo_voting_mint,
1,
LockupKind::Constant,
LockupPeriod::OneYear,
)
.await?;
context
.addin
.deposit(
&registrar,
&delegate_voter,
&mngo_voting_mint,
delegate_authority,
delegate_token_account,
0,
6_000_000,
)
.await?;
context
.addin
.stake(
&registrar,
&delegate_voter,
delegate_authority.pubkey(),
&context.rewards.program_id,
0,
1,
6_000_000,
)
.await?;

// CREATE VOTER
let voter = context
.addin
.create_voter(
&registrar,
&token_owner_record,
voter_authority,
payer,
&rewards_pool,
&deposit_mining,
&context.rewards.program_id,
)
.await;

// test deposit and stake
let voter_token_account = context.users[1].token_accounts[0];
context
.addin
.create_deposit_entry(
&registrar,
&voter,
&voter,
&mngo_voting_mint,
0,
LockupKind::None,
LockupPeriod::None,
)
.await?;
context
.addin
.create_deposit_entry(
&registrar,
&voter,
&voter,
&mngo_voting_mint,
1,
LockupKind::Constant,
LockupPeriod::OneYear,
)
.await?;
context
.addin
.deposit(
&registrar,
&voter,
&mngo_voting_mint,
voter_authority,
voter_token_account,
0,
10000,
)
.await?;
context
.addin
.stake(
&registrar,
&voter,
voter.authority.pubkey(),
&context.rewards.program_id,
0,
1,
10000,
)
.await?;

advance_clock_by_ts(&mut context.solana.context.borrow_mut(), 5 * 86400).await;

let (old_delegate_mining, _) = find_deposit_mining_addr(
&context.rewards.program_id,
&voter.authority.pubkey(),
&rewards_pool,
);

context
.addin
.change_delegate(
&registrar,
&voter,
&delegate_voter,
&old_delegate_mining,
&context.rewards.program_id,
1,
)
.await?;

context
.addin
.change_delegate(
&registrar,
&voter,
&voter,
&delegate_mining,
&context.rewards.program_id,
1,
)
.await?;

Ok(())
}

0 comments on commit 9725ee3

Please sign in to comment.