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
RepayObligationLiquidity
Does not require RefreshReserve as it is impossible to worsen an obligation’s health by repaying.
cToken Instructions:
DepositReserveLiquidity
Deposit funds into the reserve, mint cToken
No need to escrow the cTokens in the CollateralSupplyAddress
Relies on cToken:Token Ratio
RedeemReserveCollateral
Withdraw Funds, burn cTokens
Relies on cToken:Token Ratio
Monitoring/Misc Instructions
RefreshReserve
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
RefreshObligation
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
Notes:
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.