diff --git a/programs/marginfi/src/instructions/cdp.rs b/programs/marginfi/src/instructions/cdp.rs index 908f9e4a..5db75f2f 100644 --- a/programs/marginfi/src/instructions/cdp.rs +++ b/programs/marginfi/src/instructions/cdp.rs @@ -6,6 +6,7 @@ use fixed::types::I80F48; use crate::{ constants::{CDP_MINT_AUTH_SEED, LIQUIDITY_VAULT_SEED}, + math_error, prelude::MarginfiResult, state::{ cdp::{Cdp, CdpBank, CdpCollateralBank, CdpCollateralBankStatus}, @@ -95,7 +96,7 @@ pub struct CreateCdpCollateralBank<'info> { } pub fn create_cdp(ctx: Context) -> MarginfiResult { - let cdp = ctx.accounts.cdp.load_init()?; + let mut cdp = ctx.accounts.cdp.load_init()?; *cdp = Cdp { authority: ctx.accounts.authority.key(), @@ -132,18 +133,18 @@ pub fn cdp_deposit(ctx: Context, amount: u64) -> MarginfiResult { let deposit_shares = bank.get_asset_shares(I80F48::from_num(amount))?; - bank.change_asset_shares(deposit_shares); - cdp.change_collateral_shares(deposit_shares); + bank.change_asset_shares(deposit_shares)?; + cdp.change_collateral_shares(deposit_shares)?; bank.deposit_spl_transfer( amount, Transfer { - from: ctx.accounts.cdp_authority_ta, - to: ctx.accounts.bank_vault, + from: ctx.accounts.cdp_authority_ta.to_account_info(), + to: ctx.accounts.bank_vault.to_account_info(), authority: ctx.accounts.cdp_authority.to_account_info(), }, ctx.accounts.token_program.to_account_info(), - ); + )?; Ok(()) } @@ -160,3 +161,32 @@ pub struct CdpDeposit<'info> { pub cdp_authority_ta: AccountInfo<'info>, pub token_program: Program<'info, Token>, } + +pub fn cdp_mint(ctx: Context, amount: u64) -> MarginfiResult { + let mut cdp_bank = ctx.accounts.cdp_bank.load_mut()?; + let mut cdp = ctx.accounts.cdp.load_mut()?; + + let liab_shares = cdp_bank + .get_liability_shares(I80F48::from_num(amount)) + .ok_or_else(math_error!())?; + + cdp_bank.update_liability_share_amount(liab_shares)?; + cdp.change_liability_shares(liab_shares)?; + + Ok(()) +} + +/// Remaining accounts have `bank` oracle ais +#[derive(Accounts)] +pub struct CdpMint<'info> { + pub group: AccountLoader<'info, MarginfiGroup>, + pub cdp_bank: AccountLoader<'info, CdpBank>, + pub cdp_collateral_bank: AccountLoader<'info, CdpCollateralBank>, + pub bank: AccountLoader<'info, Bank>, + pub cdp_mint: Box>, + pub cdp_mint_authority: AccountInfo<'info>, + pub cdp: AccountLoader<'info, Cdp>, + pub cdp_authority: Signer<'info>, + pub cdp_authority_ta: AccountInfo<'info>, + pub token_program: Program<'info, Token>, +} diff --git a/programs/marginfi/src/state/cdp.rs b/programs/marginfi/src/state/cdp.rs index f9001cea..725622d4 100644 --- a/programs/marginfi/src/state/cdp.rs +++ b/programs/marginfi/src/state/cdp.rs @@ -50,6 +50,26 @@ pub struct CdpBank { pub liability_limit: u64, } +impl CdpBank { + pub fn get_liability_shares(&self, amount: I80F48) -> Option { + amount.checked_div(self.liability_share_value.into()) + } + + pub fn get_liability_amount(&self, shares: I80F48) -> Option { + shares.checked_mul(self.liability_share_value.into()) + } + + pub fn update_liability_share_amount(&mut self, shares: I80F48) -> MarginfiResult { + self.total_liability_shares = WrappedI80F48::from( + shares + .checked_add(self.total_liability_shares.into()) + .ok_or_else(math_error!())?, + ); + + Ok(()) + } +} + #[repr(u8)] #[derive(Copy, Clone, Debug, AnchorDeserialize, AnchorSerialize)] pub enum CdpCollateralBankStatus {