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,