Skip to content

Commit 8a92aab

Browse files
RadiantAeonranope-finance
authored
Lite refresh reserve (#59)
* lite refresh that doesn't take the oracle price when depositing * mark reserve as stale * format * added fask track for repay and made a test * check that reserve is stale after depositing * clean up Co-authored-by: ra <[email protected]> Co-authored-by: Nope X <[email protected]>
1 parent fe19117 commit 8a92aab

File tree

3 files changed

+108
-21
lines changed

3 files changed

+108
-21
lines changed

token-lending/program/src/processor.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,23 @@ fn _refresh_reserve<'a>(
411411
}
412412

413413
reserve.liquidity.market_price = get_price(switchboard_feed_info, pyth_price_info, clock)?;
414+
Reserve::pack(reserve, &mut reserve_info.data.borrow_mut())?;
415+
416+
_refresh_reserve_interest(program_id, reserve_info, clock)
417+
}
418+
419+
/// Lite version of refresh_reserve that should be used when the oracle price doesn't need to be updated
420+
/// BE CAREFUL WHEN USING THIS
421+
fn _refresh_reserve_interest<'a>(
422+
program_id: &Pubkey,
423+
reserve_info: &AccountInfo<'a>,
424+
clock: &Clock,
425+
) -> ProgramResult {
426+
let mut reserve = Reserve::unpack(&reserve_info.data.borrow())?;
427+
if reserve_info.owner != program_id {
428+
msg!("Reserve provided is not owned by the lending program");
429+
return Err(LendingError::InvalidAccountOwner.into());
430+
}
414431

415432
reserve.accrue_interest(clock.slot)?;
416433
reserve.last_update.update_slot(clock.slot);
@@ -483,7 +500,6 @@ fn _deposit_reserve_liquidity<'a>(
483500
msg!("Lending market token program does not match the token program provided");
484501
return Err(LendingError::InvalidTokenProgram.into());
485502
}
486-
487503
let mut reserve = Reserve::unpack(&reserve_info.data.borrow())?;
488504
if reserve_info.owner != program_id {
489505
msg!("Reserve provided is not owned by the lending program");
@@ -513,7 +529,6 @@ fn _deposit_reserve_liquidity<'a>(
513529
msg!("Reserve is stale and must be refreshed in the current slot");
514530
return Err(LendingError::ReserveStale.into());
515531
}
516-
517532
let authority_signer_seeds = &[
518533
lending_market_info.key.as_ref(),
519534
&[lending_market.bump_seed],
@@ -971,7 +986,6 @@ fn _deposit_obligation_collateral<'a>(
971986
.deposit(collateral_amount)?;
972987
obligation.last_update.mark_stale();
973988
Obligation::pack(obligation, &mut obligation_info.data.borrow_mut())?;
974-
975989
spl_token_transfer(TokenTransferParams {
976990
source: source_collateral_info.clone(),
977991
destination: destination_collateral_info.clone(),
@@ -980,7 +994,6 @@ fn _deposit_obligation_collateral<'a>(
980994
authority_signer_seeds: &[],
981995
token_program: token_program_id.clone(),
982996
})?;
983-
984997
Ok(())
985998
}
986999

@@ -1006,12 +1019,13 @@ fn process_deposit_reserve_liquidity_and_obligation_collateral(
10061019
let destination_collateral_info = next_account_info(account_info_iter)?;
10071020
let obligation_info = next_account_info(account_info_iter)?;
10081021
let obligation_owner_info = next_account_info(account_info_iter)?;
1009-
let pyth_price_info = next_account_info(account_info_iter)?;
1010-
let switchboard_feed_info = next_account_info(account_info_iter)?;
1022+
let _pyth_price_info = next_account_info(account_info_iter)?;
1023+
let _switchboard_feed_info = next_account_info(account_info_iter)?;
10111024
let user_transfer_authority_info = next_account_info(account_info_iter)?;
10121025
let clock = &Clock::from_account_info(next_account_info(account_info_iter)?)?;
10131026
let token_program_id = next_account_info(account_info_iter)?;
10141027

1028+
_refresh_reserve_interest(program_id, reserve_info, clock)?;
10151029
let collateral_amount = _deposit_reserve_liquidity(
10161030
program_id,
10171031
liquidity_amount,
@@ -1026,13 +1040,7 @@ fn process_deposit_reserve_liquidity_and_obligation_collateral(
10261040
clock,
10271041
token_program_id,
10281042
)?;
1029-
_refresh_reserve(
1030-
program_id,
1031-
reserve_info,
1032-
pyth_price_info,
1033-
switchboard_feed_info,
1034-
clock,
1035-
)?;
1043+
_refresh_reserve_interest(program_id, reserve_info, clock)?;
10361044
_deposit_obligation_collateral(
10371045
program_id,
10381046
collateral_amount,
@@ -1046,6 +1054,11 @@ fn process_deposit_reserve_liquidity_and_obligation_collateral(
10461054
clock,
10471055
token_program_id,
10481056
)?;
1057+
// mark the reserve as stale to make sure no weird bugs happen
1058+
let mut reserve = Reserve::unpack(&reserve_info.data.borrow())?;
1059+
reserve.last_update.mark_stale();
1060+
Reserve::pack(reserve, &mut reserve_info.data.borrow_mut())?;
1061+
10491062
Ok(())
10501063
}
10511064

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#![cfg(feature = "test-bpf")]
2+
3+
mod helpers;
4+
5+
use helpers::*;
6+
use solana_program_test::*;
7+
use solana_sdk::{pubkey::Pubkey, signature::Keypair};
8+
use spl_token_lending::processor::process_instruction;
9+
10+
#[tokio::test]
11+
async fn test_success() {
12+
let mut test = ProgramTest::new(
13+
"spl_token_lending",
14+
spl_token_lending::id(),
15+
processor!(process_instruction),
16+
);
17+
18+
// limit to track compute unit increase
19+
test.set_bpf_compute_max_units(70_000);
20+
21+
let user_accounts_owner = Keypair::new();
22+
let lending_market = add_lending_market(&mut test);
23+
24+
let usdc_mint = add_usdc_mint(&mut test);
25+
let usdc_oracle = add_usdc_oracle(&mut test);
26+
let usdc_test_reserve = add_reserve(
27+
&mut test,
28+
&lending_market,
29+
&usdc_oracle,
30+
&user_accounts_owner,
31+
AddReserveArgs {
32+
user_liquidity_amount: 100 * FRACTIONAL_TO_USDC,
33+
liquidity_amount: 10_000 * FRACTIONAL_TO_USDC,
34+
liquidity_mint_decimals: usdc_mint.decimals,
35+
liquidity_mint_pubkey: usdc_mint.pubkey,
36+
config: test_reserve_config(),
37+
mark_fresh: true,
38+
..AddReserveArgs::default()
39+
},
40+
);
41+
42+
let test_obligation = add_obligation(
43+
&mut test,
44+
&lending_market,
45+
&user_accounts_owner,
46+
AddObligationArgs::default(),
47+
);
48+
49+
let (mut banks_client, payer, _recent_blockhash) = test.start().await;
50+
51+
test_obligation.validate_state(&mut banks_client).await;
52+
53+
// let initial_collateral_supply_balance =
54+
// get_token_balance(&mut banks_client, usdc_test_reserve.collateral_supply_pubkey).await;
55+
// let initial_user_collateral_balance =
56+
// get_token_balance(&mut banks_client, usdc_test_reserve.user_collateral_pubkey).await;
57+
58+
lending_market
59+
.deposit_obligation_and_collateral(
60+
&mut banks_client,
61+
&user_accounts_owner,
62+
&payer,
63+
&usdc_test_reserve,
64+
&test_obligation,
65+
100 * FRACTIONAL_TO_USDC,
66+
)
67+
.await;
68+
69+
let usdc_reserve = usdc_test_reserve.get_state(&mut banks_client).await;
70+
assert_eq!(usdc_reserve.last_update.stale, true);
71+
}

token-lending/program/tests/helpers/mod.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,6 @@ impl TestLendingMarket {
602602
payer: &Keypair,
603603
reserve: &TestReserve,
604604
obligation: &TestObligation,
605-
obligation_keypair: &Keypair,
606605
liquidity_amount: u64,
607606
) {
608607
let user_transfer_authority = Keypair::new();
@@ -617,6 +616,15 @@ impl TestLendingMarket {
617616
liquidity_amount,
618617
)
619618
.unwrap(),
619+
approve(
620+
&spl_token::id(),
621+
&reserve.user_collateral_pubkey,
622+
&user_transfer_authority.pubkey(),
623+
&user_accounts_owner.pubkey(),
624+
&[],
625+
liquidity_amount,
626+
)
627+
.unwrap(),
620628
deposit_reserve_liquidity_and_obligation_collateral(
621629
spl_token_lending::id(),
622630
liquidity_amount,
@@ -625,7 +633,7 @@ impl TestLendingMarket {
625633
reserve.pubkey,
626634
reserve.liquidity_supply_pubkey,
627635
reserve.collateral_mint_pubkey,
628-
reserve.pubkey,
636+
self.pubkey,
629637
reserve.collateral_supply_pubkey,
630638
obligation.pubkey,
631639
obligation.owner,
@@ -639,12 +647,7 @@ impl TestLendingMarket {
639647

640648
let recent_blockhash = banks_client.get_recent_blockhash().await.unwrap();
641649
transaction.sign(
642-
&[
643-
payer,
644-
user_accounts_owner,
645-
&user_transfer_authority,
646-
&obligation_keypair,
647-
],
650+
&[payer, user_accounts_owner, &user_transfer_authority],
648651
recent_blockhash,
649652
);
650653

0 commit comments

Comments
 (0)