Skip to content

Commit

Permalink
[mtg-296] delegated staking extend staking with delegate parameter (#13)
Browse files Browse the repository at this point in the history
* initial delegate

* add delegate initial design

* update tests

* update tests && fixtures

* initial delegate

* add delegate initial design

* update fixtures

* remove redundant reprs

* store deposit mining on each creation of deposit entry && add additional validations for stake and extend methods

* update tests

* remove redundant file

* mtg-425: Error handling improvements  (#14)

improved error handling

* initial delegate

* add delegate initial design

* update tests

* update tests && fixtures

* initial delegate

* add delegate initial design

* update fixtures

* remove redundant reprs

* store deposit mining on each creation of deposit entry && add additional validations for stake and extend methods

* update tests

* remove redundant file

* add delegate as a dedicated wallet instead of delegate_mining

* Update program-states/src/state/deposit_entry.rs

Co-authored-by: Stanislav Cherviakov <[email protected]>

* Update programs/voter-stake-registry/src/cpi_instructions.rs

Co-authored-by: Stanislav Cherviakov <[email protected]>

* unify mining verification

* simplify mining verification

* [mtg-308] (#15)

* added change delegate function

* Fixes after rebase

* fix aligment

* Update program-states/src/state/deposit_entry.rs

Co-authored-by: Stanislav Cherviakov <[email protected]>

---------

Co-authored-by: Stanislav Cherviakov <[email protected]>

---------

Co-authored-by: Matiukhin Vlad <[email protected]>
Co-authored-by: Stanislav Cherviakov <[email protected]>
  • Loading branch information
3 people authored Jul 19, 2024
1 parent 86d4afb commit b7b51e6
Show file tree
Hide file tree
Showing 28 changed files with 2,382 additions and 839 deletions.
1,190 changes: 688 additions & 502 deletions idl/voter_stake_registry.ts

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions program-states/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,19 @@ pub enum VsrError {
// 6028 / 0x178c
#[msg("Arithmetic operation has beed overflowed")]
ArithmeticOverflow,
// 6029 / 0x178d
#[msg("Rewards: Delegate must have at least 15_000_000 of own weighted stake")]
InsufficientWeightedStake,
// 6030 / 0x178e
#[msg("Rewards: Invalid delegate account")]
InvalidDelegate,
// 6031 / 0x178f
#[msg("Rewards: Invalid mining account")]
InvalidMining,
// 6032 / 0x1790
#[msg("Rewards: Updating delegate is sooner than 5 days")]
DelegateUpdateIsTooSoon,
// 6033 / 0x1791
#[msg("Rewards: Cannot change delegate to the same delegate")]
SameDelegate,
}
64 changes: 16 additions & 48 deletions program-states/src/state/deposit_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,26 @@ use anchor_lang::prelude::*;

/// Bookkeeping for a single deposit for a given mint and lockup schedule.
#[zero_copy]
#[derive(Default)]
#[derive(Default, Debug)]
pub struct DepositEntry {
// Locked state.
pub lockup: Lockup,
/// Delegated staker
/// Delegated staker. It's an address of a Delegate.
pub delegate: Pubkey,
/// Amount in deposited, in native currency. Withdraws of vested tokens
/// directly reduce this amount.
///
/// This directly tracks the total amount added by the user. They may
/// never withdraw more than this amount.
pub amount_deposited_native: u64,
/// The last time when the delegate was updated
pub delegate_last_update_ts: u64,
// Points to the VotingMintConfig this deposit uses.
pub voting_mint_config_idx: u8,
// True if the deposit entry is being used.
pub is_used: bool,
pub _reserved1: [u8; 6],
}
const_assert!(std::mem::size_of::<DepositEntry>() == 32 + 32 + 8 + 1 + 1 + 6);
const_assert!(std::mem::size_of::<DepositEntry>() == 32 + 32 + 8 + 8 + 1 + 1 + 6);
const_assert!(std::mem::size_of::<DepositEntry>() % 8 == 0);

impl DepositEntry {
Expand Down Expand Up @@ -105,13 +106,10 @@ mod tests {
end_ts: lockup_start + LockupPeriod::Flex.to_secs(), // start + cooldown + period
kind: Constant,
period,
cooldown_requested: false,
cooldown_ends_at: 0,
_reserved1: [0; 5],
..Default::default()
},
is_used: true,
voting_mint_config_idx: 0,
_reserved1: [0; 6],
..Default::default()
};

let baseline_vote_weight = deposit.amount_deposited_native;
Expand All @@ -131,11 +129,7 @@ mod tests {
fn test_weighted_stake_unused() {
let deposit = DepositEntry {
amount_deposited_native: 20_000,
lockup: Lockup::default(),
is_used: false,
voting_mint_config_idx: 0,
delegate: Pubkey::default(),
_reserved1: [0; 6],
..Default::default()
};
assert_eq!(deposit.weighted_stake(0), 0);
}
Expand All @@ -145,19 +139,9 @@ mod tests {
let amount = 20_000;
let deposit = DepositEntry {
amount_deposited_native: amount,
lockup: Lockup {
start_ts: 0,
end_ts: 0,
kind: Constant,
period: LockupPeriod::Flex,
cooldown_requested: false,
cooldown_ends_at: 0,
_reserved1: [0; 5],
},
lockup: Lockup::default(),
is_used: true,
voting_mint_config_idx: 0,
delegate: Pubkey::default(),
_reserved1: [0; 6],
..Default::default()
};
assert_eq!(deposit.weighted_stake(10), amount);
}
Expand All @@ -168,18 +152,12 @@ mod tests {
let deposit = DepositEntry {
amount_deposited_native: amount,
lockup: Lockup {
start_ts: 0,
end_ts: 100,
kind: Constant,
period: LockupPeriod::Flex,
cooldown_requested: true,
cooldown_ends_at: 200,
_reserved1: [0; 5],
..Default::default()
},
is_used: true,
voting_mint_config_idx: 0,
delegate: Pubkey::default(),
_reserved1: [0; 6],
..Default::default()
};
assert_eq!(deposit.weighted_stake(150), 0);
}
Expand All @@ -190,18 +168,13 @@ mod tests {
let deposit = DepositEntry {
amount_deposited_native: amount,
lockup: Lockup {
start_ts: 0,
end_ts: 100,
kind: Constant,
period: LockupPeriod::OneYear,
cooldown_requested: false,
cooldown_ends_at: 0,
_reserved1: [0; 5],
..Default::default()
},
is_used: true,
voting_mint_config_idx: 0,
delegate: Pubkey::default(),
_reserved1: [0; 6],
..Default::default()
};
assert_eq!(
deposit.weighted_stake(50),
Expand All @@ -216,18 +189,13 @@ mod tests {
let deposit = DepositEntry {
amount_deposited_native: amount,
lockup: Lockup {
start_ts: 0,
end_ts: 200,
kind: None,
period: LockupPeriod::None,
cooldown_requested: false,
cooldown_ends_at: 0,
_reserved1: [0; 5],
..Default::default()
},
is_used: true,
voting_mint_config_idx: 0,
delegate: Pubkey::default(),
_reserved1: [0; 6],
..Default::default()
};
assert_eq!(deposit.weighted_stake(50), 0);

Expand Down
11 changes: 4 additions & 7 deletions program-states/src/state/lockup.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::error::*;
use anchor_lang::prelude::*;
use borsh::{BorshDeserialize, BorshSerialize};

/// Seconds in one day.
pub const SECS_PER_DAY: u64 = 86_400;
Expand All @@ -11,7 +12,7 @@ pub const SECS_PER_MONTH: u64 = 365 * SECS_PER_DAY / 12;
pub const COOLDOWN_SECS: u64 = 86_400 * 5;

#[zero_copy]
#[derive(Default)]
#[derive(Default, Debug)]
pub struct Lockup {
/// Start of the lockup.
pub start_ts: u64,
Expand Down Expand Up @@ -161,10 +162,7 @@ impl Lockup {
}
}

#[repr(u8)]
#[derive(
AnchorSerialize, AnchorDeserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
)]
#[derive(BorshDeserialize, BorshSerialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum LockupPeriod {
None,
Flex,
Expand Down Expand Up @@ -201,8 +199,7 @@ impl LockupPeriod {
}
}

#[repr(u8)]
#[derive(AnchorSerialize, AnchorDeserialize, Debug, Clone, Copy, PartialEq)]
#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Copy, PartialEq)]
pub enum LockupKind {
/// No lockup, tokens can be withdrawn as long as not engaged in a proposal.
None,
Expand Down
4 changes: 3 additions & 1 deletion program-states/src/state/voter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ pub struct Voter {
pub voter_weight_record_bump: u8,
pub _reserved1: [u8; 14],
}
const_assert!(std::mem::size_of::<Voter>() == 80 * 32 + 32 + 32 + 1 + 1 + 14);
const_assert!(std::mem::size_of::<Voter>() == 88 * 32 + 32 + 32 + 1 + 1 + 14);
const_assert!(std::mem::size_of::<Voter>() % 8 == 0);

impl Voter {
pub const MIN_OWN_WEIGHTED_STAKE: u64 = 15_000_000;

/// The full vote weight available to the voter
pub fn weight(&self) -> Result<u64> {
self.deposits
Expand Down
Loading

0 comments on commit b7b51e6

Please sign in to comment.