Integration Guide

Introduction

Solend has 3 types of accounts: lending market, reserve, and obligation.

There's only one instance of a lending market for now. There's a one-to-one mapping from listed asset to reserve. There's a one-to-one mapping from user to obligations (which tracks user's collateral/borrows).

Rust definitions are here.

Calculating TVL from on-chain data example

https://github.com/solendprotocol/tvl-calculator-example

Deriving obligation address

const seed = LENDING_MARKET_ADDRESS.slice(0, 32);
const obligationAddress = await PublicKey.createWithSeed(
  new PublicKey(address),
  seed,
  new PublicKey(SOLEND_PROGRAM_ID),
);

Calculating APY

The following typescript snippet is extracted from our codebase:

export const calculateSupplyAPY = (reserve: Reserve) => {
  const currentUtilization = calculateUtilizationRatio(reserve);
  const borrowAPY = calculateBorrowAPY(reserve);
  return currentUtilization * borrowAPY;
};

export const calculateUtilizationRatio = (reserve: Reserve) => {
  const borrowedAmount = reserve.liquidity.borrowedAmountWads
    .div(new BN(`1${''.padEnd(18, '0')}`))
    .toNumber();
  const availableAmount = reserve.liquidity.availableAmount.toNumber();
  const currentUtilization =
    borrowedAmount / (availableAmount + borrowedAmount);
  return currentUtilization;
};

export const calculateBorrowAPY = (reserve: Reserve) => {
  const currentUtilization = calculateUtilizationRatio(reserve);
  const optimalUtilization = reserve.config.optimalUtilizationRate / 100;
  let borrowAPY;
  if (optimalUtilization === 1.0 || currentUtilization < optimalUtilization) {
    const normalizedFactor = currentUtilization / optimalUtilization;
    const optimalBorrowRate = reserve.config.optimalBorrowRate / 100;
    const minBorrowRate = reserve.config.minBorrowRate / 100;
    borrowAPY =
      normalizedFactor * (optimalBorrowRate - minBorrowRate) + minBorrowRate;
  } else {
    const normalizedFactor =
      (currentUtilization - optimalUtilization) / (1 - optimalUtilization);
    const optimalBorrowRate = reserve.config.optimalBorrowRate / 100;
    const maxBorrowRate = reserve.config.maxBorrowRate / 100;
    borrowAPY =
      normalizedFactor * (maxBorrowRate - optimalBorrowRate) +
      optimalBorrowRate;
  }

  return borrowAPY;
};

Additionally, we have a few other resources for developers:

Last updated