2023-02-21 23:36:59 -08:00
|
|
|
import { AnchorProvider, Wallet } from '@coral-xyz/anchor';
|
2023-02-22 06:08:05 -08:00
|
|
|
import { getAccount } from '@solana/spl-token';
|
2022-08-30 08:01:17 -07:00
|
|
|
import { Cluster, Connection, Keypair } from '@solana/web3.js';
|
2022-12-08 07:04:58 -08:00
|
|
|
import * as dotenv from 'dotenv';
|
2022-08-13 10:36:09 -07:00
|
|
|
import fs from 'fs';
|
2023-02-21 23:36:59 -08:00
|
|
|
import { MangoClient } from '../../src/client';
|
|
|
|
import { MANGO_V4_ID } from '../../src/constants';
|
|
|
|
import { I80F48, ZERO_I80F48 } from '../../src/numbers/I80F48';
|
|
|
|
import { toUiDecimals } from '../../src/utils';
|
2022-12-08 07:04:58 -08:00
|
|
|
dotenv.config();
|
2022-08-13 10:36:09 -07:00
|
|
|
|
2022-08-30 08:01:17 -07:00
|
|
|
const CLUSTER_URL =
|
|
|
|
process.env.CLUSTER_URL_OVERRIDE || process.env.MB_CLUSTER_URL;
|
|
|
|
const PAYER_KEYPAIR =
|
|
|
|
process.env.PAYER_KEYPAIR_OVERRIDE || process.env.MB_PAYER_KEYPAIR;
|
2022-12-08 07:04:58 -08:00
|
|
|
const GROUP_NUM = Number(process.env.GROUP_NUM || 0);
|
2022-08-30 08:01:17 -07:00
|
|
|
const CLUSTER: Cluster =
|
|
|
|
(process.env.CLUSTER_OVERRIDE as Cluster) || 'mainnet-beta';
|
|
|
|
|
2022-10-11 00:38:52 -07:00
|
|
|
async function main(): Promise<void> {
|
2022-08-13 10:36:09 -07:00
|
|
|
const options = AnchorProvider.defaultOptions();
|
2022-08-30 08:01:17 -07:00
|
|
|
const connection = new Connection(CLUSTER_URL!, options);
|
2022-08-13 10:36:09 -07:00
|
|
|
|
|
|
|
const admin = Keypair.fromSecretKey(
|
2022-08-30 08:01:17 -07:00
|
|
|
Buffer.from(JSON.parse(fs.readFileSync(PAYER_KEYPAIR!, 'utf-8'))),
|
2022-08-13 10:36:09 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
const adminWallet = new Wallet(admin);
|
|
|
|
const adminProvider = new AnchorProvider(connection, adminWallet, options);
|
|
|
|
const client = MangoClient.connect(
|
|
|
|
adminProvider,
|
2022-08-30 08:01:17 -07:00
|
|
|
CLUSTER,
|
|
|
|
MANGO_V4_ID[CLUSTER],
|
2022-11-04 07:35:40 -07:00
|
|
|
{ idsSource: 'get-program-accounts' },
|
2022-08-13 10:36:09 -07:00
|
|
|
);
|
|
|
|
|
2022-08-30 08:01:17 -07:00
|
|
|
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
|
2022-08-13 10:36:09 -07:00
|
|
|
console.log(`Group ${group.publicKey.toBase58()}`);
|
|
|
|
|
2022-08-19 07:46:59 -07:00
|
|
|
const banks = Array.from(group.banksMapByMint.values()).flat();
|
2022-08-13 10:36:09 -07:00
|
|
|
const banksMapUsingTokenIndex = new Map(
|
|
|
|
banks.map((bank) => {
|
2022-09-01 00:48:23 -07:00
|
|
|
(bank as any).indexedDepositsByMangoAccounts = ZERO_I80F48();
|
|
|
|
(bank as any).indexedBorrowsByMangoAccounts = ZERO_I80F48();
|
2022-08-13 10:36:09 -07:00
|
|
|
return [bank.tokenIndex, bank];
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
const mangoAccounts = await client.getAllMangoAccounts(group);
|
2023-01-16 03:26:44 -08:00
|
|
|
|
2022-08-13 10:36:09 -07:00
|
|
|
mangoAccounts.map((mangoAccount) =>
|
|
|
|
mangoAccount.tokensActive().forEach((token) => {
|
|
|
|
const bank = banksMapUsingTokenIndex.get(token.tokenIndex);
|
|
|
|
if (token.indexedPosition.isPos()) {
|
|
|
|
(bank as any).indexedDepositsByMangoAccounts = (
|
|
|
|
bank as any
|
|
|
|
).indexedDepositsByMangoAccounts.add(
|
|
|
|
token.indexedPosition.mul(
|
2022-08-31 04:55:15 -07:00
|
|
|
banksMapUsingTokenIndex.get(token.tokenIndex)!.depositIndex,
|
2022-08-13 10:36:09 -07:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (token.indexedPosition.isNeg()) {
|
|
|
|
(bank as any).indexedBorrowsByMangoAccounts = (
|
|
|
|
bank as any
|
|
|
|
).indexedBorrowsByMangoAccounts.add(
|
|
|
|
token.indexedPosition
|
|
|
|
.abs()
|
2022-08-31 04:55:15 -07:00
|
|
|
.mul(banksMapUsingTokenIndex.get(token.tokenIndex)!.borrowIndex),
|
2022-08-13 10:36:09 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
for (const bank of await Array.from(banksMapUsingTokenIndex.values()).sort(
|
|
|
|
(a, b) => a.tokenIndex - b.tokenIndex,
|
|
|
|
)) {
|
2023-02-22 06:08:05 -08:00
|
|
|
const account = await getAccount(
|
|
|
|
client.program.provider.connection,
|
|
|
|
bank.vault,
|
2022-08-15 10:13:18 -07:00
|
|
|
);
|
2023-02-22 06:08:05 -08:00
|
|
|
const vault = I80F48.fromNumber(Number(account.amount));
|
2022-08-15 10:13:18 -07:00
|
|
|
|
|
|
|
const error = vault.sub(
|
|
|
|
(bank as any).indexedDepositsByMangoAccounts
|
|
|
|
.sub((bank as any).indexedBorrowsByMangoAccounts)
|
|
|
|
.add(bank.collectedFeesNative)
|
|
|
|
.add(bank.dust),
|
|
|
|
);
|
|
|
|
|
2022-08-13 10:36:09 -07:00
|
|
|
let res = `${bank.name}`;
|
|
|
|
res =
|
|
|
|
res +
|
2022-08-17 07:54:36 -07:00
|
|
|
`\n ${'tokenIndex'.padEnd(40)} ${bank.tokenIndex}` +
|
|
|
|
`\n ${'bank'.padEnd(40)} ${bank.publicKey}` +
|
|
|
|
`\n ${'vault'.padEnd(40)} ${bank.vault}` +
|
2023-01-16 03:26:44 -08:00
|
|
|
`\n ${'oracle'.padEnd(40)} ${bank.oracle}` +
|
2022-08-17 07:54:36 -07:00
|
|
|
`\n ${'mint'.padEnd(40)} ${bank.mint}` +
|
2022-08-31 04:55:15 -07:00
|
|
|
`\n ${'price'.padEnd(40)} ${bank.price?.toNumber()}` +
|
2022-08-19 07:46:59 -07:00
|
|
|
`\n ${'uiPrice'.padEnd(40)} ${bank.uiPrice}` +
|
2022-08-15 10:13:18 -07:00
|
|
|
`\n ${'error'.padEnd(40)} ${error}` +
|
2022-08-13 10:36:09 -07:00
|
|
|
`\n ${'collectedFeesNative'.padEnd(40)} ${bank.collectedFeesNative}` +
|
2022-08-15 06:53:51 -07:00
|
|
|
`\n ${'dust'.padEnd(40)} ${bank.dust}` +
|
2022-12-08 07:50:11 -08:00
|
|
|
`\n ${'vault balance'.padEnd(40)} ${toUiDecimals(
|
|
|
|
vault,
|
|
|
|
bank.mintDecimals,
|
|
|
|
)}, ${vault} native` +
|
2022-08-13 10:36:09 -07:00
|
|
|
`\n ${'deposits'.padEnd(40)} ${bank.indexedDeposits.mul(
|
|
|
|
bank.depositIndex,
|
|
|
|
)}` +
|
|
|
|
`\n ${'deposits (sum over all mango accounts)'.padEnd(40)} ${
|
|
|
|
(bank as any).indexedDepositsByMangoAccounts
|
|
|
|
}` +
|
2022-08-17 07:54:36 -07:00
|
|
|
`\n ${'borrows'.padEnd(40)} ${bank.indexedBorrows.mul(
|
2022-08-13 10:36:09 -07:00
|
|
|
bank.borrowIndex,
|
|
|
|
)}` +
|
|
|
|
`\n ${'borrows (sum over all mango accounts)'.padEnd(40)} ${
|
|
|
|
(bank as any).indexedBorrowsByMangoAccounts
|
|
|
|
}` +
|
2022-08-19 01:46:34 -07:00
|
|
|
`\n ${'avgUtilization since last rate update'.padEnd(40)} ${(
|
2022-08-17 07:54:36 -07:00
|
|
|
100 * bank.avgUtilization.toNumber()
|
|
|
|
).toFixed(1)}%` +
|
|
|
|
`\n ${'rate parameters'.padEnd(40)} ${(
|
|
|
|
100 * bank.rate0.toNumber()
|
|
|
|
).toFixed()}% @ ${(100 * bank.util0.toNumber()).toFixed()}% util, ${(
|
|
|
|
100 * bank.rate1.toNumber()
|
|
|
|
).toFixed()}% @${(100 * bank.util1.toNumber()).toFixed()}% util, ${(
|
|
|
|
100 * bank.maxRate.toNumber()
|
|
|
|
).toFixed()}% @ 100% util` +
|
|
|
|
`\n ${'depositRate'.padEnd(40)} ${(
|
|
|
|
100 * bank.getDepositRate().toNumber()
|
|
|
|
).toFixed(2)}%` +
|
|
|
|
`\n ${'borrowRate'.padEnd(40)} ${(
|
|
|
|
100 * bank.getBorrowRate().toNumber()
|
|
|
|
).toFixed(2)}%` +
|
2022-08-19 01:46:34 -07:00
|
|
|
`\n ${'last index update'.padEnd(40)} ${new Date(
|
|
|
|
1000 * bank.indexLastUpdated.toNumber(),
|
|
|
|
)}` +
|
|
|
|
`\n ${'last rates update'.padEnd(40)} ${new Date(
|
|
|
|
1000 * bank.bankRateLastUpdated.toNumber(),
|
2022-12-08 07:50:11 -08:00
|
|
|
)}` +
|
|
|
|
`\n ${'net borrows in window'.padEnd(
|
|
|
|
40,
|
|
|
|
)} ${bank.netBorrowsInWindow.toNumber()} / ${bank.netBorrowLimitPerWindowQuote.toNumber()}`;
|
2022-08-13 10:36:09 -07:00
|
|
|
|
|
|
|
console.log(`${res}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
process.exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
main();
|
|
|
|
} catch (error) {
|
|
|
|
console.log(error);
|
|
|
|
}
|