From 03dbac82f9821f581f93a877772a97fdedf67dc6 Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Mon, 15 Aug 2022 19:13:18 +0200 Subject: [PATCH 1/8] error for debugging banks Signed-off-by: microwavedcola1 --- ts/client/src/debug-scripts/mb-debug-banks.ts | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/ts/client/src/debug-scripts/mb-debug-banks.ts b/ts/client/src/debug-scripts/mb-debug-banks.ts index ddaa6b7f5..275ae337a 100644 --- a/ts/client/src/debug-scripts/mb-debug-banks.ts +++ b/ts/client/src/debug-scripts/mb-debug-banks.ts @@ -2,7 +2,7 @@ import { AnchorProvider, Wallet } from '@project-serum/anchor'; import { coder } from '@project-serum/anchor/dist/cjs/spl/token'; import { Connection, Keypair } from '@solana/web3.js'; import fs from 'fs'; -import { ZERO_I80F48 } from '../accounts/I80F48'; +import { I80F48, ZERO_I80F48 } from '../accounts/I80F48'; import { MangoClient } from '../client'; import { MANGO_V4_ID } from '../constants'; @@ -69,9 +69,28 @@ async function main() { for (const bank of await Array.from(banksMapUsingTokenIndex.values()).sort( (a, b) => a.tokenIndex - b.tokenIndex, )) { + const vault = I80F48.fromNumber( + coder() + .accounts.decode( + 'token', + await ( + await client.program.provider.connection.getAccountInfo(bank.vault) + ).data, + ) + .amount.toNumber(), + ); + + const error = vault.sub( + (bank as any).indexedDepositsByMangoAccounts + .sub((bank as any).indexedBorrowsByMangoAccounts) + .add(bank.collectedFeesNative) + .add(bank.dust), + ); + let res = `${bank.name}`; res = res + + `\n ${'error'.padEnd(40)} ${error}` + `\n ${'collectedFeesNative'.padEnd(40)} ${bank.collectedFeesNative}` + `\n ${'dust'.padEnd(40)} ${bank.dust}` + `\n ${'deposits'.padEnd(40)} ${bank.indexedDeposits.mul( @@ -95,14 +114,7 @@ async function main() { `\n ${'avgUtilization'.padEnd(40)} ${bank.avgUtilization}` + `\n ${'depositRate'.padEnd(40)} ${bank.getDepositRate()}` + `\n ${'borrowRate'.padEnd(40)} ${bank.getBorrowRate()}` + - `\n ${'vault'.padEnd(40)} ${coder() - .accounts.decode( - 'token', - await ( - await client.program.provider.connection.getAccountInfo(bank.vault) - ).data, - ) - .amount.toNumber()}`; + `\n ${'vault'.padEnd(40)} ${vault}`; console.log(`${res}`); } From 20c915f0eeb52ee4f25413568ef1d8bfeff05d0c Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Mon, 15 Aug 2022 20:16:46 +0200 Subject: [PATCH 2/8] return 0 for swap from same source to same target Signed-off-by: microwavedcola1 --- ts/client/src/accounts/mangoAccount.ts | 4 ++++ ts/client/src/debug-scripts/mb-debug-user.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/ts/client/src/accounts/mangoAccount.ts b/ts/client/src/accounts/mangoAccount.ts index 9043db788..cdc1502d2 100644 --- a/ts/client/src/accounts/mangoAccount.ts +++ b/ts/client/src/accounts/mangoAccount.ts @@ -234,6 +234,10 @@ export class MangoAccount { targetTokenName: string, slippageAndFeesFactor: number, ): I80F48 { + if (sourceTokenName === targetTokenName) { + return ZERO_I80F48; + } + return this.accountData.healthCache .getMaxSourceForTokenSwap( group, diff --git a/ts/client/src/debug-scripts/mb-debug-user.ts b/ts/client/src/debug-scripts/mb-debug-user.ts index f38fae551..76353eb5b 100644 --- a/ts/client/src/debug-scripts/mb-debug-user.ts +++ b/ts/client/src/debug-scripts/mb-debug-user.ts @@ -91,6 +91,7 @@ async function debugUser(client, group, mangoAccount) { ); } getMaxSourceForTokenSwapWrapper('SOL', 'BTC'); + getMaxSourceForTokenSwapWrapper('USDC', 'USDC'); } async function main() { From da93f1118e50f77a9a4d0a0fd17298ef002f88ae Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Mon, 15 Aug 2022 20:19:09 +0200 Subject: [PATCH 3/8] defensive code Signed-off-by: microwavedcola1 --- ts/client/src/accounts/healthCache.ts | 8 ++++++++ ts/client/src/accounts/mangoAccount.ts | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ts/client/src/accounts/healthCache.ts b/ts/client/src/accounts/healthCache.ts index 38452c82f..041723fd8 100644 --- a/ts/client/src/accounts/healthCache.ts +++ b/ts/client/src/accounts/healthCache.ts @@ -196,6 +196,14 @@ export class HealthCache { const sourceBank = group.banksMap.get(sourceTokenName); const targetBank = group.banksMap.get(targetTokenName); + if (sourceTokenName === targetTokenName) { + return ZERO_I80F48; + } + + if (!sourceBank.price || sourceBank.price.lte(ZERO_I80F48)) { + return ZERO_I80F48; + } + // The health_ratio is a nonlinear based on swap amount. // For large swap amounts the slope is guaranteed to be negative, but small amounts // can have positive slope (e.g. using source deposits to pay back target borrows). diff --git a/ts/client/src/accounts/mangoAccount.ts b/ts/client/src/accounts/mangoAccount.ts index cdc1502d2..9043db788 100644 --- a/ts/client/src/accounts/mangoAccount.ts +++ b/ts/client/src/accounts/mangoAccount.ts @@ -234,10 +234,6 @@ export class MangoAccount { targetTokenName: string, slippageAndFeesFactor: number, ): I80F48 { - if (sourceTokenName === targetTokenName) { - return ZERO_I80F48; - } - return this.accountData.healthCache .getMaxSourceForTokenSwap( group, From 4ee4ab829fe1f48909b78a79ec0a2d52b2f90002 Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Mon, 15 Aug 2022 20:23:51 +0200 Subject: [PATCH 4/8] more defensive coding Signed-off-by: microwavedcola1 --- ts/client/src/accounts/healthCache.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ts/client/src/accounts/healthCache.ts b/ts/client/src/accounts/healthCache.ts index 041723fd8..766d4b9f6 100644 --- a/ts/client/src/accounts/healthCache.ts +++ b/ts/client/src/accounts/healthCache.ts @@ -204,6 +204,15 @@ export class HealthCache { return ZERO_I80F48; } + if ( + sourceBank.initLiabWeight + .sub(targetBank.initAssetWeight) + .abs() + .lte(ZERO_I80F48) + ) { + return ZERO_I80F48; + } + // The health_ratio is a nonlinear based on swap amount. // For large swap amounts the slope is guaranteed to be negative, but small amounts // can have positive slope (e.g. using source deposits to pay back target borrows). From a9c4f549171395bb8d32659e2c6803e43f1664d5 Mon Sep 17 00:00:00 2001 From: tjs Date: Tue, 16 Aug 2022 00:27:06 -0400 Subject: [PATCH 5/8] use custom sendTransaction in the client --- ts/client/src/client.ts | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ts/client/src/client.ts b/ts/client/src/client.ts index 39785c09a..37de30a42 100644 --- a/ts/client/src/client.ts +++ b/ts/client/src/client.ts @@ -537,14 +537,22 @@ export class MangoClient { accountNumber?: number, name?: string, ): Promise { - return await this.program.methods + const transaction = await this.program.methods .accountCreate(accountNumber ?? 0, 8, 0, 0, 0, name ?? '') .accounts({ group: group.publicKey, owner: (this.program.provider as AnchorProvider).wallet.publicKey, payer: (this.program.provider as AnchorProvider).wallet.publicKey, }) - .rpc({ skipPreflight: true }); + .transaction(); + + return await sendTransaction( + this.program.provider as AnchorProvider, + transaction, + { + postSendTxCallback: this.postSendTxCallback, + }, + ); } public async expandMangoAccount( @@ -572,14 +580,22 @@ export class MangoClient { name?: string, delegate?: PublicKey, ): Promise { - return await this.program.methods + const transaction = await this.program.methods .accountEdit(name ?? null, delegate ?? null) .accounts({ group: group.publicKey, account: mangoAccount.publicKey, owner: (this.program.provider as AnchorProvider).wallet.publicKey, }) - .rpc({ skipPreflight: true }); + .transaction(); + + return await sendTransaction( + this.program.provider as AnchorProvider, + transaction, + { + postSendTxCallback: this.postSendTxCallback, + }, + ); } public async getMangoAccount(mangoAccount: MangoAccount) { @@ -762,7 +778,7 @@ export class MangoClient { [bank], ); - return await this.program.methods + const transaction = await this.program.methods .tokenDeposit(new BN(nativeAmount)) .accounts({ group: group.publicKey, @@ -781,7 +797,15 @@ export class MangoClient { .preInstructions(preInstructions) .postInstructions(postInstructions) .signers(additionalSigners) - .rpc({ skipPreflight: true }); + .transaction(); + + return await sendTransaction( + this.program.provider as AnchorProvider, + transaction, + { + postSendTxCallback: this.postSendTxCallback, + }, + ); } public async tokenWithdraw( From 2483e7cc18ec81eac9819f7fe9de043473c238ab Mon Sep 17 00:00:00 2001 From: tjs Date: Tue, 16 Aug 2022 01:04:14 -0400 Subject: [PATCH 6/8] support passing additional signers to sendTransaction --- ts/client/src/client.ts | 1 + ts/client/src/utils/rpc.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/ts/client/src/client.ts b/ts/client/src/client.ts index 37de30a42..cb34ec47e 100644 --- a/ts/client/src/client.ts +++ b/ts/client/src/client.ts @@ -803,6 +803,7 @@ export class MangoClient { this.program.provider as AnchorProvider, transaction, { + additionalSigners, postSendTxCallback: this.postSendTxCallback, }, ); diff --git a/ts/client/src/utils/rpc.ts b/ts/client/src/utils/rpc.ts index 82f2c8c67..08281278a 100644 --- a/ts/client/src/utils/rpc.ts +++ b/ts/client/src/utils/rpc.ts @@ -12,6 +12,9 @@ export async function sendTransaction( await connection.getLatestBlockhash(opts.preflightCommitment) ).blockhash; transaction.feePayer = payer.publicKey; + if (opts.additionalSigners.length > 0) { + transaction.partialSign(...opts.additionalSigners); + } await payer.signTransaction(transaction); const rawTransaction = transaction.serialize(); From 3c06b718c6faaee861fdbc734399aa72547e8a5c Mon Sep 17 00:00:00 2001 From: tjs Date: Tue, 16 Aug 2022 01:08:25 -0400 Subject: [PATCH 7/8] handle when optional param doesnt exist --- ts/client/src/utils/rpc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/client/src/utils/rpc.ts b/ts/client/src/utils/rpc.ts index 08281278a..fa4b47a72 100644 --- a/ts/client/src/utils/rpc.ts +++ b/ts/client/src/utils/rpc.ts @@ -12,7 +12,7 @@ export async function sendTransaction( await connection.getLatestBlockhash(opts.preflightCommitment) ).blockhash; transaction.feePayer = payer.publicKey; - if (opts.additionalSigners.length > 0) { + if (opts.additionalSigners?.length > 0) { transaction.partialSign(...opts.additionalSigners); } From afc95f4498dd3c5e878666d7c9553d44fefae7d3 Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Tue, 16 Aug 2022 13:49:33 +0200 Subject: [PATCH 8/8] fix Signed-off-by: microwavedcola1 --- ts/client/src/debug-scripts/mb-debug-banks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/client/src/debug-scripts/mb-debug-banks.ts b/ts/client/src/debug-scripts/mb-debug-banks.ts index 275ae337a..68b9f0e62 100644 --- a/ts/client/src/debug-scripts/mb-debug-banks.ts +++ b/ts/client/src/debug-scripts/mb-debug-banks.ts @@ -102,7 +102,7 @@ async function main() { `\n ${'cachedIndexedTotalDeposits'.padEnd(40)} ${( bank as any ).cachedIndexedTotalDeposits.mul(bank.depositIndex)}` + - `\n ${'indexedBorrows'.padEnd(40)} ${bank.indexedBorrows.mul( + `\n ${'borrows'.padEnd(40)} ${bank.indexedBorrows.mul( bank.borrowIndex, )}` + `\n ${'borrows (sum over all mango accounts)'.padEnd(40)} ${