Merge branch 'mc/update-risk' into deploy
This commit is contained in:
commit
888a270cf2
|
@ -1,9 +1,6 @@
|
|||
import {
|
||||
LISTING_PRESETS,
|
||||
LISTING_PRESETS_PYTH,
|
||||
MidPriceImpact,
|
||||
getMidPriceImpacts,
|
||||
getProposedTier,
|
||||
} from '@blockworks-foundation/mango-v4-settings/lib/helpers/listingTools';
|
||||
import { AnchorProvider, Wallet } from '@coral-xyz/anchor';
|
||||
import { BN } from '@project-serum/anchor';
|
||||
|
@ -21,12 +18,14 @@ import {
|
|||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import fs from 'fs';
|
||||
import { OracleProvider } from '../src/accounts/oracle';
|
||||
import { Bank } from '../src/accounts/bank';
|
||||
import { Group } from '../src/accounts/group';
|
||||
import { Builder } from '../src/builder';
|
||||
import { MangoClient } from '../src/client';
|
||||
import { NullTokenEditParams } from '../src/clientIxParamBuilder';
|
||||
import { MANGO_V4_MAIN_GROUP as MANGO_V4_PRIMARY_GROUP } from '../src/constants';
|
||||
import { toUiDecimalsForQuote } from '../src/utils';
|
||||
import { getEquityForMangoAccounts } from '../src/risk';
|
||||
import { buildFetch } from '../src/utils';
|
||||
import {
|
||||
MANGO_DAO_WALLET_GOVERNANCE,
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
|
@ -77,56 +76,40 @@ async function setupVsr(
|
|||
return vsrClient;
|
||||
}
|
||||
|
||||
async function updateTokenParams(): Promise<void> {
|
||||
const [client, wallet] = await Promise.all([buildClient(), setupWallet()]);
|
||||
const vsrClient = await setupVsr(client.connection, wallet);
|
||||
|
||||
const group = await client.getGroup(MANGO_V4_PRIMARY_GROUP);
|
||||
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const midPriceImpacts = getMidPriceImpacts(group.pis);
|
||||
|
||||
Array.from(group.banksMapByTokenIndex.values())
|
||||
.map((banks) => banks[0])
|
||||
.filter(
|
||||
(bank) =>
|
||||
bank.mint.toBase58() == 'So11111111111111111111111111111111111111112' ||
|
||||
bank.name.toLocaleLowerCase().indexOf('usdc') > -1 ||
|
||||
bank.name.toLocaleLowerCase().indexOf('stsol') > -1,
|
||||
async function getTotalLiqorEquity(
|
||||
client: MangoClient,
|
||||
group: Group,
|
||||
mangoAccounts: import('/Users/mc/repos/mango-v4/ts/client/src/accounts/mangoAccount').MangoAccount[],
|
||||
): Promise<number> {
|
||||
const liqors = (
|
||||
await (
|
||||
await (
|
||||
await buildFetch()
|
||||
)(
|
||||
`https://api.mngo.cloud/data/v4/stats/liqors-over_period?over_period=1MONTH`,
|
||||
{
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
},
|
||||
)
|
||||
.forEach(async (bank) => {
|
||||
// Limit borrows to 1/3rd of deposit, rounded to 1000, only update if more than 10% different
|
||||
const depositsInUsd = bank.nativeDeposits().mul(bank.price);
|
||||
let newNetBorrowLimitPerWindowQuote: number | null =
|
||||
depositsInUsd.toNumber() / 3;
|
||||
newNetBorrowLimitPerWindowQuote =
|
||||
Math.round(newNetBorrowLimitPerWindowQuote / 1_000_000_000) *
|
||||
1_000_000_000;
|
||||
newNetBorrowLimitPerWindowQuote =
|
||||
Math.abs(
|
||||
(newNetBorrowLimitPerWindowQuote -
|
||||
bank.netBorrowLimitPerWindowQuote.toNumber()) /
|
||||
bank.netBorrowLimitPerWindowQuote.toNumber(),
|
||||
) > 0.1
|
||||
? newNetBorrowLimitPerWindowQuote
|
||||
: null;
|
||||
|
||||
// Kick in weight scaling as late as possible until liquidation fee remains reasonable
|
||||
// Only update if more than 10% different
|
||||
let newWeightScaleQuote: number | null = null;
|
||||
if (
|
||||
bank.tokenIndex != 0 && // USDC
|
||||
bank.mint.toBase58() != 'So11111111111111111111111111111111111111112' // SOL
|
||||
) {
|
||||
const PRESETS =
|
||||
bank?.oracleProvider === OracleProvider.Pyth
|
||||
? LISTING_PRESETS_PYTH
|
||||
: LISTING_PRESETS;
|
||||
).json()
|
||||
).map((data) => new PublicKey(data['liqor']));
|
||||
const ttlLiqorEquity = (
|
||||
await getEquityForMangoAccounts(client, group, liqors, mangoAccounts)
|
||||
).reduce((partialSum, ae) => partialSum + ae.Equity.val, 0);
|
||||
return ttlLiqorEquity;
|
||||
}
|
||||
|
||||
function getPriceImpactForBank(
|
||||
midPriceImpacts: MidPriceImpact[],
|
||||
bank: Bank,
|
||||
): MidPriceImpact {
|
||||
const tokenToPriceImpact = midPriceImpacts
|
||||
.filter((x) => x.avg_price_impact_percent < 1)
|
||||
.reduce(
|
||||
(acc: { [key: string]: MidPriceImpact }, val: MidPriceImpact) => {
|
||||
.reduce((acc: { [key: string]: MidPriceImpact }, val: MidPriceImpact) => {
|
||||
if (
|
||||
!acc[val.symbol] ||
|
||||
val.target_amount > acc[val.symbol].target_amount
|
||||
|
@ -134,37 +117,77 @@ async function updateTokenParams(): Promise<void> {
|
|||
acc[val.symbol] = val;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
}, {});
|
||||
const priceImpact = tokenToPriceImpact[getApiTokenName(bank.name)];
|
||||
const suggestedTier = getProposedTier(
|
||||
PRESETS,
|
||||
priceImpact?.target_amount,
|
||||
bank.oracleProvider === OracleProvider.Pyth,
|
||||
return priceImpact;
|
||||
}
|
||||
|
||||
async function updateTokenParams(): Promise<void> {
|
||||
const [client, wallet] = await Promise.all([buildClient(), setupWallet()]);
|
||||
const vsrClient = await setupVsr(client.connection, wallet);
|
||||
|
||||
const group = await client.getGroup(MANGO_V4_PRIMARY_GROUP);
|
||||
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
const mangoAccounts = await client.getAllMangoAccounts(group, true);
|
||||
const ttlLiqorEquityUi = await getTotalLiqorEquity(
|
||||
client,
|
||||
group,
|
||||
mangoAccounts,
|
||||
);
|
||||
newWeightScaleQuote =
|
||||
PRESETS[suggestedTier].borrowWeightScaleStartQuote;
|
||||
|
||||
newWeightScaleQuote =
|
||||
bank.depositWeightScaleStartQuote !== newWeightScaleQuote ||
|
||||
bank.borrowWeightScaleStartQuote !== newWeightScaleQuote
|
||||
? newWeightScaleQuote
|
||||
: null;
|
||||
}
|
||||
const midPriceImpacts = getMidPriceImpacts(group.pis);
|
||||
|
||||
if (
|
||||
newNetBorrowLimitPerWindowQuote == null &&
|
||||
newWeightScaleQuote == null
|
||||
) {
|
||||
return;
|
||||
}
|
||||
Array.from(group.banksMapByTokenIndex.values())
|
||||
.map((banks) => banks[0])
|
||||
.filter(
|
||||
(bank) =>
|
||||
// // low low liquidity
|
||||
// bank.name.includes('DUAL') ||
|
||||
// bank.name.includes('MNGO') ||
|
||||
// // low liquidity
|
||||
// bank.name.includes('ALL') ||
|
||||
// bank.name.includes('CROWN') ||
|
||||
// bank.name.includes('GUAC') ||
|
||||
// bank.name.includes('HNT') ||
|
||||
// bank.name.includes('KIN') ||
|
||||
// bank.name.includes('OPOS') ||
|
||||
// bank.name.includes('RLB') ||
|
||||
// bank.name.includes('USDH') ||
|
||||
// better liquidity
|
||||
bank.name.includes('BONK') ||
|
||||
bank.name.includes('bSOL') ||
|
||||
bank.name.includes('CHAI') ||
|
||||
bank.name.includes('DAI') ||
|
||||
bank.name.includes('ETH (Portal)') ||
|
||||
bank.name.includes('JitoSOL') ||
|
||||
bank.name.includes('LDO') ||
|
||||
bank.name.includes('MSOL') ||
|
||||
bank.name.includes('ORCA') ||
|
||||
bank.name.includes('RAY') ||
|
||||
bank.name.includes('SOL') ||
|
||||
bank.name.includes('stSOL') ||
|
||||
bank.name.includes('TBTC') ||
|
||||
bank.name.includes('USDC') ||
|
||||
bank.name.includes('wBTC (Portal)') ||
|
||||
bank.name.includes('USDT'),
|
||||
)
|
||||
.forEach(async (bank) => {
|
||||
const priceImpact = getPriceImpactForBank(midPriceImpacts, bank);
|
||||
|
||||
const params = Builder(NullTokenEditParams)
|
||||
.netBorrowLimitPerWindowQuote(newNetBorrowLimitPerWindowQuote)
|
||||
.borrowWeightScaleStartQuote(newWeightScaleQuote)
|
||||
.depositWeightScaleStartQuote(newWeightScaleQuote)
|
||||
.build();
|
||||
const scaleStartQuoteUi = Math.min(
|
||||
50 * ttlLiqorEquityUi,
|
||||
4 * priceImpact.target_amount,
|
||||
);
|
||||
|
||||
const newNetDepositsUi = Math.max(
|
||||
10_000,
|
||||
Math.min(bank.uiDeposits(), 300_000) / 3 +
|
||||
Math.max(0, bank.uiDeposits() - 300_000) / 5,
|
||||
);
|
||||
|
||||
const params = Builder(NullTokenEditParams).build();
|
||||
|
||||
const ix = await client.program.methods
|
||||
.tokenEdit(
|
||||
|
@ -224,21 +247,6 @@ async function updateTokenParams(): Promise<void> {
|
|||
throw simulated.value.logs;
|
||||
}
|
||||
|
||||
console.log(`Bank ${bank.name}`);
|
||||
console.log(
|
||||
`- netBorrowLimitPerWindowQuote UI old ${toUiDecimalsForQuote(
|
||||
bank.netBorrowLimitPerWindowQuote.toNumber(),
|
||||
).toLocaleString()} new ${toUiDecimalsForQuote(
|
||||
newNetBorrowLimitPerWindowQuote!,
|
||||
).toLocaleString()}`,
|
||||
);
|
||||
console.log(
|
||||
`- WeightScaleQuote UI old ${toUiDecimalsForQuote(
|
||||
bank.depositWeightScaleStartQuote,
|
||||
).toLocaleString()} new ${toUiDecimalsForQuote(
|
||||
newWeightScaleQuote!,
|
||||
).toLocaleString()}`,
|
||||
);
|
||||
instructions.push(ix);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue