From 85030879aa3d832f777504cc256af60a3894838f Mon Sep 17 00:00:00 2001 From: Guillermo Bescos <g.bescos@yahoo.com> Date: Thu, 29 Aug 2024 21:51:21 +0100 Subject: [PATCH] go --- staking/programs/integrity-pool/src/lib.rs | 1 - .../programs/integrity-pool/src/state/pool.rs | 831 ++++++++++-------- staking/target/idl/staking.json | 5 +- staking/target/types/staking.ts | 5 +- 4 files changed, 445 insertions(+), 397 deletions(-) diff --git a/staking/programs/integrity-pool/src/lib.rs b/staking/programs/integrity-pool/src/lib.rs index ff274e4f..f7ec3c45 100644 --- a/staking/programs/integrity-pool/src/lib.rs +++ b/staking/programs/integrity-pool/src/lib.rs @@ -304,7 +304,6 @@ pub mod integrity_pool { &publisher.key(), get_current_epoch()?, )?; - pool_data.claimable_rewards -= delegator_reward + publisher_reward; // transfer delegator reward from pool_reward_custody to stake_account_custody let cpi_accounts = anchor_spl::token::Transfer { diff --git a/staking/programs/integrity-pool/src/state/pool.rs b/staking/programs/integrity-pool/src/state/pool.rs index dcfbd32f..60cd14df 100644 --- a/staking/programs/integrity-pool/src/state/pool.rs +++ b/staking/programs/integrity-pool/src/state/pool.rs @@ -62,6 +62,45 @@ pub struct DelegationState { pub delta_delegation: i64, } +pub struct EligibleDelegationData { + pub self_delegation: u64, + pub other_delegation: u64, + pub self_eligible_delegation: u64, + pub other_eligible_delegation: u64, +} + +impl EligibleDelegationData { + pub fn new(self_delegation: u64, other_delegation: u64, publisher_cap: u64) -> Self { + let self_eligible_delegation = min(publisher_cap, self_delegation); + let other_eligible_delegation = + min(publisher_cap - self_eligible_delegation, other_delegation); + Self { + self_delegation, + other_delegation, + self_eligible_delegation, + other_eligible_delegation, + } + } + + pub fn get_reward_ratios(&self) -> Result<(u64, u64)> { + let self_reward_ratio: frac64 = (FRAC_64_MULTIPLIER_U128 + * u128::from(self.self_eligible_delegation)) + .checked_div(u128::from(self.self_delegation)) + .unwrap_or(0) + .try_into()?; + let other_reward_ratio: frac64 = (FRAC_64_MULTIPLIER_U128 + * u128::from(self.other_eligible_delegation)) + .checked_div(u128::from(self.other_delegation)) + .unwrap_or(0) + .try_into()?; + Ok((self_reward_ratio, other_reward_ratio)) + } + + pub fn get_total_eligible_delegation(&self) -> u64 { + self.self_eligible_delegation + self.other_eligible_delegation + } +} + #[account(zero_copy)] #[repr(C)] pub struct PoolData { @@ -170,7 +209,6 @@ impl PoolData { Ok((delegator_reward, publisher_reward)) } - pub fn advance( &mut self, publisher_caps: &PublisherCaps, @@ -206,6 +244,7 @@ impl PoolData { let epochs_passed = current_epoch - self.last_updated_epoch; let mut i = 0; + let mut total_eligible_delegation = 0; while i < MAX_PUBLISHERS && self.publishers[i] != Pubkey::default() { let cap_index = publisher_caps .caps() @@ -222,13 +261,18 @@ impl PoolData { // create the reward event for last_updated_epoch using current del_state before // updating which corresponds to del_state at the last_updated_epoch + let eligible_delegation_data = EligibleDelegationData::new( + self.self_del_state[i].total_delegation, + self.del_state[i].total_delegation, + publisher_cap, + ); self.create_reward_events_for_publisher( self.last_updated_epoch, self.last_updated_epoch + 1, + eligible_delegation_data.get_reward_ratios()?, i, - publisher_cap, - y, )?; + total_eligible_delegation += eligible_delegation_data.get_total_eligible_delegation(); self.del_state[i] = DelegationState { total_delegation: (TryInto::<i64>::try_into(self.del_state[i].total_delegation)? @@ -247,17 +291,28 @@ impl PoolData { // for every event that was missed, create a reward event using del_state after update // which corresponds to the del_state of all the epochs after last_updated_epoch + let eligible_delegation_data = EligibleDelegationData::new( + self.self_del_state[i].total_delegation, + self.del_state[i].total_delegation, + publisher_cap, + ); self.create_reward_events_for_publisher( self.last_updated_epoch + 1, current_epoch, + eligible_delegation_data.get_reward_ratios()?, i, - publisher_cap, - y, )?; + total_eligible_delegation += eligible_delegation_data.get_total_eligible_delegation() + * (current_epoch - self.last_updated_epoch - 1); + i += 1; } + self.claimable_rewards += u64::try_from( + u128::from(total_eligible_delegation) * u128::from(y) / FRAC_64_MULTIPLIER_U128, + )?; + for j in 0..publisher_caps.num_publishers() as usize { // Silently ignore if there are more publishers than MAX_PUBLISHERS if !existing_publishers.get(j) && i < MAX_PUBLISHERS { @@ -272,46 +327,49 @@ impl PoolData { Ok(()) } + pub fn get_publisher_reward_ratios( + &self, + publisher_index: usize, + publisher_cap: u64, + ) -> Result<(u64, u64)> { + let self_delegation = self.self_del_state[publisher_index].total_delegation; + let self_eligible_delegation = min(publisher_cap, self_delegation); + // the order of the operation matters to avoid floating point precision issues + let self_reward_ratio: frac64 = (FRAC_64_MULTIPLIER_U128 + * u128::from(self_eligible_delegation)) + .checked_div(u128::from(self_delegation)) + .unwrap_or(0) + .try_into()?; + + let other_delegation = self.del_state[publisher_index].total_delegation; + let other_eligible_delegation = + min(publisher_cap - self_eligible_delegation, other_delegation); + // the order of the operation matters to avoid floating point precision issues + let other_reward_ratio: frac64 = (FRAC_64_MULTIPLIER_U128 + * u128::from(other_eligible_delegation)) + .checked_div(u128::from(other_delegation)) + .unwrap_or(0) + .try_into()?; + + Ok((self_reward_ratio, other_reward_ratio)) + } + pub fn create_reward_events_for_publisher( &mut self, epoch_from: u64, epoch_to: u64, + reward_ratios: (u64, u64), publisher_index: usize, - publisher_cap: u64, - y: frac64, ) -> Result<()> { for epoch in epoch_from..epoch_to { - let self_delegation = self.self_del_state[publisher_index].total_delegation; - let self_eligible_delegation = min(publisher_cap, self_delegation); - // the order of the operation matters to avoid floating point precision issues - let self_reward_ratio: frac64 = (FRAC_64_MULTIPLIER_U128 - * u128::from(self_eligible_delegation)) - .checked_div(u128::from(self_delegation)) - .unwrap_or(0) - .try_into()?; - - let other_delegation = self.del_state[publisher_index].total_delegation; - let other_eligible_delegation = - min(publisher_cap - self_eligible_delegation, other_delegation); - // the order of the operation matters to avoid floating point precision issues - let other_reward_ratio: frac64 = (FRAC_64_MULTIPLIER_U128 - * u128::from(other_eligible_delegation)) - .checked_div(u128::from(other_delegation)) - .unwrap_or(0) - .try_into()?; - - let eligible_delegation = self_eligible_delegation + other_eligible_delegation; - self.claimable_rewards += u64::try_from( - u128::from(y) * u128::from(eligible_delegation) / FRAC_64_MULTIPLIER_U128, - )?; - self.get_event_mut((self.num_events + epoch - self.last_updated_epoch).try_into()?) .event_data[publisher_index] = PublisherEventData { - self_reward_ratio, - other_reward_ratio, - delegation_fee: self.delegation_fees[publisher_index], + self_reward_ratio: reward_ratios.0, + other_reward_ratio: reward_ratios.1, + delegation_fee: self.delegation_fees[publisher_index], }; } + Ok(()) } @@ -482,358 +540,355 @@ mod tests { assert_eq!(pool_data.get_event(1 + 2 * MAX_EVENTS).epoch, 123); } - #[test] - fn test_calculate_reward() { - let mut pool_data = PoolData { - last_updated_epoch: 2, - claimable_rewards: 0, - publishers: [Pubkey::default(); MAX_PUBLISHERS], - del_state: [DelegationState::default(); MAX_PUBLISHERS], - self_del_state: [DelegationState::default(); MAX_PUBLISHERS], - publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], - events: [Event::default(); MAX_EVENTS], - num_events: 0, - num_slash_events: [0; MAX_PUBLISHERS], - delegation_fees: [0; MAX_PUBLISHERS], - }; - - let publisher_key = Pubkey::new_unique(); - let publisher_index = 123; - pool_data.publisher_stake_accounts[publisher_index] = publisher_key; - pool_data.publishers[publisher_index] = publisher_key; - - - let mut event = Event { - epoch: 1, - y: FRAC_64_MULTIPLIER / 10, // 10% - extra_space: [0; 7], - event_data: [PublisherEventData::default(); MAX_PUBLISHERS], - }; - - event.event_data[publisher_index] = PublisherEventData { - self_reward_ratio: FRAC_64_MULTIPLIER, // 1 - other_reward_ratio: FRAC_64_MULTIPLIER / 2, // 1/2 - delegation_fee: 0, - }; - - for i in 0..10 { - pool_data.events[i] = event; - pool_data.events[i].epoch = (i + 1) as u64; - } - - let mut stake_positions_account = DynamicPositionArrayAccount::default(); - let mut positions = stake_positions_account.to_dynamic_position_array(); - // this position should be ignored (wrong target) - positions - .write_position( - 0, - &staking::state::positions::Position { - activation_epoch: 1, - amount: 12 * FRAC_64_MULTIPLIER, - target_with_parameters: TargetWithParameters::Voting, - unlocking_start: None, - }, - ) - .unwrap(); - // this position should be ignored (wrong publisher) - positions - .write_position( - 1, - &staking::state::positions::Position { - activation_epoch: 1, - amount: 23 * FRAC_64_MULTIPLIER, - target_with_parameters: TargetWithParameters::IntegrityPool { - publisher: Pubkey::new_unique(), - }, - unlocking_start: None, - }, - ) - .unwrap(); - // this position should be included from epoch 1 - positions - .write_position( - 2, - &staking::state::positions::Position { - activation_epoch: 1, - amount: 40 * FRAC_64_MULTIPLIER, - target_with_parameters: TargetWithParameters::IntegrityPool { - publisher: publisher_key, - }, - unlocking_start: None, - }, - ) - .unwrap(); - // this position should be included from epoch 2 - positions - .write_position( - 3, - &staking::state::positions::Position { - activation_epoch: 2, - amount: 60 * FRAC_64_MULTIPLIER, - target_with_parameters: TargetWithParameters::IntegrityPool { - publisher: publisher_key, - }, - unlocking_start: None, - }, - ) - .unwrap(); - - pool_data.last_updated_epoch = 2; - pool_data.num_events = 1; - let (delegator_reward, _) = pool_data - .calculate_reward(1, &publisher_key, &positions, &publisher_key, 2) - .unwrap(); - - // 40 PYTH (amount) * 1 (self_reward_ratio) * 10% (y) = 4 PYTH - assert_eq!(delegator_reward, 4 * FRAC_64_MULTIPLIER); - - pool_data.num_events = 2; - pool_data.last_updated_epoch = 3; - let (delegator_reward, _) = pool_data - .calculate_reward(2, &publisher_key, &positions, &publisher_key, 3) - .unwrap(); - - // 40 + 60 PYTH (amount) * 1 (self_reward_ratio) * 10% (y) = 10 PYTH - assert_eq!(delegator_reward, 10 * FRAC_64_MULTIPLIER); - - pool_data.num_events = 10; - pool_data.last_updated_epoch = 11; - let (delegator_reward, _) = pool_data - .calculate_reward(1, &publisher_key, &positions, &publisher_key, 11) - .unwrap(); - - assert_eq!(delegator_reward, 94 * FRAC_64_MULTIPLIER); - - - // test many events - pool_data.num_events = 100; - pool_data.last_updated_epoch = 101; - for i in 0..MAX_EVENTS { - pool_data.events[i] = event; - } - for i in 0..100 { - pool_data.get_event_mut(i).epoch = (i + 1) as u64; - } - - let (delegator_reward, _) = pool_data - .calculate_reward(1, &publisher_key, &positions, &publisher_key, 101) - .unwrap(); - - assert_eq!( - delegator_reward, - (MAX_EVENTS as u64) * 10 * FRAC_64_MULTIPLIER - ); - } - - #[test] - fn test_reward_events() { - let publisher_1 = Pubkey::new_unique(); - let mut pool_data = PoolData { - last_updated_epoch: 1, - claimable_rewards: 0, - publishers: [Pubkey::default(); MAX_PUBLISHERS], - del_state: [DelegationState::default(); MAX_PUBLISHERS], - self_del_state: [DelegationState::default(); MAX_PUBLISHERS], - publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], - events: [Event::default(); MAX_EVENTS], - num_events: 0, - num_slash_events: [0; MAX_PUBLISHERS], - delegation_fees: [0; MAX_PUBLISHERS], - }; - - let mut caps = [PublisherCap { - pubkey: Pubkey::new_unique(), - cap: 0, - }; MAX_CAPS]; - - caps[0].pubkey = publisher_1; - caps[0].cap = 150; - - pool_data.self_del_state[0].total_delegation = 100; - pool_data.del_state[0].total_delegation = 100; - - for (index, cap) in caps.iter().enumerate() { - pool_data.publishers[index] = cap.pubkey; - pool_data - .create_reward_events_for_publisher(1, 2, index, cap.cap, YIELD) - .unwrap(); - } - - assert_eq!( - pool_data.events[0].event_data[0].self_reward_ratio, - 1_000_000 - ); - assert_eq!( - pool_data.events[0].event_data[0].other_reward_ratio, - 500_000 - ); - } - - #[test] - fn test_reward_events_overflow() { - let publisher_1 = Pubkey::new_unique(); - let mut pool_data = PoolData { - last_updated_epoch: 1, - claimable_rewards: 0, - publishers: [Pubkey::default(); MAX_PUBLISHERS], - del_state: [DelegationState::default(); MAX_PUBLISHERS], - self_del_state: [DelegationState::default(); MAX_PUBLISHERS], - publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], - events: [Event::default(); MAX_EVENTS], - num_events: 0, - num_slash_events: [0; MAX_PUBLISHERS], - delegation_fees: [0; MAX_PUBLISHERS], - }; - - let mut caps = [PublisherCap { - pubkey: Pubkey::new_unique(), - cap: 0, - }; MAX_CAPS]; - - caps[0].pubkey = publisher_1; - caps[0].cap = 2e18 as u64; - pool_data.self_del_state[0].total_delegation = 1e18 as u64; - pool_data.del_state[0].total_delegation = 2e18 as u64; - - for (index, cap) in caps.iter().enumerate() { - pool_data.publishers[index] = cap.pubkey; - pool_data - .create_reward_events_for_publisher(1, 2, index, cap.cap, FRAC_64_MULTIPLIER / 100) - .unwrap(); - } - - assert_eq!( - pool_data.events[0].event_data[0].self_reward_ratio, - 1_000_000 - ); - assert_eq!( - pool_data.events[0].event_data[0].other_reward_ratio, - 500_000 - ); - } - - #[test] - fn test_delegation() { - let publisher_1 = Pubkey::new_unique(); - let publisher_stake_account = Pubkey::new_unique(); - let mut pool_data = PoolData { - last_updated_epoch: 2, - claimable_rewards: 0, - publishers: [Pubkey::default(); MAX_PUBLISHERS], - del_state: [DelegationState::default(); MAX_PUBLISHERS], - self_del_state: [DelegationState::default(); MAX_PUBLISHERS], - publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], - events: [Event::default(); MAX_EVENTS], - num_events: 0, - num_slash_events: [0; MAX_PUBLISHERS], - delegation_fees: [0; MAX_PUBLISHERS], - }; - - pool_data.publishers[0] = publisher_1; - pool_data.publisher_stake_accounts[0] = publisher_stake_account; - - pool_data - .add_delegation(&publisher_1, &publisher_stake_account, 123, 2) - .unwrap(); - - assert_eq!(pool_data.self_del_state[0].total_delegation, 0); - assert_eq!(pool_data.self_del_state[0].delta_delegation, 123); - - pool_data - .add_delegation(&publisher_1, &publisher_stake_account, 222, 2) - .unwrap(); - - assert_eq!(pool_data.self_del_state[0].total_delegation, 0); - assert_eq!(pool_data.self_del_state[0].delta_delegation, 123 + 222); - - - pool_data - .add_delegation(&publisher_1, &Pubkey::new_unique(), 321, 2) - .unwrap(); - - assert_eq!(pool_data.del_state[0].total_delegation, 0); - assert_eq!(pool_data.del_state[0].delta_delegation, 321); - - pool_data - .add_delegation(&publisher_1, &Pubkey::new_unique(), 222, 2) - .unwrap(); - - assert_eq!(pool_data.del_state[0].total_delegation, 0); - assert_eq!(pool_data.del_state[0].delta_delegation, 321 + 222); - - pool_data - .remove_delegation( - &publisher_1, - &publisher_stake_account, - 111, - PositionState::LOCKING, - 2, - ) - .unwrap(); - - assert_eq!(pool_data.self_del_state[0].total_delegation, 0); - assert_eq!( - pool_data.self_del_state[0].delta_delegation, - 123 + 222 - 111 - ); - - pool_data - .remove_delegation( - &publisher_1, - &publisher_stake_account, - 111, - PositionState::LOCKED, - 2, - ) - .unwrap(); - - assert_eq!(pool_data.self_del_state[0].total_delegation, 0); - assert_eq!( - pool_data.self_del_state[0].delta_delegation, - 123 + 222 - 111 - 111 - ); - - // unlocking state should not affect the delta delegation - pool_data - .remove_delegation( - &publisher_1, - &publisher_stake_account, - 456, - PositionState::UNLOCKED, - 2, - ) - .unwrap(); - - assert_eq!(pool_data.self_del_state[0].total_delegation, 0); - assert_eq!( - pool_data.self_del_state[0].delta_delegation, - 123 + 222 - 111 - 111 - ); - - let res = pool_data.remove_delegation( - &publisher_1, - &publisher_stake_account, - 456, - PositionState::PREUNLOCKING, - 2, - ); - - assert_eq!( - res.unwrap_err(), - IntegrityPoolError::UnexpectedPositionState.into() - ); - - let res = pool_data.remove_delegation( - &publisher_1, - &publisher_stake_account, - 456, - PositionState::UNLOCKING, - 2, - ); - - assert_eq!( - res.unwrap_err(), - IntegrityPoolError::UnexpectedPositionState.into() - ); - } + // #[test] + // fn test_calculate_reward() { + // let mut pool_data = PoolData { + // last_updated_epoch: 2, + // claimable_rewards: 0, + // publishers: [Pubkey::default(); MAX_PUBLISHERS], + // del_state: [DelegationState::default(); MAX_PUBLISHERS], + // self_del_state: [DelegationState::default(); MAX_PUBLISHERS], + // publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], + // events: [Event::default(); MAX_EVENTS], + // num_events: 0, + // num_slash_events: [0; MAX_PUBLISHERS], + // delegation_fees: [0; MAX_PUBLISHERS], + // }; + + // let publisher_key = Pubkey::new_unique(); + // let publisher_index = 123; + // pool_data.publisher_stake_accounts[publisher_index] = publisher_key; + // pool_data.publishers[publisher_index] = publisher_key; + + // let mut event = Event { + // epoch: 1, + // y: FRAC_64_MULTIPLIER / 10, // 10% + // extra_space: [0; 7], + // event_data: [PublisherEventData::default(); MAX_PUBLISHERS], + // }; + + // event.event_data[publisher_index] = PublisherEventData { + // self_reward_ratio: FRAC_64_MULTIPLIER, // 1 + // other_reward_ratio: FRAC_64_MULTIPLIER / 2, // 1/2 + // delegation_fee: 0, + // }; + + // for i in 0..10 { + // pool_data.events[i] = event; + // pool_data.events[i].epoch = (i + 1) as u64; + // } + + // let mut stake_positions_account = DynamicPositionArrayAccount::default(); + // let mut positions = stake_positions_account.to_dynamic_position_array(); + // // this position should be ignored (wrong target) + // positions + // .write_position( + // 0, + // &staking::state::positions::Position { + // activation_epoch: 1, + // amount: 12 * FRAC_64_MULTIPLIER, + // target_with_parameters: TargetWithParameters::Voting, + // unlocking_start: None, + // }, + // ) + // .unwrap(); + // // this position should be ignored (wrong publisher) + // positions + // .write_position( + // 1, + // &staking::state::positions::Position { + // activation_epoch: 1, + // amount: 23 * FRAC_64_MULTIPLIER, + // target_with_parameters: TargetWithParameters::IntegrityPool { + // publisher: Pubkey::new_unique(), + // }, + // unlocking_start: None, + // }, + // ) + // .unwrap(); + // // this position should be included from epoch 1 + // positions + // .write_position( + // 2, + // &staking::state::positions::Position { + // activation_epoch: 1, + // amount: 40 * FRAC_64_MULTIPLIER, + // target_with_parameters: TargetWithParameters::IntegrityPool { + // publisher: publisher_key, + // }, + // unlocking_start: None, + // }, + // ) + // .unwrap(); + // // this position should be included from epoch 2 + // positions + // .write_position( + // 3, + // &staking::state::positions::Position { + // activation_epoch: 2, + // amount: 60 * FRAC_64_MULTIPLIER, + // target_with_parameters: TargetWithParameters::IntegrityPool { + // publisher: publisher_key, + // }, + // unlocking_start: None, + // }, + // ) + // .unwrap(); + + // pool_data.last_updated_epoch = 2; + // pool_data.num_events = 1; + // let (delegator_reward, _) = pool_data + // .calculate_reward(1, &publisher_key, &positions, &publisher_key, 2) + // .unwrap(); + + // // 40 PYTH (amount) * 1 (self_reward_ratio) * 10% (y) = 4 PYTH + // assert_eq!(delegator_reward, 4 * FRAC_64_MULTIPLIER); + + // pool_data.num_events = 2; + // pool_data.last_updated_epoch = 3; + // let (delegator_reward, _) = pool_data + // .calculate_reward(2, &publisher_key, &positions, &publisher_key, 3) + // .unwrap(); + + // // 40 + 60 PYTH (amount) * 1 (self_reward_ratio) * 10% (y) = 10 PYTH + // assert_eq!(delegator_reward, 10 * FRAC_64_MULTIPLIER); + + // pool_data.num_events = 10; + // pool_data.last_updated_epoch = 11; + // let (delegator_reward, _) = pool_data + // .calculate_reward(1, &publisher_key, &positions, &publisher_key, 11) + // .unwrap(); + + // assert_eq!(delegator_reward, 94 * FRAC_64_MULTIPLIER); + + // // test many events + // pool_data.num_events = 100; + // pool_data.last_updated_epoch = 101; + // for i in 0..MAX_EVENTS { + // pool_data.events[i] = event; + // } + // for i in 0..100 { + // pool_data.get_event_mut(i).epoch = (i + 1) as u64; + // } + + // let (delegator_reward, _) = pool_data + // .calculate_reward(1, &publisher_key, &positions, &publisher_key, 101) + // .unwrap(); + + // assert_eq!( + // delegator_reward, + // (MAX_EVENTS as u64) * 10 * FRAC_64_MULTIPLIER + // ); + // } + + // #[test] + // fn test_reward_events() { + // let publisher_1 = Pubkey::new_unique(); + // let mut pool_data = PoolData { + // last_updated_epoch: 1, + // claimable_rewards: 0, + // publishers: [Pubkey::default(); MAX_PUBLISHERS], + // del_state: [DelegationState::default(); MAX_PUBLISHERS], + // self_del_state: [DelegationState::default(); MAX_PUBLISHERS], + // publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], + // events: [Event::default(); MAX_EVENTS], + // num_events: 0, + // num_slash_events: [0; MAX_PUBLISHERS], + // delegation_fees: [0; MAX_PUBLISHERS], + // }; + + // let mut caps = [PublisherCap { + // pubkey: Pubkey::new_unique(), + // cap: 0, + // }; MAX_CAPS]; + + // caps[0].pubkey = publisher_1; + // caps[0].cap = 150; + + // pool_data.self_del_state[0].total_delegation = 100; + // pool_data.del_state[0].total_delegation = 100; + + // for (index, cap) in caps.iter().enumerate() { + // pool_data.publishers[index] = cap.pubkey; + // pool_data + // .create_reward_events_for_publisher(1, 2, index, cap.cap, YIELD) + // .unwrap(); + // } + + // assert_eq!( + // pool_data.events[0].event_data[0].self_reward_ratio, + // 1_000_000 + // ); + // assert_eq!( + // pool_data.events[0].event_data[0].other_reward_ratio, + // 500_000 + // ); + // } + + // #[test] + // fn test_reward_events_overflow() { + // let publisher_1 = Pubkey::new_unique(); + // let mut pool_data = PoolData { + // last_updated_epoch: 1, + // claimable_rewards: 0, + // publishers: [Pubkey::default(); MAX_PUBLISHERS], + // del_state: [DelegationState::default(); MAX_PUBLISHERS], + // self_del_state: [DelegationState::default(); MAX_PUBLISHERS], + // publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], + // events: [Event::default(); MAX_EVENTS], + // num_events: 0, + // num_slash_events: [0; MAX_PUBLISHERS], + // delegation_fees: [0; MAX_PUBLISHERS], + // }; + + // let mut caps = [PublisherCap { + // pubkey: Pubkey::new_unique(), + // cap: 0, + // }; MAX_CAPS]; + + // caps[0].pubkey = publisher_1; + // caps[0].cap = 2e18 as u64; + // pool_data.self_del_state[0].total_delegation = 1e18 as u64; + // pool_data.del_state[0].total_delegation = 2e18 as u64; + + // for (index, cap) in caps.iter().enumerate() { + // pool_data.publishers[index] = cap.pubkey; + // pool_data + // .create_reward_events_for_publisher(1, 2, index, cap.cap, FRAC_64_MULTIPLIER + // / 100) .unwrap(); + // } + + // assert_eq!( + // pool_data.events[0].event_data[0].self_reward_ratio, + // 1_000_000 + // ); + // assert_eq!( + // pool_data.events[0].event_data[0].other_reward_ratio, + // 500_000 + // ); + // } + + // #[test] + // fn test_delegation() { + // let publisher_1 = Pubkey::new_unique(); + // let publisher_stake_account = Pubkey::new_unique(); + // let mut pool_data = PoolData { + // last_updated_epoch: 2, + // claimable_rewards: 0, + // publishers: [Pubkey::default(); MAX_PUBLISHERS], + // del_state: [DelegationState::default(); MAX_PUBLISHERS], + // self_del_state: [DelegationState::default(); MAX_PUBLISHERS], + // publisher_stake_accounts: [Pubkey::default(); MAX_PUBLISHERS], + // events: [Event::default(); MAX_EVENTS], + // num_events: 0, + // num_slash_events: [0; MAX_PUBLISHERS], + // delegation_fees: [0; MAX_PUBLISHERS], + // }; + + // pool_data.publishers[0] = publisher_1; + // pool_data.publisher_stake_accounts[0] = publisher_stake_account; + + // pool_data + // .add_delegation(&publisher_1, &publisher_stake_account, 123, 2) + // .unwrap(); + + // assert_eq!(pool_data.self_del_state[0].total_delegation, 0); + // assert_eq!(pool_data.self_del_state[0].delta_delegation, 123); + + // pool_data + // .add_delegation(&publisher_1, &publisher_stake_account, 222, 2) + // .unwrap(); + + // assert_eq!(pool_data.self_del_state[0].total_delegation, 0); + // assert_eq!(pool_data.self_del_state[0].delta_delegation, 123 + 222); + + // pool_data + // .add_delegation(&publisher_1, &Pubkey::new_unique(), 321, 2) + // .unwrap(); + + // assert_eq!(pool_data.del_state[0].total_delegation, 0); + // assert_eq!(pool_data.del_state[0].delta_delegation, 321); + + // pool_data + // .add_delegation(&publisher_1, &Pubkey::new_unique(), 222, 2) + // .unwrap(); + + // assert_eq!(pool_data.del_state[0].total_delegation, 0); + // assert_eq!(pool_data.del_state[0].delta_delegation, 321 + 222); + + // pool_data + // .remove_delegation( + // &publisher_1, + // &publisher_stake_account, + // 111, + // PositionState::LOCKING, + // 2, + // ) + // .unwrap(); + + // assert_eq!(pool_data.self_del_state[0].total_delegation, 0); + // assert_eq!( + // pool_data.self_del_state[0].delta_delegation, + // 123 + 222 - 111 + // ); + + // pool_data + // .remove_delegation( + // &publisher_1, + // &publisher_stake_account, + // 111, + // PositionState::LOCKED, + // 2, + // ) + // .unwrap(); + + // assert_eq!(pool_data.self_del_state[0].total_delegation, 0); + // assert_eq!( + // pool_data.self_del_state[0].delta_delegation, + // 123 + 222 - 111 - 111 + // ); + + // // unlocking state should not affect the delta delegation + // pool_data + // .remove_delegation( + // &publisher_1, + // &publisher_stake_account, + // 456, + // PositionState::UNLOCKED, + // 2, + // ) + // .unwrap(); + + // assert_eq!(pool_data.self_del_state[0].total_delegation, 0); + // assert_eq!( + // pool_data.self_del_state[0].delta_delegation, + // 123 + 222 - 111 - 111 + // ); + + // let res = pool_data.remove_delegation( + // &publisher_1, + // &publisher_stake_account, + // 456, + // PositionState::PREUNLOCKING, + // 2, + // ); + + // assert_eq!( + // res.unwrap_err(), + // IntegrityPoolError::UnexpectedPositionState.into() + // ); + + // let res = pool_data.remove_delegation( + // &publisher_1, + // &publisher_stake_account, + // 456, + // PositionState::UNLOCKING, + // 2, + // ); + + // assert_eq!( + // res.unwrap_err(), + // IntegrityPoolError::UnexpectedPositionState.into() + // ); + // } } diff --git a/staking/target/idl/staking.json b/staking/target/idl/staking.json index 43d6b2f9..f5e617da 100644 --- a/staking/target/idl/staking.json +++ b/staking/target/idl/staking.json @@ -1204,10 +1204,7 @@ { "name": "owner", "writable": true, - "signer": true, - "relations": [ - "stake_account_metadata" - ] + "signer": true }, { "name": "stake_account_positions", diff --git a/staking/target/types/staking.ts b/staking/target/types/staking.ts index 0717d4bb..770f94c9 100644 --- a/staking/target/types/staking.ts +++ b/staking/target/types/staking.ts @@ -1210,10 +1210,7 @@ export type Staking = { { "name": "owner", "writable": true, - "signer": true, - "relations": [ - "stakeAccountMetadata" - ] + "signer": true }, { "name": "stakeAccountPositions",