Merge branch 'main' into dev

This commit is contained in:
tjs 2023-01-02 15:36:08 -05:00
commit 92f92cb967
4 changed files with 139 additions and 173 deletions

View File

@ -217,7 +217,8 @@ export class HealthCache {
return health; return health;
} }
public assets(healthType: HealthType): I80F48 { // An undefined HealthType will use an asset and liab weight of 1
public assets(healthType?: HealthType): I80F48 {
const assets = ZERO_I80F48(); const assets = ZERO_I80F48();
for (const tokenInfo of this.tokenInfos) { for (const tokenInfo of this.tokenInfos) {
const contrib = tokenInfo.healthContribution(healthType); const contrib = tokenInfo.healthContribution(healthType);
@ -246,7 +247,8 @@ export class HealthCache {
return assets; return assets;
} }
public liabs(healthType: HealthType): I80F48 { // An undefined HealthType will use an asset and liab weight of 1
public liabs(healthType?: HealthType): I80F48 {
const liabs = ZERO_I80F48(); const liabs = ZERO_I80F48();
for (const tokenInfo of this.tokenInfos) { for (const tokenInfo of this.tokenInfos) {
const contrib = tokenInfo.healthContribution(healthType); const contrib = tokenInfo.healthContribution(healthType);
@ -1155,15 +1157,15 @@ export class HealthCache {
export class Prices { export class Prices {
constructor(public oracle: I80F48, public stable: I80F48) {} constructor(public oracle: I80F48, public stable: I80F48) {}
public liab(healthType: HealthType): I80F48 { public liab(healthType: HealthType | undefined): I80F48 {
if (healthType == HealthType.maint) { if (healthType === HealthType.maint || healthType === undefined) {
return this.oracle; return this.oracle;
} }
return this.oracle.max(this.stable); return this.oracle.max(this.stable);
} }
public asset(healthType: HealthType): I80F48 { public asset(healthType: HealthType | undefined): I80F48 {
if (healthType == HealthType.maint) { if (healthType === HealthType.maint || healthType === undefined) {
return this.oracle; return this.oracle;
} }
return this.oracle.min(this.stable); return this.oracle.min(this.stable);
@ -1223,8 +1225,11 @@ export class TokenInfo {
: this.maintLiabWeight; : this.maintLiabWeight;
} }
healthContribution(healthType: HealthType): I80F48 { healthContribution(healthType?: HealthType): I80F48 {
let weight, price; let weight, price;
if (healthType === undefined) {
return this.balanceNative.mul(this.prices.oracle);
}
if (this.balanceNative.isNeg()) { if (this.balanceNative.isNeg()) {
weight = this.liabWeight(healthType); weight = this.liabWeight(healthType);
price = this.prices.liab(healthType); price = this.prices.liab(healthType);
@ -1317,8 +1322,9 @@ export class Serum3Info {
); );
} }
// An undefined HealthType will use an asset and liab weight of 1
healthContribution( healthContribution(
healthType: HealthType, healthType: HealthType | undefined,
tokenInfos: TokenInfo[], tokenInfos: TokenInfo[],
tokenMaxReserved: I80F48[], tokenMaxReserved: I80F48[],
marketReserved: Serum3Reserved, marketReserved: Serum3Reserved,
@ -1359,6 +1365,13 @@ export class Serum3Info {
assetPart = maxBalance; assetPart = maxBalance;
liabPart = marketReserved.sub(maxBalance); liabPart = marketReserved.sub(maxBalance);
} }
if (healthType === undefined) {
return assetPart
.mul(tokenInfo.prices.oracle)
.add(liabPart.mul(tokenInfo.prices.oracle));
}
const assetWeight = tokenInfo.assetWeight(healthType); const assetWeight = tokenInfo.assetWeight(healthType);
const liabWeight = tokenInfo.liabWeight(healthType); const liabWeight = tokenInfo.liabWeight(healthType);
const assetPrice = tokenInfo.prices.asset(healthType); const assetPrice = tokenInfo.prices.asset(healthType);
@ -1478,13 +1491,13 @@ export class PerpInfo {
); );
} }
healthContribution(healthType: HealthType): I80F48 { healthContribution(healthType: HealthType | undefined): I80F48 {
return this.trustedMarket return this.trustedMarket
? this.uncappedHealthContribution(healthType) ? this.uncappedHealthContribution(healthType)
: this.uncappedHealthContribution(healthType).min(ZERO_I80F48()); : this.uncappedHealthContribution(healthType).min(ZERO_I80F48());
} }
uncappedHealthContribution(healthType: HealthType): I80F48 { uncappedHealthContribution(healthType: HealthType | undefined): I80F48 {
function orderExecutionCase( function orderExecutionCase(
pi: PerpInfo, pi: PerpInfo,
ordersBaseLots: BN, ordersBaseLots: BN,

View File

@ -355,7 +355,7 @@ export class MangoAccount {
* Sum of all positive assets. * Sum of all positive assets.
* @returns assets, in native quote * @returns assets, in native quote
*/ */
public getAssetsValue(group: Group, healthType: HealthType): I80F48 { public getAssetsValue(group: Group, healthType?: HealthType): I80F48 {
const hc = HealthCache.fromMangoAccount(group, this); const hc = HealthCache.fromMangoAccount(group, this);
return hc.assets(healthType); return hc.assets(healthType);
} }
@ -364,7 +364,7 @@ export class MangoAccount {
* Sum of all negative assets. * Sum of all negative assets.
* @returns liabs, in native quote * @returns liabs, in native quote
*/ */
public getLiabsValue(group: Group, healthType: HealthType): I80F48 { public getLiabsValue(group: Group, healthType?: HealthType): I80F48 {
const hc = HealthCache.fromMangoAccount(group, this); const hc = HealthCache.fromMangoAccount(group, this);
return hc.liabs(healthType); return hc.liabs(healthType);
} }

View File

@ -88,10 +88,25 @@ export class MangoClient {
Error.stackTraceLimit = 1000; Error.stackTraceLimit = 1000;
} }
/// public /// Transactions
private async sendAndConfirmTransaction(
ixs: TransactionInstruction[],
alts: AddressLookupTableAccount[],
opts: any = {},
): Promise<string> {
return await sendTransaction(
this.program.provider as AnchorProvider,
ixs,
alts,
{
postSendTxCallback: this.postSendTxCallback,
prioritizationFee: this.prioritizationFee,
...opts,
},
);
}
// Group // Group
public async groupCreate( public async groupCreate(
groupNum: number, groupNum: number,
testing: boolean, testing: boolean,
@ -390,13 +405,9 @@ export class MangoClient {
) )
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[...preInstructions, ix], [...preInstructions, ix],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -570,13 +581,9 @@ export class MangoClient {
}) })
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
[], group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -640,13 +647,9 @@ export class MangoClient {
}) })
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
[], group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -788,13 +791,9 @@ export class MangoClient {
}) })
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
[], group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -888,14 +887,10 @@ export class MangoClient {
) )
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[...preInstructions, ix, ...postInstructions], [...preInstructions, ix, ...postInstructions],
group.addressLookupTablesList, group.addressLookupTablesList,
{ { additionalSigners },
additionalSigners,
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -978,13 +973,9 @@ export class MangoClient {
) )
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[...preInstructions, ix, ...postInstructions], [...preInstructions, ix, ...postInstructions],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1263,13 +1254,15 @@ export class MangoClient {
limit, limit,
); );
return await sendTransaction( const ix2 = await this.serum3SettleFundsIx(
this.program.provider as AnchorProvider, group,
[ix], mangoAccount,
externalMarketPk,
);
return await this.sendAndConfirmTransaction(
[ix, ix2],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1304,13 +1297,9 @@ export class MangoClient {
}) })
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1371,13 +1360,9 @@ export class MangoClient {
externalMarketPk, externalMarketPk,
); );
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1433,13 +1418,9 @@ export class MangoClient {
this.serum3SettleFundsIx(group, mangoAccount, externalMarketPk), this.serum3SettleFundsIx(group, mangoAccount, externalMarketPk),
]); ]);
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
ixes, ixes,
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1715,28 +1696,24 @@ export class MangoClient {
expiryTimestamp?: number, expiryTimestamp?: number,
limit?: number, limit?: number,
): Promise<TransactionSignature> { ): Promise<TransactionSignature> {
return await sendTransaction( const ix = await this.perpPlaceOrderIx(
this.program.provider as AnchorProvider, group,
[ mangoAccount,
await this.perpPlaceOrderIx( perpMarketIndex,
group, side,
mangoAccount, price,
perpMarketIndex, quantity,
side, maxQuoteQuantity,
price, clientOrderId,
quantity, orderType,
maxQuoteQuantity, reduceOnly,
clientOrderId, expiryTimestamp,
orderType, limit,
reduceOnly, );
expiryTimestamp,
limit, return await this.sendAndConfirmTransaction(
), [ix],
],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1812,29 +1789,25 @@ export class MangoClient {
expiryTimestamp?: number, expiryTimestamp?: number,
limit?: number, limit?: number,
): Promise<TransactionSignature> { ): Promise<TransactionSignature> {
return await sendTransaction( const ix = await this.perpPlaceOrderPeggedIx(
this.program.provider as AnchorProvider, group,
[ mangoAccount,
await this.perpPlaceOrderPeggedIx( perpMarketIndex,
group, side,
mangoAccount, priceOffset,
perpMarketIndex, pegLimit,
side, quantity,
priceOffset, maxQuoteQuantity,
pegLimit, clientOrderId,
quantity, orderType,
maxQuoteQuantity, reduceOnly,
clientOrderId, expiryTimestamp,
orderType, limit,
reduceOnly, );
expiryTimestamp,
limit, return await this.sendAndConfirmTransaction(
), [ix],
],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1924,20 +1897,16 @@ export class MangoClient {
perpMarketIndex: PerpMarketIndex, perpMarketIndex: PerpMarketIndex,
orderId: BN, orderId: BN,
): Promise<TransactionSignature> { ): Promise<TransactionSignature> {
return await sendTransaction( const ix = await this.perpCancelOrderIx(
this.program.provider as AnchorProvider, group,
[ mangoAccount,
await this.perpCancelOrderIx( perpMarketIndex,
group, orderId,
mangoAccount, );
perpMarketIndex,
orderId, return await this.sendAndConfirmTransaction(
), [ix],
],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -1947,20 +1916,16 @@ export class MangoClient {
perpMarketIndex: PerpMarketIndex, perpMarketIndex: PerpMarketIndex,
limit: number, limit: number,
): Promise<TransactionSignature> { ): Promise<TransactionSignature> {
return await sendTransaction( const ix = await this.perpCancelAllOrdersIx(
this.program.provider as AnchorProvider, group,
[ mangoAccount,
await this.perpCancelAllOrdersIx( perpMarketIndex,
group, limit,
mangoAccount, );
perpMarketIndex,
limit, return await this.sendAndConfirmTransaction(
), [ix],
],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -2023,13 +1988,9 @@ export class MangoClient {
) )
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -2067,13 +2028,9 @@ export class MangoClient {
) )
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -2292,8 +2249,7 @@ export class MangoClient {
]) ])
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ [
...preInstructions, ...preInstructions,
flashLoanBeginIx, flashLoanBeginIx,
@ -2301,9 +2257,6 @@ export class MangoClient {
flashLoanEndIx, flashLoanEndIx,
], ],
[...group.addressLookupTablesList, ...userDefinedAlts], [...group.addressLookupTablesList, ...userDefinedAlts],
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -2379,13 +2332,9 @@ export class MangoClient {
.remainingAccounts(parsedHealthAccounts) .remainingAccounts(parsedHealthAccounts)
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -2403,13 +2352,9 @@ export class MangoClient {
}) })
.instruction(); .instruction();
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
[ix], [ix],
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
@ -2727,13 +2672,9 @@ export class MangoClient {
]); ]);
transactionInstructions.push(cancelOrderIx, placeOrderIx); transactionInstructions.push(cancelOrderIx, placeOrderIx);
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
transactionInstructions, transactionInstructions,
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
public async modifySerum3Order( public async modifySerum3Order(
@ -2774,13 +2715,9 @@ export class MangoClient {
]); ]);
transactionInstructions.push(cancelOrderIx, settleIx, placeOrderIx); transactionInstructions.push(cancelOrderIx, settleIx, placeOrderIx);
return await sendTransaction( return await this.sendAndConfirmTransaction(
this.program.provider as AnchorProvider,
transactionInstructions, transactionInstructions,
group.addressLookupTablesList, group.addressLookupTablesList,
{
postSendTxCallback: this.postSendTxCallback,
},
); );
} }
} }

View File

@ -2,6 +2,7 @@ import { AnchorProvider } from '@project-serum/anchor';
import NodeWallet from '@project-serum/anchor/dist/cjs/nodewallet'; import NodeWallet from '@project-serum/anchor/dist/cjs/nodewallet';
import { import {
AddressLookupTableAccount, AddressLookupTableAccount,
ComputeBudgetProgram,
MessageV0, MessageV0,
Signer, Signer,
TransactionInstruction, TransactionInstruction,
@ -21,6 +22,10 @@ export async function sendTransaction(
const payer = (provider as AnchorProvider).wallet; const payer = (provider as AnchorProvider).wallet;
if (opts.prioritizationFee) {
ixs = [createComputeBudgetIx(2, 200_000 * ixs.length + 1), ...ixs];
}
const message = MessageV0.compile({ const message = MessageV0.compile({
payerKey: (provider as AnchorProvider).wallet.publicKey, payerKey: (provider as AnchorProvider).wallet.publicKey,
instructions: ixs, instructions: ixs,
@ -94,6 +99,17 @@ export async function sendTransaction(
return signature; return signature;
} }
export const createComputeBudgetIx = (
prioritizationFee: number,
units: number,
): TransactionInstruction => {
const computeBudgetIx = ComputeBudgetProgram.requestUnits({
additionalFee: prioritizationFee,
units,
});
return computeBudgetIx;
};
class MangoError extends Error { class MangoError extends Error {
message: string; message: string;
txid: string; txid: string;