From 5dfe5965cd050abc69809511ce1b9e0beb3e5362 Mon Sep 17 00:00:00 2001 From: 0xodia <0xodia@solend.fi> Date: Tue, 25 Jul 2023 14:06:57 -0400 Subject: [PATCH] v2.0.2 fixes --- .../ReserveStats/ReserveStats.tsx | 15 ++---- solend-lite/src/stores/pools.ts | 9 +--- solend-sdk/package.json | 2 +- solend-sdk/src/core/action/action.ts | 49 +++++++++++++++++-- solend-sdk/src/core/types.ts | 1 + solend-sdk/src/core/utils/index.ts | 1 + solend-sdk/src/core/utils/rates.ts | 42 +++------------- solend-sdk/src/core/utils/utils.ts | 32 ------------ solend-sdk/src/instructions/forgiveDebt.ts | 9 ++-- .../setLendingMarketOwnerAndConfig.ts | 2 +- 10 files changed, 66 insertions(+), 96 deletions(-) diff --git a/solend-lite/src/components/TransactionTakeover/ReserveStats/ReserveStats.tsx b/solend-lite/src/components/TransactionTakeover/ReserveStats/ReserveStats.tsx index 751e7b96..154c1478 100644 --- a/solend-lite/src/components/TransactionTakeover/ReserveStats/ReserveStats.tsx +++ b/solend-lite/src/components/TransactionTakeover/ReserveStats/ReserveStats.tsx @@ -7,7 +7,6 @@ import BigNumber from 'bignumber.js'; import styles from './ReserveStats.module.scss'; import classNames from 'classnames'; import { ChevronDownIcon, ChevronUpIcon, CopyIcon } from '@chakra-ui/icons'; -import { computeExtremeRates } from '@solendprotocol/solend-sdk'; import { useAtom } from 'jotai'; import humanizeDuration from 'humanize-duration'; import { SLOT_RATE } from 'utils/utils'; @@ -213,11 +212,7 @@ function ReserveStats({ @@ -251,9 +244,7 @@ function ReserveStats({ row label='Supermax borrow APR' value={formatPercent( - reserve.maxBorrowApr === reserve.targetBorrowApr - ? computeExtremeRates(reserve.maxBorrowApr) - : reserve.maxBorrowApr, + reserve.superMaxBorrowRate )} tooltip='Maximum possible borrow APR.' /> diff --git a/solend-lite/src/stores/pools.ts b/solend-lite/src/stores/pools.ts index ed079a59..8a9cc3d0 100644 --- a/solend-lite/src/stores/pools.ts +++ b/solend-lite/src/stores/pools.ts @@ -19,6 +19,7 @@ import { getReservesOfPool, parseLendingMarket, parseRateLimiter, + PoolType, } from '@solendprotocol/solend-sdk'; import { DEBUG_MODE, PROGRAM_ID } from 'common/config'; import { atomWithRefresh } from './shared'; @@ -33,13 +34,6 @@ export type SelectedReserveType = ReserveType & { logo: string | null; }; -export type PoolType = { - name: string | null; - address: string; - authorityAddress: string; - reserves: Array; -}; - export type SelectedPoolType = { name: string | null; address: string; @@ -67,6 +61,7 @@ export const poolsAtom = atomWithDefault<{ [address: string]: PoolType }>( name: pool.name, authorityAddress: pool.authorityAddress, address: pool.address, + owner: pool.owner, reserves: [] as Array, }, ]), diff --git a/solend-sdk/package.json b/solend-sdk/package.json index 04964a68..b8fac562 100644 --- a/solend-sdk/package.json +++ b/solend-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solendprotocol/solend-sdk", - "version": "0.6.16", + "version": "0.6.20", "private": true, "main": "src/index.ts", "module": "src/index.ts", diff --git a/solend-sdk/src/core/action/action.ts b/solend-sdk/src/core/action/action.ts index a8d2561b..a4a4784d 100644 --- a/solend-sdk/src/core/action/action.ts +++ b/solend-sdk/src/core/action/action.ts @@ -34,6 +34,7 @@ import { syncNative, depositObligationCollateralInstruction, withdrawObligationCollateralInstruction, + forgiveDebtInstruction, } from "../../instructions"; import { POSITION_LIMIT } from "../constants"; import { EnvironmentType, PoolType, ReserveType } from "../types"; @@ -49,7 +50,8 @@ export type ActionType = | "mint" | "redeem" | "depositCollateral" - | "withdrawCollateral"; + | "withdrawCollateral" + | "forgive"; export class SolendActionCore { programId: PublicKey; @@ -139,12 +141,13 @@ export class SolendActionCore { publicKey: PublicKey, connection: Connection, environment: EnvironmentType = "production", + customObligationAddress?: PublicKey, hostAta?: PublicKey ) { const seed = pool.address.slice(0, 32); const programId = getProgramId(environment); - const obligationAddress = await PublicKey.createWithSeed( + const obligationAddress = customObligationAddress ?? await PublicKey.createWithSeed( publicKey, seed, programId @@ -228,6 +231,32 @@ export class SolendActionCore { ); } + static async buildForgiveTxns( + pool: PoolType, + reserve: ReserveType, + connection: Connection, + amount: string, + publicKey: PublicKey, + obligationAddress: PublicKey, + environment: EnvironmentType = "production" + ) { + const axn = await SolendActionCore.initialize( + pool, + reserve, + "deposit", + new BN(amount), + publicKey, + connection, + environment, + obligationAddress + ); + + await axn.addSupportIxs("forgive"); + await axn.addForgiveIx(); + + return axn + } + static async buildDepositTxns( pool: PoolType, reserve: ReserveType, @@ -269,6 +298,7 @@ export class SolendActionCore { publicKey, connection, environment, + undefined, hostAta ); @@ -499,6 +529,19 @@ export class SolendActionCore { return signature; } + addForgiveIx() { + this.lendingIxs.push( + forgiveDebtInstruction( + this.obligationAddress, + new PublicKey(this.reserve.address), + new PublicKey(this.pool.address), + new PublicKey(this.pool.owner), + this.amount, + this.programId + ) + ); + } + addDepositIx() { this.lendingIxs.push( depositReserveLiquidityAndObligationCollateralInstruction( @@ -707,7 +750,7 @@ export class SolendActionCore { } async addSupportIxs(action: ActionType) { - if (["withdraw", "borrow", "withdrawCollateral"].includes(action)) { + if (["withdraw", "borrow", "withdrawCollateral", "forgive"].includes(action)) { await this.addRefreshIxs(); } if (!["mint", "redeem"].includes(action)) { diff --git a/solend-sdk/src/core/types.ts b/solend-sdk/src/core/types.ts index 7aac9054..3a3e9f4e 100644 --- a/solend-sdk/src/core/types.ts +++ b/solend-sdk/src/core/types.ts @@ -23,6 +23,7 @@ export type PoolType = { name: string | null; address: string; authorityAddress: string; + owner: string; reserves: Array; }; diff --git a/solend-sdk/src/core/utils/index.ts b/solend-sdk/src/core/utils/index.ts index 602b4335..fefcacd1 100644 --- a/solend-sdk/src/core/utils/index.ts +++ b/solend-sdk/src/core/utils/index.ts @@ -4,3 +4,4 @@ export * from "./utils"; export * from "./pools"; export * from "./obligations"; export * from "./wallet"; +export * from "./rates"; \ No newline at end of file diff --git a/solend-sdk/src/core/utils/rates.ts b/solend-sdk/src/core/utils/rates.ts index 1c805c48..92c409e2 100644 --- a/solend-sdk/src/core/utils/rates.ts +++ b/solend-sdk/src/core/utils/rates.ts @@ -62,14 +62,16 @@ const calculateBorrowAPR = (reserve: Reserve) => { ); const maxBorrowRate = new BigNumber(reserve.config.maxBorrowRate / 100); - borrowAPR = weight.times(maxBorrowRate.minus(optimalBorrowRate)).plus(optimalBorrowRate) + borrowAPR = weight + .times(maxBorrowRate.minus(optimalBorrowRate)) + .plus(optimalBorrowRate) } else { const weight = currentUtilization - .minus(optimalUtilization) - .dividedBy(maxUtilizationRate.minus(optimalUtilization)); + .minus(maxUtilizationRate) + .dividedBy(new BigNumber(100).minus(maxUtilizationRate)); const maxBorrowRate = new BigNumber(reserve.config.maxBorrowRate / 100) - const superMaxBorrowRate = new BigNumber(reserve.config.superMaxBorrowRate.toString()).dividedBy(100); + const superMaxBorrowRate = new BigNumber(reserve.config.superMaxBorrowRate / 100); borrowAPR = weight .times(superMaxBorrowRate.minus(maxBorrowRate)) @@ -106,35 +108,3 @@ export const calculateSupplyInterest = (reserve: Reserve, showApy: boolean) => export const calculateBorrowInterest = (reserve: Reserve, showApy: boolean) => showApy ? calculateBorrowAPY(reserve) : calculateBorrowAPR(reserve); - -export function computeExtremeRates(configRate: number) { - const rate = 0.5; - let cleanRate = configRate; - - if (configRate >= 2.47) { - cleanRate = Number(configRate.toString().replace(".", "")); - } - - switch (cleanRate) { - case 251: - return rate * 6; - case 252: - return rate * 7; - case 253: - return rate * 8; - case 254: - return rate * 10; - case 255: - return rate * 12; - case 250: - return rate * 20; - case 249: - return rate * 30; - case 248: - return rate * 40; - case 247: - return rate * 50; - default: - return cleanRate; - } -} diff --git a/solend-sdk/src/core/utils/utils.ts b/solend-sdk/src/core/utils/utils.ts index ca34fba2..db5330fe 100644 --- a/solend-sdk/src/core/utils/utils.ts +++ b/solend-sdk/src/core/utils/utils.ts @@ -124,35 +124,3 @@ export async function createObligationAddress( ) ).toBase58(); } - -export function computeExtremeRates(configRate: number) { - const rate = 0.5; - let cleanRate = configRate; - - if (configRate >= 2.47) { - cleanRate = Number(configRate.toString().replace(".", "")); - } - - switch (cleanRate) { - case 251: - return rate * 6; - case 252: - return rate * 7; - case 253: - return rate * 8; - case 254: - return rate * 10; - case 255: - return rate * 12; - case 250: - return rate * 20; - case 249: - return rate * 30; - case 248: - return rate * 40; - case 247: - return rate * 50; - default: - return cleanRate; - } -} diff --git a/solend-sdk/src/instructions/forgiveDebt.ts b/solend-sdk/src/instructions/forgiveDebt.ts index 928d2cc1..d365c1c6 100644 --- a/solend-sdk/src/instructions/forgiveDebt.ts +++ b/solend-sdk/src/instructions/forgiveDebt.ts @@ -2,13 +2,14 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import * as BufferLayout from "buffer-layout"; import * as Layout from "../utils/layout"; import { LendingInstruction } from "./instruction"; +import BN from "bn.js"; -export const ForgiveDebtInstruction = ( +export const forgiveDebtInstruction = ( obligation: PublicKey, reserve: PublicKey, lendingMarket: PublicKey, lendingMarketOwner: PublicKey, - liquidityAmount: number, + liquidityAmount: number | BN, lendingProgramId: PublicKey ): TransactionInstruction => { const dataLayout = BufferLayout.struct([ @@ -19,8 +20,8 @@ export const ForgiveDebtInstruction = ( const data = Buffer.alloc(dataLayout.span); dataLayout.encode( { - instruction: LendingInstruction.SetLendingMarketOwnerAndConfig, - liquidityAmount: liquidityAmount, + instruction: LendingInstruction.ForgiveDebt, + liquidityAmount: new BN(liquidityAmount), }, data ); diff --git a/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts b/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts index ebf282cf..9e351334 100644 --- a/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts +++ b/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts @@ -10,7 +10,7 @@ import { LendingInstruction } from "./instruction"; /// /// 0. `[writable]` Lending market account. /// 1. `[signer]` Current owner. -export const SetLendingMarketOwnerAndConfigInstruction = ( +export const setLendingMarketOwnerAndConfigInstruction = ( lendingMarket: PublicKey, currentMarketOwner: PublicKey, newMarketOwner: PublicKey,