diff --git a/token-lending/program/src/processor.rs b/token-lending/program/src/processor.rs index d8c4e3faf3d..a4303c52f0e 100644 --- a/token-lending/program/src/processor.rs +++ b/token-lending/program/src/processor.rs @@ -411,6 +411,23 @@ fn _refresh_reserve<'a>( } reserve.liquidity.market_price = get_price(switchboard_feed_info, pyth_price_info, clock)?; + Reserve::pack(reserve, &mut reserve_info.data.borrow_mut())?; + + _refresh_reserve_interest(program_id, reserve_info, clock) +} + +/// Lite version of refresh_reserve that should be used when the oracle price doesn't need to be updated +/// BE CAREFUL WHEN USING THIS +fn _refresh_reserve_interest<'a>( + program_id: &Pubkey, + reserve_info: &AccountInfo<'a>, + clock: &Clock, +) -> ProgramResult { + let mut reserve = Reserve::unpack(&reserve_info.data.borrow())?; + if reserve_info.owner != program_id { + msg!("Reserve provided is not owned by the lending program"); + return Err(LendingError::InvalidAccountOwner.into()); + } reserve.accrue_interest(clock.slot)?; reserve.last_update.update_slot(clock.slot); @@ -483,7 +500,6 @@ fn _deposit_reserve_liquidity<'a>( msg!("Lending market token program does not match the token program provided"); return Err(LendingError::InvalidTokenProgram.into()); } - let mut reserve = Reserve::unpack(&reserve_info.data.borrow())?; if reserve_info.owner != program_id { msg!("Reserve provided is not owned by the lending program"); @@ -513,7 +529,6 @@ fn _deposit_reserve_liquidity<'a>( msg!("Reserve is stale and must be refreshed in the current slot"); return Err(LendingError::ReserveStale.into()); } - let authority_signer_seeds = &[ lending_market_info.key.as_ref(), &[lending_market.bump_seed], @@ -971,7 +986,6 @@ fn _deposit_obligation_collateral<'a>( .deposit(collateral_amount)?; obligation.last_update.mark_stale(); Obligation::pack(obligation, &mut obligation_info.data.borrow_mut())?; - spl_token_transfer(TokenTransferParams { source: source_collateral_info.clone(), destination: destination_collateral_info.clone(), @@ -980,7 +994,6 @@ fn _deposit_obligation_collateral<'a>( authority_signer_seeds: &[], token_program: token_program_id.clone(), })?; - Ok(()) } @@ -1006,12 +1019,13 @@ fn process_deposit_reserve_liquidity_and_obligation_collateral( let destination_collateral_info = next_account_info(account_info_iter)?; let obligation_info = next_account_info(account_info_iter)?; let obligation_owner_info = next_account_info(account_info_iter)?; - let pyth_price_info = next_account_info(account_info_iter)?; - let switchboard_feed_info = next_account_info(account_info_iter)?; + let _pyth_price_info = next_account_info(account_info_iter)?; + let _switchboard_feed_info = next_account_info(account_info_iter)?; let user_transfer_authority_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(next_account_info(account_info_iter)?)?; let token_program_id = next_account_info(account_info_iter)?; + _refresh_reserve_interest(program_id, reserve_info, clock)?; let collateral_amount = _deposit_reserve_liquidity( program_id, liquidity_amount, @@ -1026,13 +1040,7 @@ fn process_deposit_reserve_liquidity_and_obligation_collateral( clock, token_program_id, )?; - _refresh_reserve( - program_id, - reserve_info, - pyth_price_info, - switchboard_feed_info, - clock, - )?; + _refresh_reserve_interest(program_id, reserve_info, clock)?; _deposit_obligation_collateral( program_id, collateral_amount, @@ -1046,6 +1054,11 @@ fn process_deposit_reserve_liquidity_and_obligation_collateral( clock, token_program_id, )?; + // mark the reserve as stale to make sure no weird bugs happen + let mut reserve = Reserve::unpack(&reserve_info.data.borrow())?; + reserve.last_update.mark_stale(); + Reserve::pack(reserve, &mut reserve_info.data.borrow_mut())?; + Ok(()) } diff --git a/token-lending/program/tests/deposit_reserve_liquidity_and_obligation_collateral.rs b/token-lending/program/tests/deposit_reserve_liquidity_and_obligation_collateral.rs new file mode 100644 index 00000000000..bf2fe9e6c81 --- /dev/null +++ b/token-lending/program/tests/deposit_reserve_liquidity_and_obligation_collateral.rs @@ -0,0 +1,71 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use helpers::*; +use solana_program_test::*; +use solana_sdk::{pubkey::Pubkey, signature::Keypair}; +use spl_token_lending::processor::process_instruction; + +#[tokio::test] +async fn test_success() { + let mut test = ProgramTest::new( + "spl_token_lending", + spl_token_lending::id(), + processor!(process_instruction), + ); + + // limit to track compute unit increase + test.set_bpf_compute_max_units(70_000); + + let user_accounts_owner = Keypair::new(); + let lending_market = add_lending_market(&mut test); + + let usdc_mint = add_usdc_mint(&mut test); + let usdc_oracle = add_usdc_oracle(&mut test); + let usdc_test_reserve = add_reserve( + &mut test, + &lending_market, + &usdc_oracle, + &user_accounts_owner, + AddReserveArgs { + user_liquidity_amount: 100 * FRACTIONAL_TO_USDC, + liquidity_amount: 10_000 * FRACTIONAL_TO_USDC, + liquidity_mint_decimals: usdc_mint.decimals, + liquidity_mint_pubkey: usdc_mint.pubkey, + config: test_reserve_config(), + mark_fresh: true, + ..AddReserveArgs::default() + }, + ); + + let test_obligation = add_obligation( + &mut test, + &lending_market, + &user_accounts_owner, + AddObligationArgs::default(), + ); + + let (mut banks_client, payer, _recent_blockhash) = test.start().await; + + test_obligation.validate_state(&mut banks_client).await; + + // let initial_collateral_supply_balance = + // get_token_balance(&mut banks_client, usdc_test_reserve.collateral_supply_pubkey).await; + // let initial_user_collateral_balance = + // get_token_balance(&mut banks_client, usdc_test_reserve.user_collateral_pubkey).await; + + lending_market + .deposit_obligation_and_collateral( + &mut banks_client, + &user_accounts_owner, + &payer, + &usdc_test_reserve, + &test_obligation, + 100 * FRACTIONAL_TO_USDC, + ) + .await; + + let usdc_reserve = usdc_test_reserve.get_state(&mut banks_client).await; + assert_eq!(usdc_reserve.last_update.stale, true); +} diff --git a/token-lending/program/tests/helpers/mod.rs b/token-lending/program/tests/helpers/mod.rs index d4b47f65cfe..6afa0412f92 100644 --- a/token-lending/program/tests/helpers/mod.rs +++ b/token-lending/program/tests/helpers/mod.rs @@ -602,7 +602,6 @@ impl TestLendingMarket { payer: &Keypair, reserve: &TestReserve, obligation: &TestObligation, - obligation_keypair: &Keypair, liquidity_amount: u64, ) { let user_transfer_authority = Keypair::new(); @@ -617,6 +616,15 @@ impl TestLendingMarket { liquidity_amount, ) .unwrap(), + approve( + &spl_token::id(), + &reserve.user_collateral_pubkey, + &user_transfer_authority.pubkey(), + &user_accounts_owner.pubkey(), + &[], + liquidity_amount, + ) + .unwrap(), deposit_reserve_liquidity_and_obligation_collateral( spl_token_lending::id(), liquidity_amount, @@ -625,7 +633,7 @@ impl TestLendingMarket { reserve.pubkey, reserve.liquidity_supply_pubkey, reserve.collateral_mint_pubkey, - reserve.pubkey, + self.pubkey, reserve.collateral_supply_pubkey, obligation.pubkey, obligation.owner, @@ -639,12 +647,7 @@ impl TestLendingMarket { let recent_blockhash = banks_client.get_recent_blockhash().await.unwrap(); transaction.sign( - &[ - payer, - user_accounts_owner, - &user_transfer_authority, - &obligation_keypair, - ], + &[payer, user_accounts_owner, &user_transfer_authority], recent_blockhash, );