Skip to content

Commit 889fdc7

Browse files
authoredJan 10, 2025··
[solana] Remove admin from vesting config (#231)
* Remove admin from vesting config seeds * Remove admin from struct VestingConfig * Fix tests * Fix rust test
1 parent e1478a5 commit 889fdc7

11 files changed

+95
-72
lines changed
 

‎solana/programs/staking/src/contexts/cancel_vesting.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
use anchor_lang::prelude::*;
22
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
33

4-
use crate::context::{VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED};
4+
use crate::context::{VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED, CONFIG_SEED};
55
use crate::error::VestingError;
66
use crate::state::{Vesting, VestingBalance, VestingConfig};
7+
use crate::state::global_config::GlobalConfig;
78

89
#[derive(Accounts)]
910
pub struct CancelVesting<'info> {
10-
#[account(mut)]
11+
#[account(
12+
mut,
13+
constraint = global_config.vesting_admin == admin.key()
14+
@ VestingError::InvalidVestingAdmin
15+
)]
1116
admin: Signer<'info>,
1217
mint: InterfaceAccount<'info, Mint>,
1318
#[account(
@@ -18,9 +23,8 @@ pub struct CancelVesting<'info> {
1823
#[account(
1924
mut,
2025
constraint = !config.finalized @ VestingError::VestingFinalized, // Vesting cannot be cancelled after vest is finalized
21-
has_one = admin, // Arbitrary check as admin is baked into the PDA
2226
has_one = mint, // Arbitrary check as mint is baked into the PDA
23-
seeds = [VESTING_CONFIG_SEED.as_bytes(), admin.key().as_ref(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
27+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
2428
bump = config.bump
2529
)]
2630
config: Account<'info, VestingConfig>,
@@ -38,6 +42,11 @@ pub struct CancelVesting<'info> {
3842
bump = vesting_balance.bump
3943
)]
4044
vesting_balance: Account<'info, VestingBalance>,
45+
#[account(
46+
seeds = [CONFIG_SEED.as_bytes()],
47+
bump = global_config.bump,
48+
)]
49+
pub global_config: Box<Account<'info, GlobalConfig>>,
4150
token_program: Interface<'info, TokenInterface>,
4251
system_program: Program<'info, System>,
4352
}

‎solana/programs/staking/src/contexts/claim_vesting.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub struct ClaimVesting<'info> {
3333
#[account(
3434
mut,
3535
constraint = config.finalized @ VestingError::VestingUnfinalized,
36-
seeds = [VESTING_CONFIG_SEED.as_bytes(), global_config.vesting_admin.as_ref(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
36+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
3737
bump = config.bump
3838
)]
3939
config: Account<'info, VestingConfig>,
@@ -154,7 +154,6 @@ impl<'info> ClaimVesting<'info> {
154154

155155
let signer_seeds = [&[
156156
VESTING_CONFIG_SEED.as_bytes(),
157-
self.config.admin.as_ref(),
158157
self.config.mint.as_ref(),
159158
&seed,
160159
&bump,

‎solana/programs/staking/src/contexts/create_vesting.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
use anchor_lang::prelude::*;
22
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
33

4-
use crate::context::{VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED};
4+
use crate::context::{VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, VEST_SEED, CONFIG_SEED};
55
use crate::error::VestingError;
66
use crate::state::{Vesting, VestingBalance, VestingConfig};
7+
use crate::state::global_config::GlobalConfig;
78

89
#[derive(Accounts)]
910
#[instruction(maturation: i64)]
1011
pub struct CreateVesting<'info> {
11-
#[account(mut)]
12+
#[account(
13+
mut,
14+
constraint = global_config.vesting_admin == admin.key()
15+
@ VestingError::InvalidVestingAdmin
16+
)]
1217
admin: Signer<'info>,
1318
mint: InterfaceAccount<'info, Mint>,
1419
#[account(
@@ -19,9 +24,8 @@ pub struct CreateVesting<'info> {
1924
#[account(
2025
mut,
2126
constraint = !config.finalized @ VestingError::VestingFinalized, // Vesting cannot be cancelled after vest is finalized
22-
has_one = admin, // This check is arbitrary, as mint is baked into the PDA
2327
has_one = mint, // This check is arbitrary, as mint is baked into the PDA
24-
seeds = [VESTING_CONFIG_SEED.as_bytes(), admin.key().as_ref(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
28+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
2529
bump = config.bump
2630
)]
2731
config: Account<'info, VestingConfig>,
@@ -39,6 +43,11 @@ pub struct CreateVesting<'info> {
3943
bump = vesting_balance.bump
4044
)]
4145
vesting_balance: Account<'info, VestingBalance>,
46+
#[account(
47+
seeds = [CONFIG_SEED.as_bytes()],
48+
bump = global_config.bump,
49+
)]
50+
pub global_config: Box<Account<'info, GlobalConfig>>,
4251
token_program: Interface<'info, TokenInterface>,
4352
system_program: Program<'info, System>,
4453
}

‎solana/programs/staking/src/contexts/create_vesting_balance.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1-
use crate::context::{VESTING_BALANCE_SEED, VESTING_CONFIG_SEED};
1+
use crate::context::{VESTING_BALANCE_SEED, VESTING_CONFIG_SEED, CONFIG_SEED};
22
use crate::state::{VestingBalance, VestingConfig};
33
use anchor_lang::prelude::*;
44
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
5+
use crate::state::global_config::GlobalConfig;
6+
use crate::error::VestingError;
57

68
#[derive(Accounts)]
79
#[instruction()]
810
pub struct CreateVestingBalance<'info> {
9-
#[account(mut)]
11+
#[account(
12+
mut,
13+
constraint = global_config.vesting_admin == admin.key()
14+
@ VestingError::InvalidVestingAdmin
15+
)]
1016
admin: Signer<'info>,
1117
mint: InterfaceAccount<'info, Mint>,
1218
#[account(
1319
mut,
14-
seeds = [VESTING_CONFIG_SEED.as_bytes(), admin.key().as_ref(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
20+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
1521
bump = config.bump
1622
)]
1723
config: Account<'info, VestingConfig>,
@@ -28,6 +34,11 @@ pub struct CreateVestingBalance<'info> {
2834
token::token_program = token_program
2935
)]
3036
vester_ta: InterfaceAccount<'info, TokenAccount>,
37+
#[account(
38+
seeds = [CONFIG_SEED.as_bytes()],
39+
bump = global_config.bump,
40+
)]
41+
pub global_config: Box<Account<'info, GlobalConfig>>,
3142
token_program: Interface<'info, TokenInterface>,
3243
system_program: Program<'info, System>,
3344
}

‎solana/programs/staking/src/contexts/finalize.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
use crate::context::VESTING_CONFIG_SEED;
1+
use crate::context::{VESTING_CONFIG_SEED, CONFIG_SEED};
22
use crate::error::VestingError;
33
use crate::state::VestingConfig;
44
use anchor_lang::prelude::*;
55
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
6+
use crate::state::global_config::GlobalConfig;
67

78
#[derive(Accounts)]
89
pub struct Finalize<'info> {
9-
#[account(mut)]
10+
#[account(
11+
mut,
12+
constraint = global_config.vesting_admin == admin.key()
13+
@ VestingError::InvalidVestingAdmin
14+
)]
1015
pub admin: Signer<'info>,
1116
pub mint: InterfaceAccount<'info, Mint>,
1217
// Initialize a vault for us to store our money in escrow for vesting
@@ -21,10 +26,15 @@ pub struct Finalize<'info> {
2126
#[account(
2227
mut,
2328
constraint = !config.finalized @ VestingError::VestingFinalized,
24-
seeds = [VESTING_CONFIG_SEED.as_bytes(), admin.key().as_ref(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
29+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
2530
bump = config.bump
2631
)]
2732
config: Account<'info, VestingConfig>,
33+
#[account(
34+
seeds = [CONFIG_SEED.as_bytes()],
35+
bump = global_config.bump,
36+
)]
37+
pub global_config: Box<Account<'info, GlobalConfig>>,
2838
token_program: Interface<'info, TokenInterface>,
2939
}
3040

‎solana/programs/staking/src/contexts/initialize.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub struct Initialize<'info> {
3333
init,
3434
payer = admin,
3535
space = VestingConfig::INIT_SPACE,
36-
seeds = [VESTING_CONFIG_SEED.as_bytes(), admin.key().as_ref(), mint.key().as_ref(), seed.to_le_bytes().as_ref()],
36+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), seed.to_le_bytes().as_ref()],
3737
bump
3838
)]
3939
config: Account<'info, VestingConfig>,
@@ -54,7 +54,6 @@ impl<'info> Initialize<'info> {
5454
pub fn initialize(&mut self, seed: u64, bump: u8) -> Result<()> {
5555
self.config.set_inner(VestingConfig {
5656
mint: self.mint.key(),
57-
admin: self.admin.key(),
5857
recovery: self.recovery.key(),
5958
vested: 0,
6059
finalized: false,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub struct TransferVesting<'info> {
3030
#[account(
3131
mut,
3232
constraint = config.finalized @ VestingError::VestingUnfinalized,
33-
seeds = [VESTING_CONFIG_SEED.as_bytes(), global_config.vesting_admin.as_ref(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
33+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
3434
bump = config.bump
3535
)]
3636
config: Box<Account<'info, VestingConfig>>,

‎solana/programs/staking/src/contexts/withdraw_surplus.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
use crate::context::VESTING_CONFIG_SEED;
1+
use crate::context::{VESTING_CONFIG_SEED, CONFIG_SEED};
22
use crate::error::VestingError;
33
use crate::state::VestingConfig;
44
use anchor_lang::prelude::*;
55
use anchor_spl::associated_token::AssociatedToken;
66
use anchor_spl::token_interface::{
77
transfer_checked, Mint, TokenAccount, TokenInterface, TransferChecked,
88
};
9+
use crate::state::global_config::GlobalConfig;
910

1011
#[derive(Accounts)]
1112
pub struct WithdrawSurplus<'info> {
12-
#[account(mut)]
13+
#[account(
14+
mut,
15+
constraint = global_config.vesting_admin == admin.key()
16+
@ VestingError::InvalidVestingAdmin
17+
)]
1318
admin: Signer<'info>,
1419
#[account(
1520
mut,
@@ -29,10 +34,15 @@ pub struct WithdrawSurplus<'info> {
2934
mut,
3035
constraint = vault.amount > config.vested @ VestingError::NotInSurplus,
3136
has_one = recovery,
32-
seeds = [VESTING_CONFIG_SEED.as_bytes(), admin.key().as_ref(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
37+
seeds = [VESTING_CONFIG_SEED.as_bytes(), mint.key().as_ref(), config.seed.to_le_bytes().as_ref()],
3338
bump = config.bump
3439
)]
3540
config: Account<'info, VestingConfig>,
41+
#[account(
42+
seeds = [CONFIG_SEED.as_bytes()],
43+
bump = global_config.bump,
44+
)]
45+
pub global_config: Box<Account<'info, GlobalConfig>>,
3646
associated_token_program: Program<'info, AssociatedToken>,
3747
token_program: Interface<'info, TokenInterface>,
3848
system_program: Program<'info, System>,
@@ -46,7 +56,6 @@ impl<'info> WithdrawSurplus<'info> {
4656

4757
let signer_seeds = [&[
4858
VESTING_CONFIG_SEED.as_bytes(),
49-
self.config.admin.as_ref(),
5059
self.config.mint.as_ref(),
5160
&seed,
5261
&bump,

‎solana/programs/staking/src/state/vesting_config.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::mem::size_of;
44
#[account]
55
pub struct VestingConfig {
66
pub mint: Pubkey,
7-
pub admin: Pubkey,
87
pub recovery: Pubkey,
98
pub seed: u64,
109
pub vested: u64,
@@ -23,6 +22,6 @@ pub mod tests {
2322

2423
#[test]
2524
fn check_size() {
26-
assert!(VestingConfig::INIT_SPACE == 8 + 32 + 32 + 32 + 8 + 8 + 8); // 128
25+
assert!(VestingConfig::INIT_SPACE == 8 + 32 + 32 + 8 + 8 + 8); // 96
2726
}
2827
}

‎solana/tests/api_test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -916,20 +916,20 @@ describe("api", async () => {
916916
user8StakeConnection.userPublicKey(),
917917
WHTokenBalance.fromString("5"),
918918
);
919-
919+
920920
let currentStakeAccountCheckpointsAddress =
921921
await user8StakeConnection.getStakeAccountCheckpointsAddress(
922922
user8StakeConnection.userPublicKey(),
923923
0,
924924
);
925-
925+
926926
let currentStakeAccountCheckpoints: CheckpointAccount =
927927
await user8StakeConnection.fetchCheckpointAccount(
928928
currentStakeAccountCheckpointsAddress,
929929
);
930930

931931
let currentCheckpointCount = currentStakeAccountCheckpoints.getCheckpointCount();
932-
932+
933933
// Fill all bar 1 checkpoints in the limit. Leave 1 space for the withdraw checkpoint
934934
for (currentCheckpointCount; currentCheckpointCount < TEST_CHECKPOINTS_ACCOUNT_LIMIT - 1; currentCheckpointCount++) {
935935
await sleep(1000);
@@ -961,7 +961,7 @@ describe("api", async () => {
961961

962962
stakeAccountMetadata = await user8StakeConnection.fetchStakeAccountMetadata(user8StakeConnection.userPublicKey());
963963

964-
964+
965965
let newCheckpointAccountIndex = stakeAccountMetadata.stakeAccountCheckpointsLastIndex;
966966
let balanceAfter = stakeAccount.tokenBalance;
967967

@@ -971,7 +971,7 @@ describe("api", async () => {
971971
balanceBefore - balanceAfter,
972972
5000000,
973973
);
974-
974+
975975
});
976976
});
977977

0 commit comments

Comments
 (0)
Please sign in to comment.