mango-v4/ts/client/src/accounts/bank.ts

605 lines
18 KiB
TypeScript
Raw Normal View History

import { BN } from '@coral-xyz/anchor';
import { utf8 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
import { PublicKey } from '@solana/web3.js';
import { I80F48, I80F48Dto, ONE_I80F48, ZERO_I80F48 } from '../numbers/I80F48';
import { As, toUiDecimals } from '../utils';
import { OracleProvider } from './oracle';
export type TokenIndex = number & As<'token-index'>;
export type OracleConfigDto = {
2022-06-21 03:38:01 -07:00
confFilter: I80F48Dto;
maxStalenessSlots: BN;
};
export type OracleConfig = {
confFilter: I80F48;
maxStalenessSlots: BN;
2022-06-21 03:38:01 -07:00
};
export type StablePriceModel = {
stablePrice: number;
lastUpdateTimestamp: BN;
delayPrices: number[];
delayAccumulatorPrice: number;
delayAccumulatorTime: number;
delayIntervalSeconds: number;
delayGrowthLimit: number;
stableGrowthLimit: number;
lastDelayIntervalIndex: number;
};
export interface BankForHealth {
tokenIndex: TokenIndex;
maintAssetWeight: I80F48;
initAssetWeight: I80F48;
maintLiabWeight: I80F48;
initLiabWeight: I80F48;
price: I80F48;
stablePriceModel: StablePriceModel;
scaledInitAssetWeight(price: I80F48): I80F48;
scaledInitLiabWeight(price: I80F48): I80F48;
nativeDeposits(): I80F48;
nativeBorrows(): I80F48;
depositWeightScaleStartQuote: number;
borrowWeightScaleStartQuote: number;
}
export class Bank implements BankForHealth {
public name: string;
public oracleConfig: OracleConfig;
public depositIndex: I80F48;
public borrowIndex: I80F48;
public indexedDeposits: I80F48;
public indexedBorrows: I80F48;
public avgUtilization: I80F48;
public adjustmentFactor: I80F48;
2022-06-21 03:38:01 -07:00
public maxRate: I80F48;
public rate0: I80F48;
public rate1: I80F48;
public util0: I80F48;
public util1: I80F48;
public _price: I80F48 | undefined;
public _uiPrice: number | undefined;
public _oracleLastUpdatedSlot: number | undefined;
public _oracleProvider: OracleProvider | undefined;
public collectedFeesNative: I80F48;
public loanFeeRate: I80F48;
public loanOriginationFeeRate: I80F48;
public initAssetWeight: I80F48;
public maintAssetWeight: I80F48;
public initLiabWeight: I80F48;
public maintLiabWeight: I80F48;
public liquidationFee: I80F48;
public dust: I80F48;
static from(
publicKey: PublicKey,
obj: {
group: PublicKey;
name: number[];
mint: PublicKey;
vault: PublicKey;
oracle: PublicKey;
oracleConfig: OracleConfigDto;
stablePriceModel: StablePriceModel;
depositIndex: I80F48Dto;
borrowIndex: I80F48Dto;
indexedDeposits: I80F48Dto;
indexedBorrows: I80F48Dto;
indexLastUpdated: BN;
bankRateLastUpdated: BN;
avgUtilization: I80F48Dto;
adjustmentFactor: I80F48Dto;
util0: I80F48Dto;
rate0: I80F48Dto;
util1: I80F48Dto;
rate1: I80F48Dto;
maxRate: I80F48Dto;
collectedFeesNative: I80F48Dto;
loanOriginationFeeRate: I80F48Dto;
loanFeeRate: I80F48Dto;
maintAssetWeight: I80F48Dto;
initAssetWeight: I80F48Dto;
maintLiabWeight: I80F48Dto;
initLiabWeight: I80F48Dto;
liquidationFee: I80F48Dto;
dust: I80F48Dto;
flashLoanTokenAccountInitial: BN;
flashLoanApprovedAmount: BN;
tokenIndex: number;
mintDecimals: number;
bankNum: number;
minVaultToDepositsRatio: number;
netBorrowLimitWindowSizeTs: BN;
lastNetBorrowsWindowStartTs: BN;
netBorrowLimitPerWindowQuote: BN;
netBorrowsInWindow: BN;
borrowWeightScaleStartQuote: number;
depositWeightScaleStartQuote: number;
reduceOnly: number;
forceClose: number;
feesWithdrawn: BN;
tokenConditionalSwapTakerFeeRate: number;
tokenConditionalSwapMakerFeeRate: number;
flashLoanDepositFeeRate: number;
},
): Bank {
return new Bank(
publicKey,
obj.group,
obj.name,
obj.mint,
obj.vault,
obj.oracle,
2022-06-21 03:38:01 -07:00
obj.oracleConfig,
obj.stablePriceModel,
obj.depositIndex,
obj.borrowIndex,
obj.indexedDeposits,
obj.indexedBorrows,
obj.indexLastUpdated,
obj.bankRateLastUpdated,
obj.avgUtilization,
obj.adjustmentFactor,
obj.util0,
obj.rate0,
obj.util1,
obj.rate1,
obj.maxRate,
obj.collectedFeesNative,
obj.loanOriginationFeeRate,
obj.loanFeeRate,
obj.maintAssetWeight,
obj.initAssetWeight,
obj.maintLiabWeight,
obj.initLiabWeight,
obj.liquidationFee,
obj.dust,
obj.flashLoanTokenAccountInitial,
obj.flashLoanApprovedAmount,
obj.tokenIndex as TokenIndex,
obj.mintDecimals,
obj.bankNum,
obj.minVaultToDepositsRatio,
obj.netBorrowLimitWindowSizeTs,
obj.lastNetBorrowsWindowStartTs,
obj.netBorrowLimitPerWindowQuote,
obj.netBorrowsInWindow,
obj.borrowWeightScaleStartQuote,
obj.depositWeightScaleStartQuote,
obj.reduceOnly,
obj.forceClose == 1,
obj.feesWithdrawn,
obj.tokenConditionalSwapTakerFeeRate,
obj.tokenConditionalSwapMakerFeeRate,
obj.flashLoanDepositFeeRate,
);
}
constructor(
public publicKey: PublicKey,
public group: PublicKey,
name: number[],
public mint: PublicKey,
public vault: PublicKey,
public oracle: PublicKey,
oracleConfig: OracleConfigDto,
public stablePriceModel: StablePriceModel,
depositIndex: I80F48Dto,
borrowIndex: I80F48Dto,
indexedDeposits: I80F48Dto,
indexedBorrows: I80F48Dto,
public indexLastUpdated: BN,
public bankRateLastUpdated: BN,
avgUtilization: I80F48Dto,
adjustmentFactor: I80F48Dto,
util0: I80F48Dto,
rate0: I80F48Dto,
util1: I80F48Dto,
rate1: I80F48Dto,
2022-06-21 03:38:01 -07:00
maxRate: I80F48Dto,
collectedFeesNative: I80F48Dto,
loanOriginationFeeRate: I80F48Dto,
loanFeeRate: I80F48Dto,
maintAssetWeight: I80F48Dto,
initAssetWeight: I80F48Dto,
maintLiabWeight: I80F48Dto,
initLiabWeight: I80F48Dto,
liquidationFee: I80F48Dto,
2022-08-04 10:42:41 -07:00
dust: I80F48Dto,
2023-07-19 11:57:29 -07:00
public flashLoanTokenAccountInitial: BN,
public flashLoanApprovedAmount: BN,
public tokenIndex: TokenIndex,
public mintDecimals: number,
public bankNum: number,
public minVaultToDepositsRatio: number,
public netBorrowLimitWindowSizeTs: BN,
public lastNetBorrowsWindowStartTs: BN,
public netBorrowLimitPerWindowQuote: BN,
public netBorrowsInWindow: BN,
public borrowWeightScaleStartQuote: number,
public depositWeightScaleStartQuote: number,
public reduceOnly: number,
public forceClose: boolean,
public feesWithdrawn: BN,
public tokenConditionalSwapTakerFeeRate: number,
public tokenConditionalSwapMakerFeeRate: number,
public flashLoanDepositFeeRate: number,
) {
this.name = utf8.decode(new Uint8Array(name)).split('\x00')[0];
this.oracleConfig = {
confFilter: I80F48.from(oracleConfig.confFilter),
maxStalenessSlots: oracleConfig.maxStalenessSlots,
} as OracleConfig;
this.depositIndex = I80F48.from(depositIndex);
this.borrowIndex = I80F48.from(borrowIndex);
this.indexedDeposits = I80F48.from(indexedDeposits);
this.indexedBorrows = I80F48.from(indexedBorrows);
this.avgUtilization = I80F48.from(avgUtilization);
this.adjustmentFactor = I80F48.from(adjustmentFactor);
2022-06-21 03:38:01 -07:00
this.maxRate = I80F48.from(maxRate);
this.util0 = I80F48.from(util0);
this.rate0 = I80F48.from(rate0);
this.util1 = I80F48.from(util1);
this.rate1 = I80F48.from(rate1);
this.collectedFeesNative = I80F48.from(collectedFeesNative);
this.loanFeeRate = I80F48.from(loanFeeRate);
this.loanOriginationFeeRate = I80F48.from(loanOriginationFeeRate);
this.maintAssetWeight = I80F48.from(maintAssetWeight);
this.initAssetWeight = I80F48.from(initAssetWeight);
this.maintLiabWeight = I80F48.from(maintLiabWeight);
this.initLiabWeight = I80F48.from(initLiabWeight);
this.liquidationFee = I80F48.from(liquidationFee);
this.dust = I80F48.from(dust);
this._price = undefined;
this._uiPrice = undefined;
this._oracleLastUpdatedSlot = undefined;
this._oracleProvider = undefined;
}
toString(): string {
return (
'Bank ' +
'\n public key - ' +
this.publicKey.toBase58() +
'\n token index - ' +
this.tokenIndex +
'\n token name - ' +
this.name +
'\n vault - ' +
this.vault.toBase58() +
'\n mintDecimals - ' +
this.mintDecimals +
'\n oracle - ' +
this.oracle.toBase58() +
'\n price - ' +
this._price?.toString() +
'\n uiPrice - ' +
this._uiPrice +
'\n deposit index - ' +
this.depositIndex.toString() +
'\n borrow index - ' +
this.borrowIndex.toString() +
'\n indexedDeposits - ' +
this.indexedDeposits.toString() +
'\n indexedBorrows - ' +
this.indexedBorrows.toString() +
'\n indexLastUpdated - ' +
new Date(this.indexLastUpdated.toNumber() * 1000) +
'\n bankRateLastUpdated - ' +
new Date(this.bankRateLastUpdated.toNumber() * 1000) +
'\n avgUtilization - ' +
this.avgUtilization.toString() +
'\n adjustmentFactor - ' +
this.adjustmentFactor.toString() +
'\n maxRate - ' +
this.maxRate.toString() +
'\n util0 - ' +
this.util0.toString() +
'\n rate0 - ' +
this.rate0.toString() +
'\n util1 - ' +
this.util1.toString() +
'\n rate1 - ' +
this.rate1.toString() +
'\n loanFeeRate - ' +
this.loanFeeRate.toString() +
'\n loanOriginationFeeRate - ' +
this.loanOriginationFeeRate.toString() +
'\n maintAssetWeight - ' +
this.maintAssetWeight.toString() +
'\n initAssetWeight - ' +
this.initAssetWeight.toString() +
'\n maintLiabWeight - ' +
this.maintLiabWeight.toString() +
'\n initLiabWeight - ' +
this.initLiabWeight.toString() +
'\n liquidationFee - ' +
this.liquidationFee.toString() +
'\n uiDeposits() - ' +
this.uiDeposits() +
'\n uiBorrows() - ' +
this.uiBorrows() +
'\n getDepositRate() - ' +
this.getDepositRate().toString() +
'\n getBorrowRate() - ' +
this.getBorrowRate().toString()
);
}
2022-06-21 03:38:01 -07:00
areDepositsReduceOnly(): boolean {
return this.reduceOnly == 1;
}
areBorrowsReduceOnly(): boolean {
return this.reduceOnly == 1 || this.reduceOnly == 2;
}
scaledInitAssetWeight(price: I80F48): I80F48 {
const depositsQuote = this.nativeDeposits().mul(price);
if (
this.depositWeightScaleStartQuote >= Number.MAX_SAFE_INTEGER ||
depositsQuote.lte(I80F48.fromNumber(this.depositWeightScaleStartQuote))
) {
return this.initAssetWeight;
}
return this.initAssetWeight.mul(
I80F48.fromNumber(this.depositWeightScaleStartQuote).div(depositsQuote),
);
}
scaledInitLiabWeight(price: I80F48): I80F48 {
const borrowsQuote = this.nativeBorrows().mul(price);
if (
this.borrowWeightScaleStartQuote >= Number.MAX_SAFE_INTEGER ||
borrowsQuote.lte(I80F48.fromNumber(this.borrowWeightScaleStartQuote))
) {
return this.initLiabWeight;
}
return this.initLiabWeight.mul(
borrowsQuote.div(I80F48.fromNumber(this.borrowWeightScaleStartQuote)),
);
}
getAssetPrice(): I80F48 {
return this.price.min(I80F48.fromNumber(this.stablePriceModel.stablePrice));
}
getLiabPrice(): I80F48 {
return this.price.max(I80F48.fromNumber(this.stablePriceModel.stablePrice));
}
get price(): I80F48 {
if (this._price === undefined) {
throw new Error(
`Undefined price for bank ${this.publicKey} with tokenIndex ${this.tokenIndex}!`,
);
}
return this._price;
}
get uiPrice(): number {
if (this._uiPrice === undefined) {
throw new Error(
`Undefined uiPrice for bank ${this.publicKey} with tokenIndex ${this.tokenIndex}!`,
);
}
return this._uiPrice;
}
get oracleLastUpdatedSlot(): number {
if (this._oracleLastUpdatedSlot === undefined) {
throw new Error(
`Undefined oracleLastUpdatedSlot for bank ${this.publicKey} with tokenIndex ${this.tokenIndex}!`,
);
}
return this._oracleLastUpdatedSlot;
}
get oracleProvider(): OracleProvider {
if (this._oracleProvider === undefined) {
throw new Error(
`Undefined oracleProvider for bank ${this.publicKey} with tokenIndex ${this.tokenIndex}!`,
);
}
return this._oracleProvider;
}
2022-06-21 03:38:01 -07:00
nativeDeposits(): I80F48 {
return this.indexedDeposits.mul(this.depositIndex);
2022-06-21 03:38:01 -07:00
}
nativeBorrows(): I80F48 {
return this.indexedBorrows.mul(this.borrowIndex);
2022-06-21 03:38:01 -07:00
}
uiDeposits(): number {
return toUiDecimals(this.nativeDeposits(), this.mintDecimals);
2022-06-21 03:38:01 -07:00
}
uiBorrows(): number {
return toUiDecimals(this.nativeBorrows(), this.mintDecimals);
2022-06-21 03:38:01 -07:00
}
/**
*
merge deploy changes to dev (#586) * expose perp order type on perp order Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.9.17 * Fix funding rate method Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix scrript Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.9.18 * ts-client v0.9.19 * fix script * update reduce only and force close flags in ts client Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.1 * expose underlying property Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.2 * Fix bug in closing mango account (#559) * reafactor code for collecting health accounts, fix bug where bank oracle was skipped while closing account Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.3 * fix client code for building health accounts Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.4 * Fix bug in sim max serum3 bid Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.5 * increase charge Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * ts-client v0.14.0 * Fix getBorrowRate() to include loan upkeep * ts-client v0.14.1 * Client: Move jup's CU ix outside of flash loan That makes a flash loan based jup swap usable with delegates. * liquidator: Don't attempt to close in-use token positions This could happen if the user manually used serum on the liquidator account. * Mc/ci cd (#570) * prettier Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix branch Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * rename Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Increase iterations for max swap to fix some edge case, fix debug script since fees are already accounted for Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.14.2 * Risk notification bot (#565) * risk stuff Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * cleanup Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * client function Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.0 * fix risk computati Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.2 * Fix units Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * dont drop or rally stable assets Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * dont skip usdc Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.3 * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.4 * update Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.5 * update Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.6 * add highlight Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.7 * Fix math Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.10 * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.12 --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> Co-authored-by: Christian Kamm <mail@ckamm.de>
2023-05-16 10:20:43 -07:00
* @returns borrow rate, 0 is 0% where 1 is 100%; not including loan upkeep rate
*/
merge deploy changes to dev (#586) * expose perp order type on perp order Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.9.17 * Fix funding rate method Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix scrript Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.9.18 * ts-client v0.9.19 * fix script * update reduce only and force close flags in ts client Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.1 * expose underlying property Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.2 * Fix bug in closing mango account (#559) * reafactor code for collecting health accounts, fix bug where bank oracle was skipped while closing account Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.3 * fix client code for building health accounts Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.4 * Fix bug in sim max serum3 bid Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.5 * increase charge Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * ts-client v0.14.0 * Fix getBorrowRate() to include loan upkeep * ts-client v0.14.1 * Client: Move jup's CU ix outside of flash loan That makes a flash loan based jup swap usable with delegates. * liquidator: Don't attempt to close in-use token positions This could happen if the user manually used serum on the liquidator account. * Mc/ci cd (#570) * prettier Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix branch Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * rename Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Increase iterations for max swap to fix some edge case, fix debug script since fees are already accounted for Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.14.2 * Risk notification bot (#565) * risk stuff Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * cleanup Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * client function Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.0 * fix risk computati Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.2 * Fix units Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * dont drop or rally stable assets Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * dont skip usdc Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.3 * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.4 * update Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.5 * update Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.6 * add highlight Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.7 * Fix math Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.10 * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.12 --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> Co-authored-by: Christian Kamm <mail@ckamm.de>
2023-05-16 10:20:43 -07:00
getBorrowRateWithoutUpkeepRate(): I80F48 {
2022-06-21 03:38:01 -07:00
const totalBorrows = this.nativeBorrows();
const totalDeposits = this.nativeDeposits();
if (totalDeposits.isZero() || totalBorrows.isZero()) {
return ZERO_I80F48();
2022-06-21 03:38:01 -07:00
}
const utilization = totalBorrows.div(totalDeposits);
if (utilization.lt(this.util0)) {
const slope = this.rate0.div(this.util0);
return slope.mul(utilization);
} else if (utilization.lt(this.util1)) {
const extraUtil = utilization.sub(this.util0);
const slope = this.rate1.sub(this.rate0).div(this.util1.sub(this.util0));
return this.rate0.add(slope.mul(extraUtil));
} else {
2022-06-21 03:38:01 -07:00
const extraUtil = utilization.sub(this.util1);
const slope = this.maxRate
.sub(this.rate1)
.div(I80F48.fromNumber(1).sub(this.util1));
return this.rate1.add(slope.mul(extraUtil));
}
}
/**
*
merge deploy changes to dev (#586) * expose perp order type on perp order Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.9.17 * Fix funding rate method Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix scrript Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.9.18 * ts-client v0.9.19 * fix script * update reduce only and force close flags in ts client Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.1 * expose underlying property Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.2 * Fix bug in closing mango account (#559) * reafactor code for collecting health accounts, fix bug where bank oracle was skipped while closing account Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.3 * fix client code for building health accounts Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.4 * Fix bug in sim max serum3 bid Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.13.5 * increase charge Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * ts-client v0.14.0 * Fix getBorrowRate() to include loan upkeep * ts-client v0.14.1 * Client: Move jup's CU ix outside of flash loan That makes a flash loan based jup swap usable with delegates. * liquidator: Don't attempt to close in-use token positions This could happen if the user manually used serum on the liquidator account. * Mc/ci cd (#570) * prettier Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix branch Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * rename Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Increase iterations for max swap to fix some edge case, fix debug script since fees are already accounted for Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.14.2 * Risk notification bot (#565) * risk stuff Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * cleanup Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * client function Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.0 * fix risk computati Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.2 * Fix units Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * dont drop or rally stable assets Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * dont skip usdc Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fixes from review Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.3 * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.4 * update Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.5 * update Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.6 * add highlight Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.7 * Fix math Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.10 * Fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * v0.15.12 --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> Co-authored-by: Christian Kamm <mail@ckamm.de>
2023-05-16 10:20:43 -07:00
* @returns total borrow rate, 0 is 0% where 1 is 100% (including loan upkeep rate)
*/
getBorrowRate(): I80F48 {
return this.getBorrowRateWithoutUpkeepRate().add(this.loanFeeRate);
}
/**
*
* @returns total borrow rate percentage (including loan upkeep rate)
*/
getBorrowRateUi(): number {
return this.getBorrowRate().toNumber() * 100;
}
/**
*
* @returns deposit rate, 0 is 0% where 1 is 100%
*/
2022-06-21 03:38:01 -07:00
getDepositRate(): I80F48 {
const borrowRate = this.getBorrowRate();
const totalBorrows = this.nativeBorrows();
const totalDeposits = this.nativeDeposits();
if (totalDeposits.isZero() && totalBorrows.isZero()) {
return ZERO_I80F48();
} else if (totalDeposits.isZero()) {
2022-06-21 03:38:01 -07:00
return this.maxRate;
}
const utilization = totalBorrows.div(totalDeposits);
return utilization.mul(borrowRate);
}
/**
*
* @returns deposit rate percentage
*/
getDepositRateUi(): number {
return this.getDepositRate().toNumber() * 100;
}
getNetBorrowLimitPerWindow(): I80F48 {
return I80F48.fromI64(this.netBorrowLimitPerWindowQuote).div(this.price);
}
getBorrowLimitLeftInWindow(): I80F48 {
return this.getNetBorrowLimitPerWindow()
.sub(I80F48.fromI64(this.netBorrowsInWindow))
.max(ZERO_I80F48());
}
getNetBorrowLimitPerWindowUi(): number {
return toUiDecimals(this.getNetBorrowLimitPerWindow(), this.mintDecimals);
}
getMaxWithdraw(vaultBalance: BN, userDeposits = ZERO_I80F48()): I80F48 {
userDeposits = userDeposits.max(ZERO_I80F48());
// any borrow must respect the minVaultToDepositsRatio
const minVaultBalanceRequired = this.nativeDeposits().mul(
I80F48.fromNumber(this.minVaultToDepositsRatio),
);
const maxBorrowFromVault = I80F48.fromI64(vaultBalance)
.sub(minVaultBalanceRequired)
.max(ZERO_I80F48());
// User deposits can exceed maxWithdrawFromVault
let maxBorrow = maxBorrowFromVault.sub(userDeposits).max(ZERO_I80F48());
// any borrow must respect the limit left in window
maxBorrow = maxBorrow.min(this.getBorrowLimitLeftInWindow());
// borrows would be applied a fee
maxBorrow = maxBorrow.div(ONE_I80F48().add(this.loanOriginationFeeRate));
// user deposits can always be withdrawn
// even if vaults can be depleted
return maxBorrow.add(userDeposits).min(I80F48.fromI64(vaultBalance));
}
getTimeToNextBorrowLimitWindowStartsTs(): number {
return this.netBorrowLimitWindowSizeTs
.sub(new BN(Date.now() / 1000).sub(this.lastNetBorrowsWindowStartTs))
.toNumber();
}
}
export class MintInfo {
static from(
publicKey: PublicKey,
obj: {
group: PublicKey;
tokenIndex: number;
mint: PublicKey;
banks: PublicKey[];
vaults: PublicKey[];
oracle: PublicKey;
registrationTime: BN;
groupInsuranceFund: number;
},
): MintInfo {
return new MintInfo(
publicKey,
obj.group,
obj.tokenIndex as TokenIndex,
obj.mint,
obj.banks,
obj.vaults,
obj.oracle,
obj.registrationTime,
obj.groupInsuranceFund == 1,
);
}
constructor(
public publicKey: PublicKey,
public group: PublicKey,
public tokenIndex: TokenIndex,
public mint: PublicKey,
public banks: PublicKey[],
public vaults: PublicKey[],
public oracle: PublicKey,
public registrationTime: BN,
public groupInsuranceFund: boolean,
) {}
public firstBank(): PublicKey {
return this.banks[0];
}
public firstVault(): PublicKey {
return this.vaults[0];
}
toString(): string {
2022-08-04 10:42:41 -07:00
const res =
'mint ' +
this.mint.toBase58() +
'\n oracle ' +
this.oracle.toBase58() +
'\n banks ' +
this.banks
.filter((pk) => pk.toBase58() !== PublicKey.default.toBase58())
.toString() +
'\n vaults ' +
this.vaults
.filter((pk) => pk.toBase58() !== PublicKey.default.toBase58())
.toString();
return res;
}
}