User Instructions

Interact program to program via these instructions, or refer to the GitHub link below:
DepositReserveLiquidityAndObligationCollateral (Supply)
  • Deposit reserve liquidity (Transfer) + mint cTokens (MintTo) + Transfer cTokens into CollateralSupplyAddress (Transfer)
  • Does not require RefreshReserve as it is impossible to worsen an obligation’s health by repaying.
  • Sample TX
  • Redeem cTokens from CollateralSupplyAddress
  • Exchange cTokens into Tokens using the cToken Rate
  • Requires RefreshReserve to ensure that the user is able to withdraw without defaulting their existing borrows
  • RefreshReserve → RefreshObligation → WithdrawObligationCollateralAndRedeemReserveCollateral
  • Bundled with Refresh Reserve
  • if “borrow_reserve.last_update.is_stale(clock.slot)? {” fails, reserve is considered stale (refreshreserve + borrow must be in the same slot)
  • RefreshReserve → RefreshObligation → Borrow
  • Does not require RefreshReserve as it is impossible to worsen an obligation’s health by repaying.

cToken Instructions:

  • Deposit funds into the reserve, mint cToken
  • No need to escrow the cTokens in the CollateralSupplyAddress
  • Relies on cToken:Token Ratio
  • Withdraw Funds, burn cTokens
  • Relies on cToken:Token Ratio

Monitoring/Misc Instructions

  • Update the price of every reserve, usually done before RefreshObligation
  • Pull Oracle prices
  • Update CumulativeBorrowRate to calculate interest paid since last refreshed block
  • Update the Obligation CumulativeBorrowRate to apply an increase in borrow value
  • Update cToken Rate for supply side users
  • Done 2x for every reserve, supply and borrow side
  • Done after RefreshReserves
  • Calculate individual obligations that ran the Withdraw or Borrow tx to calculate LTV before borrows
  • Assess whether the tx can go through based on account health
RefreshReserve/RefreshObligation used to be required for all transactions, but were removed to reduce oracle reliance after Jan 2022’s network issues.
Liquidator will call RefreshObligation before liquidating
However, borrow/withdraw has to check whether the obligation is refreshed in the SAME slot. But obligations require that reserves are refreshed.
RefreshReserve → RefreshObligation (repeated through all the positions) requires a lot of memory, which is limited by Solana, and thus limits our positions to 6.