ts: Fix getMaxWithdrawWithBorrowForToken and add getGroupTokenVaultBalanceByMint
Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
parent
9aa0a94794
commit
357710dc24
|
@ -1,16 +1,17 @@
|
||||||
import { BorshAccountsCoder } from '@project-serum/anchor';
|
import { BorshAccountsCoder } from '@project-serum/anchor';
|
||||||
|
import { coder } from '@project-serum/anchor/dist/cjs/spl/associated-token';
|
||||||
import { Market } from '@project-serum/serum';
|
import { Market } from '@project-serum/serum';
|
||||||
import { parsePriceData, PriceData } from '@pythnetwork/client';
|
import { parsePriceData, PriceData } from '@pythnetwork/client';
|
||||||
import { PublicKey } from '@solana/web3.js';
|
import { PublicKey } from '@solana/web3.js';
|
||||||
|
import BN from 'bn.js';
|
||||||
import { MangoClient } from '../client';
|
import { MangoClient } from '../client';
|
||||||
import { SERUM3_PROGRAM_ID } from '../constants';
|
import { SERUM3_PROGRAM_ID } from '../constants';
|
||||||
import { Id } from '../ids';
|
import { Id } from '../ids';
|
||||||
|
import { toNativeDecimals } from '../utils';
|
||||||
import { Bank, MintInfo } from './bank';
|
import { Bank, MintInfo } from './bank';
|
||||||
import { I80F48, ONE_I80F48 } from './I80F48';
|
import { I80F48, ONE_I80F48 } from './I80F48';
|
||||||
import { PerpMarket } from './perp';
|
import { PerpMarket } from './perp';
|
||||||
import { Serum3Market } from './serum3';
|
import { Serum3Market } from './serum3';
|
||||||
import { toNativeDecimals } from '../utils';
|
|
||||||
import BN from 'bn.js';
|
|
||||||
|
|
||||||
export class Group {
|
export class Group {
|
||||||
static from(
|
static from(
|
||||||
|
@ -267,6 +268,30 @@ export class Group {
|
||||||
return this.banksMapByTokenIndex.get(tokenIndex)[0];
|
return this.banksMapByTokenIndex.get(tokenIndex)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param mintPk
|
||||||
|
* @returns sum of native balances of all vaults for a token
|
||||||
|
*/
|
||||||
|
public async getGroupTokenVaultBalanceByMint(
|
||||||
|
client: MangoClient,
|
||||||
|
mintPk: PublicKey,
|
||||||
|
): Promise<I80F48> {
|
||||||
|
const banks = this.banksMapByMint.get(mintPk.toString());
|
||||||
|
const amount = new BN(0);
|
||||||
|
for (const bank of banks) {
|
||||||
|
amount.add(
|
||||||
|
coder().accounts.decode(
|
||||||
|
'token',
|
||||||
|
(await client.program.provider.connection.getAccountInfo(bank.vault))
|
||||||
|
.data,
|
||||||
|
).amount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return new I80F48(amount);
|
||||||
|
}
|
||||||
|
|
||||||
public consoleLogBanks() {
|
public consoleLogBanks() {
|
||||||
for (const mintBanks of this.banksMapByMint.values()) {
|
for (const mintBanks of this.banksMapByMint.values()) {
|
||||||
for (const bank of mintBanks) {
|
for (const bank of mintBanks) {
|
||||||
|
|
|
@ -365,8 +365,8 @@ export class HealthCache {
|
||||||
|
|
||||||
return amount
|
return amount
|
||||||
.div(source.oraclePrice)
|
.div(source.oraclePrice)
|
||||||
.mul(
|
.div(
|
||||||
ONE_I80F48.sub(
|
ONE_I80F48.add(
|
||||||
group.getFirstBankByMint(sourceMintPk).loanOriginationFeeRate,
|
group.getFirstBankByMint(sourceMintPk).loanOriginationFeeRate,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -101,11 +101,9 @@ export class MangoAccount {
|
||||||
|
|
||||||
static getEquivalentUsdcPosition(
|
static getEquivalentUsdcPosition(
|
||||||
sourceBank: Bank,
|
sourceBank: Bank,
|
||||||
nativeTokenPosition: TokenPosition,
|
tp: TokenPosition,
|
||||||
): I80F48 {
|
): I80F48 {
|
||||||
return nativeTokenPosition
|
return tp ? tp.balance(sourceBank).mul(sourceBank.price) : ZERO_I80F48;
|
||||||
? nativeTokenPosition.balance(sourceBank).mul(sourceBank.price)
|
|
||||||
: ZERO_I80F48;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static getEquivalentTokenPosition(
|
static getEquivalentTokenPosition(
|
||||||
|
@ -244,23 +242,27 @@ export class MangoAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The amount of given native token you can borrow, considering all existing assets as collateral except the deposits for this token.
|
* The amount of given native token you can withdraw including borrows, considering all existing assets as collateral.
|
||||||
* Note 1: The existing native deposits need to be added to get the full amount that could be withdrawn.
|
* @returns amount of given native token you can borrow, considering all existing assets as collateral, in native token
|
||||||
* Note 2: The group might have less native deposits than what this returns. TODO: loan origination fees
|
|
||||||
* @returns amount of given native token you can borrow, considering all existing assets as collateral except the deposits for this token, in native token
|
|
||||||
*/
|
*/
|
||||||
getMaxWithdrawWithBorrowForToken(group: Group, mintPk: PublicKey): I80F48 {
|
getMaxWithdrawWithBorrowForToken(group: Group, mintPk: PublicKey): I80F48 {
|
||||||
const bank: Bank = group.getFirstBankByMint(mintPk);
|
const bank: Bank = group.getFirstBankByMint(mintPk);
|
||||||
const initHealth = (this.accountData as MangoAccountData).initHealth;
|
const initHealth = (this.accountData as MangoAccountData).initHealth;
|
||||||
const inUsdcUnits = MangoAccount.getEquivalentUsdcPosition(
|
const existingPositioninUsdcUnits = MangoAccount.getEquivalentUsdcPosition(
|
||||||
bank,
|
bank,
|
||||||
this.findToken(bank.tokenIndex),
|
this.findToken(bank.tokenIndex),
|
||||||
).max(ZERO_I80F48);
|
).max(ZERO_I80F48);
|
||||||
const newInitHealth = initHealth.sub(inUsdcUnits.mul(bank.initAssetWeight));
|
const initHealthWithoutExistingPosition = initHealth.sub(
|
||||||
return MangoAccount.getEquivalentTokenPosition(
|
existingPositioninUsdcUnits.mul(bank.initAssetWeight),
|
||||||
bank,
|
|
||||||
newInitHealth.div(bank.initLiabWeight),
|
|
||||||
);
|
);
|
||||||
|
const maxBorrowNative = MangoAccount.getEquivalentTokenPosition(
|
||||||
|
bank,
|
||||||
|
initHealthWithoutExistingPosition.div(bank.initLiabWeight),
|
||||||
|
);
|
||||||
|
const maxBorrowNativeWithoutFees = maxBorrowNative.div(
|
||||||
|
ONE_I80F48.add(bank.loanOriginationFeeRate),
|
||||||
|
);
|
||||||
|
return maxBorrowNativeWithoutFees.add(this.getTokenBalance(bank));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -73,9 +73,8 @@ async function main() {
|
||||||
coder()
|
coder()
|
||||||
.accounts.decode(
|
.accounts.decode(
|
||||||
'token',
|
'token',
|
||||||
await (
|
(await client.program.provider.connection.getAccountInfo(bank.vault))
|
||||||
await client.program.provider.connection.getAccountInfo(bank.vault)
|
.data,
|
||||||
).data,
|
|
||||||
)
|
)
|
||||||
.amount.toNumber(),
|
.amount.toNumber(),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue