mirror of https://github.com/certusone/oyster.git
feat: update layout
This commit is contained in:
parent
a2154ff63c
commit
1177d94153
|
@ -26,7 +26,7 @@ export const ReserveStatus = (props: {
|
||||||
const liquidityMint = useMint(mintAddress);
|
const liquidityMint = useMint(mintAddress);
|
||||||
const { price } = useMidPriceInUSD(mintAddress);
|
const { price } = useMidPriceInUSD(mintAddress);
|
||||||
const availableLiquidity = fromLamports(
|
const availableLiquidity = fromLamports(
|
||||||
props.reserve.availableLiquidity.toNumber(),
|
props.reserve.state.availableLiquidity,
|
||||||
liquidityMint
|
liquidityMint
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export const ReserveStatus = (props: {
|
||||||
const totalBorrows = useMemo(
|
const totalBorrows = useMemo(
|
||||||
() =>
|
() =>
|
||||||
fromLamports(
|
fromLamports(
|
||||||
wadToLamports(props.reserve.borrowedLiquidityWad),
|
wadToLamports(props.reserve.state.borrowedLiquidityWad),
|
||||||
liquidityMint
|
liquidityMint
|
||||||
),
|
),
|
||||||
[props.reserve, liquidityMint]
|
[props.reserve, liquidityMint]
|
||||||
|
|
|
@ -9,14 +9,14 @@ export const ReserveUtilizationChart = (props: { reserve: LendingReserve }) => {
|
||||||
const mintAddress = props.reserve.liquidityMint?.toBase58();
|
const mintAddress = props.reserve.liquidityMint?.toBase58();
|
||||||
const liquidityMint = useMint(mintAddress);
|
const liquidityMint = useMint(mintAddress);
|
||||||
const availableLiquidity = fromLamports(
|
const availableLiquidity = fromLamports(
|
||||||
props.reserve.availableLiquidity.toNumber(),
|
props.reserve.state.availableLiquidity,
|
||||||
liquidityMint
|
liquidityMint
|
||||||
);
|
);
|
||||||
|
|
||||||
const totalBorrows = useMemo(
|
const totalBorrows = useMemo(
|
||||||
() =>
|
() =>
|
||||||
fromLamports(
|
fromLamports(
|
||||||
wadToLamports(props.reserve.borrowedLiquidityWad),
|
wadToLamports(props.reserve.state.borrowedLiquidityWad),
|
||||||
liquidityMint
|
liquidityMint
|
||||||
),
|
),
|
||||||
[props.reserve, liquidityMint]
|
[props.reserve, liquidityMint]
|
||||||
|
|
|
@ -31,7 +31,7 @@ export const SideReserveOverview = (props: {
|
||||||
const liquidityMint = useMint(reserve.liquidityMint);
|
const liquidityMint = useMint(reserve.liquidityMint);
|
||||||
|
|
||||||
const availableLiquidity = fromLamports(
|
const availableLiquidity = fromLamports(
|
||||||
reserve.availableLiquidity.toNumber(),
|
reserve.state.availableLiquidity,
|
||||||
liquidityMint
|
liquidityMint
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import BN from "bn.js";
|
import BN from "bn.js";
|
||||||
|
|
||||||
export const TEN = new BN(10);
|
export const TEN = new BN(10);
|
||||||
|
export const HALF_WAD = TEN.pow(new BN(18));
|
||||||
export const WAD = TEN.pow(new BN(18));
|
export const WAD = TEN.pow(new BN(18));
|
||||||
export const RAY = TEN.pow(new BN(27));
|
export const RAY = TEN.pow(new BN(27));
|
||||||
export const ZERO = new BN(0);
|
export const ZERO = new BN(0);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
LendingObligationParser,
|
LendingObligationParser,
|
||||||
} from './../models/lending';
|
} from './../models/lending';
|
||||||
import { cache, getMultipleAccounts, MintParser, ParsedAccount } from './accounts';
|
import { cache, getMultipleAccounts, MintParser, ParsedAccount } from './accounts';
|
||||||
import { PublicKey } from '@solana/web3.js';
|
import { PublicKey, AccountInfo } from '@solana/web3.js';
|
||||||
import { DexMarketParser } from '../models/dex';
|
import { DexMarketParser } from '../models/dex';
|
||||||
import { usePrecacheMarket } from './market';
|
import { usePrecacheMarket } from './market';
|
||||||
import { useLendingReserves } from '../hooks';
|
import { useLendingReserves } from '../hooks';
|
||||||
|
@ -41,7 +41,10 @@ export const useLending = () => {
|
||||||
|
|
||||||
// TODO: query for all the dex from reserves
|
// TODO: query for all the dex from reserves
|
||||||
|
|
||||||
const processAccount = useCallback((item) => {
|
const processAccount = useCallback((item : { pubkey: PublicKey, account: AccountInfo<Buffer> }) => {
|
||||||
|
|
||||||
|
console.log('Account length: ', item.account.data.length);
|
||||||
|
|
||||||
if (isLendingReserve(item.account)) {
|
if (isLendingReserve(item.account)) {
|
||||||
const reserve = cache.add(item.pubkey.toBase58(), item.account, LendingReserveParser);
|
const reserve = cache.add(item.pubkey.toBase58(), item.account, LendingReserveParser);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,6 @@ export function calculateCollateralBalance(
|
||||||
reserve: LendingReserve,
|
reserve: LendingReserve,
|
||||||
balanceLamports: number) {
|
balanceLamports: number) {
|
||||||
return reserveMarketCap(reserve) *
|
return reserveMarketCap(reserve) *
|
||||||
(balanceLamports / (reserve?.collateralMintSupply.toNumber() || 1));
|
(balanceLamports / (reserve?.state.collateralMintSupply.toNumber() || 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@ import { PublicKey, SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY, TransactionInstruct
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import * as BufferLayout from 'buffer-layout';
|
import * as BufferLayout from 'buffer-layout';
|
||||||
import { TOKEN_PROGRAM_ID, LENDING_PROGRAM_ID } from '../../utils/ids';
|
import { TOKEN_PROGRAM_ID, LENDING_PROGRAM_ID } from '../../utils/ids';
|
||||||
import { wadToLamports } from '../../utils/utils';
|
|
||||||
import * as Layout from './../../utils/layout';
|
import * as Layout from './../../utils/layout';
|
||||||
import { LendingInstruction } from './lending';
|
import { LendingInstruction } from './lending';
|
||||||
import { LendingReserve } from './reserve';
|
import { calculateUtilizationRatio, LendingReserve } from './reserve';
|
||||||
|
|
||||||
export enum BorrowAmountType {
|
export enum BorrowAmountType {
|
||||||
LiquidityBorrowAmount = 0,
|
LiquidityBorrowAmount = 0,
|
||||||
|
@ -116,8 +115,7 @@ export const borrowInstruction = (
|
||||||
// deposit APY utilization currentUtilizationRate * borrowAPY
|
// deposit APY utilization currentUtilizationRate * borrowAPY
|
||||||
|
|
||||||
export const calculateBorrowAPY = (reserve: LendingReserve) => {
|
export const calculateBorrowAPY = (reserve: LendingReserve) => {
|
||||||
const totalBorrows = wadToLamports(reserve.borrowedLiquidityWad).toNumber();
|
const currentUtilization = calculateUtilizationRatio(reserve);
|
||||||
const currentUtilization = totalBorrows / (reserve.availableLiquidity.toNumber() + totalBorrows);
|
|
||||||
const optimalUtilization = reserve.config.optimalUtilizationRate / 100;
|
const optimalUtilization = reserve.config.optimalUtilizationRate / 100;
|
||||||
|
|
||||||
let borrowAPY;
|
let borrowAPY;
|
||||||
|
|
|
@ -2,11 +2,10 @@ import { PublicKey, SYSVAR_CLOCK_PUBKEY, TransactionInstruction } from '@solana/
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import * as BufferLayout from 'buffer-layout';
|
import * as BufferLayout from 'buffer-layout';
|
||||||
import { TOKEN_PROGRAM_ID, LENDING_PROGRAM_ID } from '../../utils/ids';
|
import { TOKEN_PROGRAM_ID, LENDING_PROGRAM_ID } from '../../utils/ids';
|
||||||
import { wadToLamports } from '../../utils/utils';
|
|
||||||
import * as Layout from './../../utils/layout';
|
import * as Layout from './../../utils/layout';
|
||||||
import { calculateBorrowAPY } from './borrow';
|
import { calculateBorrowAPY } from './borrow';
|
||||||
import { LendingInstruction } from './lending';
|
import { LendingInstruction } from './lending';
|
||||||
import { LendingReserve } from './reserve';
|
import { calculateUtilizationRatio, LendingReserve } from './reserve';
|
||||||
|
|
||||||
/// Deposit liquidity into a reserve. The output is a collateral token representing ownership
|
/// Deposit liquidity into a reserve. The output is a collateral token representing ownership
|
||||||
/// of the reserve liquidity pool.
|
/// of the reserve liquidity pool.
|
||||||
|
@ -32,7 +31,10 @@ export const depositInstruction = (
|
||||||
reserveSupply: PublicKey,
|
reserveSupply: PublicKey,
|
||||||
collateralMint: PublicKey
|
collateralMint: PublicKey
|
||||||
): TransactionInstruction => {
|
): TransactionInstruction => {
|
||||||
const dataLayout = BufferLayout.struct([BufferLayout.u8('instruction'), Layout.uint64('liquidityAmount')]);
|
const dataLayout = BufferLayout.struct([
|
||||||
|
BufferLayout.u8('instruction'),
|
||||||
|
Layout.uint64('liquidityAmount')
|
||||||
|
]);
|
||||||
|
|
||||||
const data = Buffer.alloc(dataLayout.span);
|
const data = Buffer.alloc(dataLayout.span);
|
||||||
dataLayout.encode(
|
dataLayout.encode(
|
||||||
|
@ -63,8 +65,7 @@ export const depositInstruction = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const calculateDepositAPY = (reserve: LendingReserve) => {
|
export const calculateDepositAPY = (reserve: LendingReserve) => {
|
||||||
const totalBorrows = wadToLamports(reserve.borrowedLiquidityWad).toNumber();
|
const currentUtilization = calculateUtilizationRatio(reserve);
|
||||||
const currentUtilization = totalBorrows / (reserve.availableLiquidity.toNumber() + totalBorrows);
|
|
||||||
|
|
||||||
const borrowAPY = calculateBorrowAPY(reserve);
|
const borrowAPY = calculateBorrowAPY(reserve);
|
||||||
return currentUtilization * borrowAPY;
|
return currentUtilization * borrowAPY;
|
||||||
|
|
|
@ -7,23 +7,38 @@ import {
|
||||||
} from '@solana/web3.js';
|
} from '@solana/web3.js';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import * as BufferLayout from 'buffer-layout';
|
import * as BufferLayout from 'buffer-layout';
|
||||||
|
import { HALF_WAD } from '../../constants';
|
||||||
import { TOKEN_PROGRAM_ID, LENDING_PROGRAM_ID } from '../../utils/ids';
|
import { TOKEN_PROGRAM_ID, LENDING_PROGRAM_ID } from '../../utils/ids';
|
||||||
import { wadToLamports } from '../../utils/utils';
|
import { wadToLamports } from '../../utils/utils';
|
||||||
import * as Layout from './../../utils/layout';
|
import * as Layout from './../../utils/layout';
|
||||||
import { LendingInstruction } from './lending';
|
import { LendingInstruction } from './lending';
|
||||||
|
|
||||||
export const LendingReserveLayout: typeof BufferLayout.Structure = BufferLayout.struct([
|
export const LendingReserveLayout: typeof BufferLayout.Structure = BufferLayout.struct([
|
||||||
Layout.uint64('lastUpdateSlot'),
|
|
||||||
Layout.publicKey('lendingMarket'),
|
Layout.publicKey('lendingMarket'),
|
||||||
Layout.publicKey('liquidityMint'),
|
Layout.publicKey('liquidityMint'),
|
||||||
BufferLayout.u8('liquidityMintDecimals'),
|
BufferLayout.u8('liquidityMintDecimals'),
|
||||||
Layout.publicKey('liquiditySupply'),
|
Layout.publicKey('liquiditySupply'),
|
||||||
Layout.publicKey('collateralMint'),
|
Layout.publicKey('collateralMint'),
|
||||||
Layout.publicKey('collateralSupply'),
|
Layout.publicKey('collateralSupply'),
|
||||||
|
|
||||||
|
Layout.publicKey('collateralFeesReceiver'),
|
||||||
|
|
||||||
// TODO: replace u32 option with generic quivalent
|
// TODO: replace u32 option with generic quivalent
|
||||||
BufferLayout.u32('dexMarketOption'),
|
BufferLayout.u32('dexMarketOption'),
|
||||||
Layout.publicKey('dexMarket'),
|
Layout.publicKey('dexMarket'),
|
||||||
|
|
||||||
|
BufferLayout.struct(
|
||||||
|
[
|
||||||
|
Layout.uint64('lastUpdateSlot'),
|
||||||
|
Layout.uint128('cumulativeBorrowRateWad'),
|
||||||
|
Layout.uint128('borrowedLiquidityWad'),
|
||||||
|
Layout.uint64('availableLiquidity'),
|
||||||
|
Layout.uint64('collateralMintSupply'),
|
||||||
|
],
|
||||||
|
'state'
|
||||||
|
),
|
||||||
|
|
||||||
BufferLayout.struct(
|
BufferLayout.struct(
|
||||||
[
|
[
|
||||||
/// Optimal utilization rate as a percent
|
/// Optimal utilization rate as a percent
|
||||||
|
@ -41,39 +56,40 @@ export const LendingReserveLayout: typeof BufferLayout.Structure = BufferLayout.
|
||||||
/// Max borrow APY
|
/// Max borrow APY
|
||||||
BufferLayout.u8('maxBorrowRate'),
|
BufferLayout.u8('maxBorrowRate'),
|
||||||
|
|
||||||
/// Fee assessed on `BorrowReserveLiquidity`, expressed as a Wad.
|
BufferLayout.struct(
|
||||||
/// Must be between 0 and 10^18, such that 10^18 = 1. A few examples for
|
[
|
||||||
/// clarity:
|
/// Fee assessed on `BorrowReserveLiquidity`, expressed as a Wad.
|
||||||
/// 1% = 10_000_000_000_000_000
|
/// Must be between 0 and 10^18, such that 10^18 = 1. A few examples for
|
||||||
/// 0.01% (1 basis point) = 100_000_000_000_000
|
/// clarity:
|
||||||
/// 0.00001% (Aave borrow fee) = 100_000_000_000
|
/// 1% = 10_000_000_000_000_000
|
||||||
BufferLayout.uint64('borrowFeeWad'),
|
/// 0.01% (1 basis point) = 100_000_000_000_000
|
||||||
|
/// 0.00001% (Aave borrow fee) = 100_000_000_000
|
||||||
|
Layout.uint64('borrowFeeWad'),
|
||||||
|
|
||||||
/// Amount of fee going to host account, if provided in liquidate and repay
|
/// Amount of fee going to host account, if provided in liquidate and repay
|
||||||
BufferLayout.u8('hostFeePercentage'),
|
BufferLayout.u8('hostFeePercentage'),
|
||||||
|
],
|
||||||
|
'fees'
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'config'
|
'config'
|
||||||
),
|
),
|
||||||
|
|
||||||
Layout.uint128('cumulativeBorrowRateWad'),
|
|
||||||
Layout.uint128('borrowedLiquidityWad'),
|
|
||||||
|
|
||||||
Layout.uint64('availableLiquidity'),
|
|
||||||
Layout.uint64('collateralMintSupply'),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const isLendingReserve = (info: AccountInfo<Buffer>) => {
|
export const isLendingReserve = (info: AccountInfo<Buffer>) => {
|
||||||
|
console.log('Lending Reserve: ', LendingReserveLayout.span)
|
||||||
return info.data.length === LendingReserveLayout.span;
|
return info.data.length === LendingReserveLayout.span;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface LendingReserve {
|
export interface LendingReserve {
|
||||||
lastUpdateSlot: BN;
|
|
||||||
|
|
||||||
lendingMarket: PublicKey;
|
lendingMarket: PublicKey;
|
||||||
liquiditySupply: PublicKey;
|
liquiditySupply: PublicKey;
|
||||||
liquidityMint: PublicKey;
|
liquidityMint: PublicKey;
|
||||||
collateralSupply: PublicKey;
|
|
||||||
collateralMint: PublicKey;
|
collateralMint: PublicKey;
|
||||||
|
collateralSupply: PublicKey;
|
||||||
|
collateralFeesReceiver: PublicKey;
|
||||||
|
|
||||||
dexMarketOption: number;
|
dexMarketOption: number;
|
||||||
dexMarket: PublicKey;
|
dexMarket: PublicKey;
|
||||||
|
@ -87,21 +103,27 @@ export interface LendingReserve {
|
||||||
optimalBorrowRate: number;
|
optimalBorrowRate: number;
|
||||||
maxBorrowRate: number;
|
maxBorrowRate: number;
|
||||||
|
|
||||||
borrowFeeWad: BN;
|
fees: {
|
||||||
hostFeePercentage: number;
|
borrowFeeWad: BN;
|
||||||
|
hostFeePercentage: number;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
cumulativeBorrowRateWad: BN;
|
state: {
|
||||||
borrowedLiquidityWad: BN;
|
lastUpdateSlot: BN;
|
||||||
|
cumulativeBorrowRateWad: BN;
|
||||||
|
borrowedLiquidityWad: BN;
|
||||||
|
|
||||||
availableLiquidity: BN;
|
availableLiquidity: BN;
|
||||||
collateralMintSupply: BN;
|
collateralMintSupply: BN;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LendingReserveParser = (pubKey: PublicKey, info: AccountInfo<Buffer>) => {
|
export const LendingReserveParser = (pubKey: PublicKey, info: AccountInfo<Buffer>) => {
|
||||||
const buffer = Buffer.from(info.data);
|
const buffer = Buffer.from(info.data);
|
||||||
const data = LendingReserveLayout.decode(buffer);
|
const data = LendingReserveLayout.decode(buffer) as LendingReserve;
|
||||||
if (data.lastUpdateSlot.toNumber() === 0) return;
|
|
||||||
|
if (data.state.lastUpdateSlot.toNumber() === 0) return;
|
||||||
|
|
||||||
const details = {
|
const details = {
|
||||||
pubkey: pubKey,
|
pubkey: pubKey,
|
||||||
|
@ -111,6 +133,8 @@ export const LendingReserveParser = (pubKey: PublicKey, info: AccountInfo<Buffer
|
||||||
info: data,
|
info: data,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return details;
|
return details;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,20 +200,22 @@ export const initReserveInstruction = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const calculateUtilizationRatio = (reserve: LendingReserve) => {
|
export const calculateUtilizationRatio = (reserve: LendingReserve) => {
|
||||||
let borrowedLiquidity = wadToLamports(reserve.borrowedLiquidityWad).toNumber();
|
const totalBorrows = wadToLamports(reserve.state.borrowedLiquidityWad).toNumber();
|
||||||
return borrowedLiquidity / (reserve.availableLiquidity.toNumber() + borrowedLiquidity);
|
const currentUtilization = totalBorrows / (reserve.state.availableLiquidity.toNumber() + totalBorrows);
|
||||||
|
|
||||||
|
return currentUtilization;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const reserveMarketCap = (reserve?: LendingReserve) => {
|
export const reserveMarketCap = (reserve?: LendingReserve) => {
|
||||||
const available = reserve?.availableLiquidity.toNumber() || 0;
|
const available = reserve?.state.availableLiquidity.toNumber() || 0;
|
||||||
const borrowed = wadToLamports(reserve?.borrowedLiquidityWad).toNumber();
|
const borrowed = wadToLamports(reserve?.state.borrowedLiquidityWad).toNumber();
|
||||||
const total = available + borrowed;
|
const total = available + borrowed;
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const collateralExchangeRate = (reserve?: LendingReserve) => {
|
export const collateralExchangeRate = (reserve?: LendingReserve) => {
|
||||||
return (reserve?.collateralMintSupply.toNumber() || 1) / reserveMarketCap(reserve);
|
return (reserve?.state.collateralMintSupply.toNumber() || 1) / reserveMarketCap(reserve);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const collateralToLiquidity = (collateralAmount: BN | number, reserve?: LendingReserve) => {
|
export const collateralToLiquidity = (collateralAmount: BN | number, reserve?: LendingReserve) => {
|
||||||
|
|
|
@ -51,7 +51,7 @@ export const HomeView = () => {
|
||||||
marketSize: fromLamports(marketCapLamports, liquidityMint?.info) *
|
marketSize: fromLamports(marketCapLamports, liquidityMint?.info) *
|
||||||
price,
|
price,
|
||||||
borrowed: fromLamports(
|
borrowed: fromLamports(
|
||||||
wadToLamports(item.info?.borrowedLiquidityWad).toNumber(),
|
wadToLamports(item.info?.state.borrowedLiquidityWad).toNumber(),
|
||||||
liquidityMint.info
|
liquidityMint.info
|
||||||
) *
|
) *
|
||||||
price,
|
price,
|
||||||
|
|
|
@ -27,14 +27,14 @@ export const LendingReserveItem = (props: {
|
||||||
const liquidityMint = useMint(props.reserve.liquidityMint);
|
const liquidityMint = useMint(props.reserve.liquidityMint);
|
||||||
|
|
||||||
const availableLiquidity = fromLamports(
|
const availableLiquidity = fromLamports(
|
||||||
props.reserve.availableLiquidity.toNumber(),
|
props.reserve.state.availableLiquidity,
|
||||||
liquidityMint
|
liquidityMint
|
||||||
);
|
);
|
||||||
|
|
||||||
const totalBorrows = useMemo(
|
const totalBorrows = useMemo(
|
||||||
() =>
|
() =>
|
||||||
fromLamports(
|
fromLamports(
|
||||||
wadToLamports(props.reserve.borrowedLiquidityWad),
|
wadToLamports(props.reserve.state.borrowedLiquidityWad),
|
||||||
liquidityMint
|
liquidityMint
|
||||||
),
|
),
|
||||||
[props.reserve, liquidityMint]
|
[props.reserve, liquidityMint]
|
||||||
|
|
Loading…
Reference in New Issue