Skip to content

Commit

Permalink
WIp
Browse files Browse the repository at this point in the history
  • Loading branch information
DaSichuan committed Jul 15, 2021
1 parent b7f7207 commit 042ab15
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 2 deletions.
27 changes: 27 additions & 0 deletions token-lending/program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,23 @@ pub enum LendingInstruction {
/// liquidity_amount is the amount of collateral tokens to withdraw
collateral_amount: u64,
},

// 16
/// Updates a reserve config parameter
///
/// Accounts expected by this instruction:
///
/// 1. `[writable]` Reserve account - refreshed
/// 2 `[]` Lending market account.
/// 3 `[]` Derived lending market authority.
/// 4 `[signer]` Lending market owner.
/// 6 `[]` Clock sysvar.
UpdateReserveConfig {
/// Specifies which config to change
config_enum: u8,
/// New value for the config
new_value: u8,
},
}

impl LendingInstruction {
Expand Down Expand Up @@ -456,6 +473,11 @@ impl LendingInstruction {
let (collateral_amount, _rest) = Self::unpack_u64(rest)?;
Self::WithdrawObligationCollateralAndRedeemReserveCollateral { collateral_amount }
}
16 => {
let (config_enum, _rest) = Self::unpack_u8(rest)?;
let (new_value, _rest) = Self::unpack_u8(_rest)?;
Self::UpdateReserveConfig { config_enum, new_value }
}
_ => {
msg!("Instruction cannot be unpacked");
return Err(LendingError::InstructionUnpackError.into());
Expand Down Expand Up @@ -612,6 +634,11 @@ impl LendingInstruction {
buf.push(15);
buf.extend_from_slice(&collateral_amount.to_le_bytes());
}
Self::UpdateReserveConfig {config_enum, new_value} => {
buf.push(16);
buf.extend_from_slice(&config_enum.to_le_bytes());
buf.extend_from_slice(&new_value.to_le_bytes());
}
}
buf
}
Expand Down
87 changes: 85 additions & 2 deletions token-lending/program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
CalculateBorrowResult, CalculateLiquidationResult, CalculateRepayResult,
InitLendingMarketParams, InitObligationParams, InitReserveParams, LendingMarket,
NewReserveCollateralParams, NewReserveLiquidityParams, Obligation, Reserve,
ReserveCollateral, ReserveConfig, ReserveLiquidity,
ReserveCollateral, ReserveConfig, ReserveConfigKey, ReserveLiquidity,
},
};
use num_traits::FromPrimitive;
Expand Down Expand Up @@ -114,13 +114,24 @@ pub fn process_instruction(
LendingInstruction::WithdrawObligationCollateralAndRedeemReserveCollateral {
collateral_amount,
} => {
msg!("Instruction: Withdraw Obligation Collateral and Redeem Reserve Collateral ");
msg!("Instruction: Withdraw Obligation Collateral and Redeem Reserve Collateral");
process_withdraw_obligation_collateral_and_redeem_reserve_liquidity(
program_id,
collateral_amount,
accounts,
)
}
LendingInstruction::UpdateReserveConfig {
config_enum,
new_value,
} => {
msg!("Instruction: UpdateReserveConfig");
process_update_reserve_config(
program_id,
ReserveConfigKey::from_u8(config_enum)?,
new_value,
accounts)
}
}
}

Expand Down Expand Up @@ -1994,6 +2005,78 @@ fn process_withdraw_obligation_collateral_and_redeem_reserve_liquidity(
)
}


#[inline(never)] // avoid stack frame limit
fn process_update_reserve_config(
program_id: &Pubkey,
config_enum: ReserveConfigKey,
new_value: u8,
accounts: &[AccountInfo],
) -> ProgramResult {

let account_info_iter = &mut accounts.iter().peekable();
let reserve_info = next_account_info(account_info_iter)?;
let lending_market_info = next_account_info(account_info_iter)?;
let lending_market_authority_info = next_account_info(account_info_iter)?;
let lending_market_owner_info = next_account_info(account_info_iter)?;
let clock = &Clock::from_account_info(next_account_info(account_info_iter)?)?;

let mut reserve = assert_uninitialized::<Reserve>(reserve_info)?;
if reserve_info.owner != program_id {
msg!(
"Reserve provided is not owned by the lending program {} != {}",
&reserve_info.owner.to_string(),
&program_id.to_string(),
);
return Err(LendingError::InvalidAccountOwner.into());
}


let lending_market = LendingMarket::unpack(&lending_market_info.data.borrow())?;
if lending_market_info.owner != program_id {
msg!(
"Lending market provided is not owned by the lending program {} != {}",
&lending_market_info.owner.to_string(),
&program_id.to_string(),
);
return Err(LendingError::InvalidAccountOwner.into());
}
if &lending_market.owner != lending_market_owner_info.key {
msg!("Lending market owner does not match the lending market owner provided");
return Err(LendingError::InvalidMarketOwner.into());
}
if !lending_market_owner_info.is_signer {
msg!("Lending market owner provided must be a signer");
return Err(LendingError::InvalidSigner.into());
}

let authority_signer_seeds = &[
lending_market_info.key.as_ref(),
&[lending_market.bump_seed],
];
let lending_market_authority_pubkey =
Pubkey::create_program_address(authority_signer_seeds, program_id)?;
if &lending_market_authority_pubkey != lending_market_authority_info.key {
msg!(
"Derived lending market authority does not match the lending market authority provided"
);
return Err(LendingError::InvalidMarketAuthority.into());
}
match config_enum {
// Make this an enum, make this decimal friendly
ReserveConfigKey::LoanToValueRatio => {
reserve.config.loan_to_value_ratio = new_value;
}
_ => {
msg!("Did not recognize reserve config key");
return Err(LendingError::InvalidConfig.into());
}
};
Reserve::pack(reserve, &mut reserve_info.data.borrow_mut())?;
Ok(())
}


fn assert_rent_exempt(rent: &Rent, account_info: &AccountInfo) -> ProgramResult {
if !rent.is_exempt(account_info.lamports(), account_info.data_len()) {
msg!(
Expand Down
16 changes: 16 additions & 0 deletions token-lending/program/src/state/reserve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,22 @@ pub struct ReserveConfig {
pub fees: ReserveFees,
}

/// ReserveConfig configurable values
#[repr(u8)]
pub enum ReserveConfigKey {
/// Enum to specify LoanToValueRatio
LoanToValueRatio = 0
}

impl ReserveConfigKey {
pub fn from_u8(value: u8) -> Result<ReserveConfigKey, ProgramError> {
match value {
0 => Ok(ReserveConfigKey::LoanToValueRatio)
_ => Err(LendingError::InvalidConfig.into())
}
}
}

/// Additional fee information on a reserve
///
/// These exist separately from interest accrual fees, and are specifically for the program owner
Expand Down

0 comments on commit 042ab15

Please sign in to comment.