User Instructions
Interact program to program via these instructions, or refer to the github here:
solana-program-library/ at mainnet · solendprotocol/solana-program-library
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 his 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 reserves, usually done before RefreshObligation
  • Pulls Oracle Prices
  • Updates 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 was removed to reduce oracle reliance after Jan2022’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 requires that reserves are refreshed.
RefreshReserve → RefreshObligation (repeated through all the positions) requires a lot of memory, which is a Solana limit, and thus limits our positions to 6.