Skip to content

Commit d5c3fce

Browse files
committed
updateexchangeratev2
1 parent 61a14a3 commit d5c3fce

File tree

9 files changed

+193
-14
lines changed

9 files changed

+193
-14
lines changed

core/src/instructions/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod update_exchange_rate_v2;
12
mod withdraw_v2;
23

4+
pub use update_exchange_rate_v2::*;
35
pub use withdraw_v2::*;
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use generic_array_struct::generic_array_struct;
2+
3+
use crate::{
4+
LIDO_STATE_ADDR, RESERVE_PDA, STSOL_MINT_ADDR, SYSTEM_PROGRAM, SYSVAR_CLOCK, SYSVAR_RENT,
5+
VALIDATOR_LIST_ADDR,
6+
};
7+
8+
#[generic_array_struct(pub)]
9+
#[repr(transparent)]
10+
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
11+
pub struct UpdateExchangeRateV2IxAccs<T> {
12+
pub lido_state: T,
13+
pub reserve: T,
14+
pub stsol_mint: T,
15+
pub validator_list: T,
16+
pub sysvar_clock: T,
17+
pub sysvar_rent: T,
18+
}
19+
20+
pub type UpdateExchangeRateV2IxKeysOwned = UpdateExchangeRateV2IxAccs<[u8; 32]>;
21+
pub type UpdateExchangeRateV2IxKeys<'a> = UpdateExchangeRateV2IxAccs<&'a [u8; 32]>;
22+
pub type UpdateExchangeRateV2IxAccsFlag = UpdateExchangeRateV2IxAccs<bool>;
23+
24+
pub const UPDATE_EXCHANGE_RATE_V2_IX_IS_WRITER: UpdateExchangeRateV2IxAccsFlag =
25+
UpdateExchangeRateV2IxAccsFlag::new([false; UPDATE_EXCHANGE_RATE_V2_IX_ACCS_LEN])
26+
.const_with_lido_state(true);
27+
28+
pub const UPDATE_EXCHANGE_RATE_V2_IX_IS_SIGNER: UpdateExchangeRateV2IxAccsFlag =
29+
UpdateExchangeRateV2IxAccsFlag::new([false; UPDATE_EXCHANGE_RATE_V2_IX_ACCS_LEN]);
30+
31+
impl<T> UpdateExchangeRateV2IxAccs<T> {
32+
#[inline]
33+
pub const fn new(arr: [T; UPDATE_EXCHANGE_RATE_V2_IX_ACCS_LEN]) -> Self {
34+
Self(arr)
35+
}
36+
}
37+
38+
impl UpdateExchangeRateV2IxKeysOwned {
39+
#[inline]
40+
pub fn as_borrowed(&self) -> UpdateExchangeRateV2IxKeys<'_> {
41+
UpdateExchangeRateV2IxKeys::new(self.0.each_ref())
42+
}
43+
}
44+
45+
impl UpdateExchangeRateV2IxKeys<'_> {
46+
#[inline]
47+
pub fn into_owned(self) -> UpdateExchangeRateV2IxKeysOwned {
48+
UpdateExchangeRateV2IxKeysOwned::new(self.0.map(|pk| *pk))
49+
}
50+
}
51+
52+
impl UpdateExchangeRateV2IxKeys<'_> {
53+
/// The account keys input to this ix should never change
54+
pub const CONST: Self = Self::new([&SYSTEM_PROGRAM; UPDATE_EXCHANGE_RATE_V2_IX_ACCS_LEN])
55+
.with_lido_consts()
56+
.with_sol_consts();
57+
58+
#[inline]
59+
pub const fn with_lido_consts(self) -> Self {
60+
self.const_with_lido_state(&LIDO_STATE_ADDR)
61+
.const_with_stsol_mint(&STSOL_MINT_ADDR)
62+
.const_with_validator_list(&VALIDATOR_LIST_ADDR)
63+
.const_with_reserve(&RESERVE_PDA)
64+
}
65+
66+
#[inline]
67+
pub const fn with_sol_consts(self) -> Self {
68+
self.const_with_sysvar_clock(&SYSVAR_CLOCK)
69+
.const_with_sysvar_rent(&SYSVAR_RENT)
70+
}
71+
}
72+
73+
pub const UPDATE_EXCHANGE_RATE_V2_IX_DISCM: u8 = 22;
74+
75+
pub const UPDATE_EXCHANGE_RATE_V2_IX_DATA_LEN: usize = 1;
76+
77+
#[repr(transparent)]
78+
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
79+
pub struct UpdateExchangeRateV2IxData([u8; UPDATE_EXCHANGE_RATE_V2_IX_DATA_LEN]);
80+
81+
impl UpdateExchangeRateV2IxData {
82+
pub const CONST: Self = Self([UPDATE_EXCHANGE_RATE_V2_IX_DISCM]);
83+
84+
#[inline]
85+
pub const fn new() -> Self {
86+
Self::CONST
87+
}
88+
89+
#[inline]
90+
pub const fn to_buf(self) -> [u8; UPDATE_EXCHANGE_RATE_V2_IX_DATA_LEN] {
91+
self.0
92+
}
93+
}

core/src/instructions/withdraw_v2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ use crate::{
55
STSOL_MINT_ADDR, SYSTEM_PROGRAM, SYSVAR_CLOCK, TOKENKEG_PROGRAM, VALIDATOR_LIST_ADDR,
66
};
77

8-
pub const WITHDRAW_V2_IX_DISCM: u8 = 23;
9-
108
#[generic_array_struct(pub)]
119
#[repr(transparent)]
1210
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
@@ -120,6 +118,8 @@ impl WithdrawV2IxKeys<'_> {
120118
}
121119
}
122120

121+
pub const WITHDRAW_V2_IX_DISCM: u8 = 23;
122+
123123
pub const WITHDRAW_V2_IX_DATA_LEN: usize = 13;
124124

125125
#[repr(transparent)]

core/src/keys.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,22 @@ pub const STAKE_AUTH_PDA: [u8; 32] = STAKE_AUTH_PDA_TUP.0;
2020
pub const STAKE_AUTH_PDA_BUMP: u8 = STAKE_AUTH_PDA_TUP.1;
2121
pub const STAKE_AUTH_PDA_STR: &str = bs58::encode_pubkey(&STAKE_AUTH_PDA).str();
2222

23+
const RESERVE_PDA_TUP: ([u8; 32], u8) = derive_program_address(
24+
&[LIDO_STATE_ADDR.as_slice(), b"reserve_account"],
25+
&PROGRAM_ID,
26+
);
27+
pub const RESERVE_PDA: [u8; 32] = RESERVE_PDA_TUP.0;
28+
pub const RESERVE_PDA_BUMP: u8 = RESERVE_PDA_TUP.1;
29+
pub const RESERVE_PDA_STR: &str = bs58::encode_pubkey(&RESERVE_PDA).str();
30+
2331
// solana system-wide consts
2432

2533
pub const SYSVAR_CLOCK: [u8; 32] =
2634
bs58::decode_pubkey("SysvarC1ock11111111111111111111111111111111");
2735

36+
pub const SYSVAR_RENT: [u8; 32] =
37+
bs58::decode_pubkey("SysvarRent111111111111111111111111111111111");
38+
2839
pub const SYSTEM_PROGRAM: [u8; 32] = bs58::decode_pubkey("11111111111111111111111111111111");
2940

3041
pub const STAKE_PROGRAM: [u8; 32] =

core/tests/common/accounts.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,31 @@ impl KeyedUiAccount {
3737
}
3838
}
3939

40+
pub fn lido_mainnet_update_exchange_rate_accounts() -> impl Iterator<Item = (Pubkey, Account)> {
41+
test_fixtures_accounts(["lido", "stsol", "validator-list", "reserve"].as_slice())
42+
}
43+
4044
pub fn lido_mainnet_withdraw_accounts() -> impl Iterator<Item = (Pubkey, Account)> {
41-
[
42-
"largest-vsa",
43-
"lido",
44-
"stsol",
45-
"validator-list",
46-
"largest-vote",
47-
]
48-
.into_iter()
49-
.map(|fname| {
45+
test_fixtures_accounts(
46+
[
47+
"largest-vsa",
48+
"lido",
49+
"stsol",
50+
"validator-list",
51+
"largest-vote",
52+
]
53+
.as_slice(),
54+
)
55+
.chain([(Pubkey::new_from_array(STAKE_AUTH_PDA), Account::default())])
56+
}
57+
58+
fn test_fixtures_accounts<'a>(
59+
fnames: &'a [&'a str],
60+
) -> impl Iterator<Item = (Pubkey, Account)> + 'a {
61+
fnames.iter().map(|fname| {
5062
let KeyedUiAccount { pubkey, account } = KeyedUiAccount::from_test_fixtures_file(fname);
5163
(pubkey.parse().unwrap(), account.decode().unwrap())
5264
})
53-
.chain([(Pubkey::new_from_array(STAKE_AUTH_PDA), Account::default())])
5465
}
5566

5667
pub fn payer_account(lamports: u64) -> Account {

core/tests/common/mollusk.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ pub fn mollusk_lido_prog() -> Mollusk {
1414
&std::fs::read(test_fixtures_dir().join("solido.so")).unwrap(),
1515
&Pubkey::new_from_array(SOLIDO_PROG_OWNER),
1616
);
17-
res.sysvars.clock.epoch = MAINNET_EXCHANGE_RATE_COMPUTED_IN_EPOCH;
18-
res.sysvars.clock.slot = 432_000 * MAINNET_EXCHANGE_RATE_COMPUTED_IN_EPOCH + 69;
17+
warp_to_epoch(&mut res, MAINNET_EXCHANGE_RATE_COMPUTED_IN_EPOCH);
1918
res.feature_set
2019
.deactivate(&Pubkey::new_from_array(MIN_1_SOL_DELEGATION_FEATURE_ID));
2120
mollusk_svm_programs_token::token::add_program(&mut res);
2221
res
2322
}
23+
24+
pub fn warp_to_epoch(mollusk: &mut Mollusk, epoch: u64) {
25+
mollusk.sysvars.warp_to_slot(432_000 * epoch + 69);
26+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
mod update_exchange_rate_v2;
12
mod withdraw_v2;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use mollusk_svm::result::InstructionResult;
2+
use solana_instruction::Instruction;
3+
use solana_pubkey::Pubkey;
4+
use solido_legacy_core::{
5+
UpdateExchangeRateV2IxData, UpdateExchangeRateV2IxKeys, PROGRAM_ID,
6+
UPDATE_EXCHANGE_RATE_V2_IX_IS_SIGNER, UPDATE_EXCHANGE_RATE_V2_IX_IS_WRITER,
7+
};
8+
9+
use crate::common::{
10+
lido_mainnet_update_exchange_rate_accounts, metas_from_keys_signer_writer, mollusk_lido_prog,
11+
warp_to_epoch, MAINNET_EXCHANGE_RATE_COMPUTED_IN_EPOCH,
12+
};
13+
14+
pub fn update_exchange_rate_v2_ix() -> Instruction {
15+
let metas = metas_from_keys_signer_writer(
16+
UpdateExchangeRateV2IxKeys::CONST.into_owned().0,
17+
UPDATE_EXCHANGE_RATE_V2_IX_IS_SIGNER.0,
18+
UPDATE_EXCHANGE_RATE_V2_IX_IS_WRITER.0,
19+
);
20+
let data = UpdateExchangeRateV2IxData::CONST;
21+
Instruction {
22+
program_id: Pubkey::new_from_array(PROGRAM_ID),
23+
accounts: metas,
24+
data: data.to_buf().into(),
25+
}
26+
}
27+
28+
#[test]
29+
fn update_exchange_rate_v2_fixture() {
30+
let mut mollusk = mollusk_lido_prog();
31+
warp_to_epoch(&mut mollusk, MAINNET_EXCHANGE_RATE_COMPUTED_IN_EPOCH + 1);
32+
33+
let ixs = &[update_exchange_rate_v2_ix()];
34+
let accounts: Vec<_> = lido_mainnet_update_exchange_rate_accounts()
35+
.chain([
36+
mollusk.sysvars.keyed_account_for_clock_sysvar(),
37+
mollusk.sysvars.keyed_account_for_rent_sysvar(),
38+
])
39+
.collect();
40+
41+
let InstructionResult { raw_result, .. } = mollusk.process_instruction_chain(ixs, &accounts);
42+
43+
raw_result.unwrap();
44+
}

test-fixtures/reserve.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"pubkey": "3Kwv3pEAuoe4WevPB4rgMBTZndGDb53XT7qwQKnvHPfX",
3+
"account": {
4+
"lamports": 21310345306455,
5+
"data": [
6+
"",
7+
"base64"
8+
],
9+
"owner": "11111111111111111111111111111111",
10+
"executable": false,
11+
"rentEpoch": 18446744073709551615,
12+
"space": 0
13+
}
14+
}

0 commit comments

Comments
 (0)