Skip to content

Commit d28d75b

Browse files
committed
Fix bug when duplicating mutable checkpoints accounts in transfer_vesting
1 parent f12f881 commit d28d75b

File tree

2 files changed

+307
-44
lines changed

2 files changed

+307
-44
lines changed

solana/programs/staking/src/contexts/transfer_vesting.rs

+58-35
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,25 @@ impl<'info> crate::contexts::TransferVesting<'info> {
104104
return err!(VestingError::TransferVestToMyself);
105105
}
106106

107+
let mut delegate_duplication = false;
108+
if let (
109+
Some(_stake_account_metadata),
110+
Some(_delegate_stake_account_metadata),
111+
Some(delegate_stake_account_checkpoints),
112+
Some(_new_stake_account_metadata),
113+
Some(_new_delegate_stake_account_metadata),
114+
Some(new_delegate_stake_account_checkpoints),
115+
) = (
116+
&mut self.stake_account_metadata,
117+
&mut self.delegate_stake_account_metadata,
118+
&mut self.delegate_stake_account_checkpoints,
119+
&mut self.new_stake_account_metadata,
120+
&mut self.new_delegate_stake_account_metadata,
121+
&mut self.new_delegate_stake_account_checkpoints,
122+
) {
123+
delegate_duplication = delegate_stake_account_checkpoints.key() == new_delegate_stake_account_checkpoints.key();
124+
}
125+
107126
if self.vesting_balance.stake_account_metadata != Pubkey::default() {
108127
if let (
109128
Some(stake_account_metadata),
@@ -185,23 +204,25 @@ impl<'info> crate::contexts::TransferVesting<'info> {
185204

186205
let current_timestamp: u64 = Clock::get()?.unix_timestamp.try_into()?;
187206

188-
push_checkpoint(
189-
delegate_stake_account_checkpoints,
190-
&delegate_checkpoints_account_info,
191-
self.vest.amount,
192-
Operation::Subtract,
193-
current_timestamp,
194-
&self.vester.to_account_info(),
195-
&self.system_program.to_account_info(),
196-
)?;
197-
let loaded_checkpoints = delegate_stake_account_checkpoints.load()?;
198-
if loaded_checkpoints.next_index
199-
>= self.global_config.max_checkpoints_account_limit.into()
200-
{
201-
if delegate_stake_account_metadata.key() == stake_account_metadata.key() {
202-
stake_account_metadata.stake_account_checkpoints_last_index += 1;
203-
} else {
204-
delegate_stake_account_metadata.stake_account_checkpoints_last_index += 1;
207+
if !delegate_duplication {
208+
push_checkpoint(
209+
delegate_stake_account_checkpoints,
210+
&delegate_checkpoints_account_info,
211+
self.vest.amount,
212+
Operation::Subtract,
213+
current_timestamp,
214+
&self.vester.to_account_info(),
215+
&self.system_program.to_account_info(),
216+
)?;
217+
let loaded_checkpoints = delegate_stake_account_checkpoints.load()?;
218+
if loaded_checkpoints.next_index
219+
>= self.global_config.max_checkpoints_account_limit.into()
220+
{
221+
if delegate_stake_account_metadata.key() == stake_account_metadata.key() {
222+
stake_account_metadata.stake_account_checkpoints_last_index += 1;
223+
} else {
224+
delegate_stake_account_metadata.stake_account_checkpoints_last_index += 1;
225+
}
205226
}
206227
}
207228
} else {
@@ -289,26 +310,28 @@ impl<'info> crate::contexts::TransferVesting<'info> {
289310

290311
let current_timestamp: u64 = Clock::get()?.unix_timestamp.try_into()?;
291312

292-
push_checkpoint(
293-
new_delegate_stake_account_checkpoints,
294-
&current_delegate_checkpoints_account_info,
295-
self.vest.amount,
296-
Operation::Add,
297-
current_timestamp,
298-
&self.vester.to_account_info(),
299-
&self.system_program.to_account_info(),
300-
)?;
313+
if !delegate_duplication {
314+
push_checkpoint(
315+
new_delegate_stake_account_checkpoints,
316+
&current_delegate_checkpoints_account_info,
317+
self.vest.amount,
318+
Operation::Add,
319+
current_timestamp,
320+
&self.vester.to_account_info(),
321+
&self.system_program.to_account_info(),
322+
)?;
301323

302-
let loaded_checkpoints = new_delegate_stake_account_checkpoints.load()?;
303-
if loaded_checkpoints.next_index
304-
>= self.global_config.max_checkpoints_account_limit.into()
305-
{
306-
if new_delegate_stake_account_metadata.key() == new_stake_account_metadata.key()
324+
let loaded_checkpoints = new_delegate_stake_account_checkpoints.load()?;
325+
if loaded_checkpoints.next_index
326+
>= self.global_config.max_checkpoints_account_limit.into()
307327
{
308-
new_stake_account_metadata.stake_account_checkpoints_last_index += 1;
309-
} else {
310-
new_delegate_stake_account_metadata.stake_account_checkpoints_last_index +=
311-
1;
328+
if new_delegate_stake_account_metadata.key() == new_stake_account_metadata.key()
329+
{
330+
new_stake_account_metadata.stake_account_checkpoints_last_index += 1;
331+
} else {
332+
new_delegate_stake_account_metadata.stake_account_checkpoints_last_index +=
333+
1;
334+
}
312335
}
313336
}
314337
} else {

0 commit comments

Comments
 (0)