Liquidation test: Fix scripts

This commit is contained in:
Christian Kamm 2022-09-01 11:47:37 +02:00
parent 511db72f8e
commit 22dc07df1d
5 changed files with 87 additions and 59 deletions

View File

@ -13,7 +13,7 @@ const GROUP_NUM = process.env.GROUP_NUM;
async function main() { async function main() {
const options = AnchorProvider.defaultOptions(); const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.MB_CLUSTER_URL, options); const connection = new Connection(process.env.MB_CLUSTER_URL!, options);
const admin = Keypair.fromSecretKey( const admin = Keypair.fromSecretKey(
Buffer.from( Buffer.from(
@ -27,6 +27,8 @@ async function main() {
adminProvider, adminProvider,
'mainnet-beta', 'mainnet-beta',
MANGO_V4_ID['mainnet-beta'], MANGO_V4_ID['mainnet-beta'],
{},
'get-program-accounts',
); );
const groups = await (async () => { const groups = await (async () => {
@ -53,16 +55,19 @@ async function main() {
} }
// close all banks // close all banks
for (const bank of group.banksMap.values()) { for (const banks of group.banksMapByMint.values()) {
sig = await client.tokenDeregister(group, bank.name); sig = await client.tokenDeregister(group, banks[0].mint);
console.log( console.log(
`Removed token ${bank.name}, sig https://explorer.solana.com/tx/${sig}`, `Removed token ${banks[0].name}, sig https://explorer.solana.com/tx/${sig}`,
); );
} }
// deregister all serum markets // deregister all serum markets
for (const market of group.serum3MarketsMap.values()) { for (const market of group.serum3MarketsMapByExternal.values()) {
sig = await client.serum3deregisterMarket(group, market.name); sig = await client.serum3deregisterMarket(
group,
market.serumMarketExternal,
);
console.log( console.log(
`Deregistered serum market ${market.name}, sig https://explorer.solana.com/tx/${sig}`, `Deregistered serum market ${market.name}, sig https://explorer.solana.com/tx/${sig}`,
); );

View File

@ -10,7 +10,7 @@ import { MANGO_V4_ID } from '../constants';
// //
// default to group 1, to not conflict with the normal group // default to group 1, to not conflict with the normal group
const GROUP_NUM = Number(process.env.GROUP_NUM || 1); const GROUP_NUM = Number(process.env.GROUP_NUM || 200);
const MAINNET_MINTS = new Map([ const MAINNET_MINTS = new Map([
['USDC', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'], ['USDC', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'],
@ -24,9 +24,16 @@ const STUB_PRICES = new Map([
['SOL', 0.04], // sol has 9 decimals, equivalent to $40 per SOL ['SOL', 0.04], // sol has 9 decimals, equivalent to $40 per SOL
]); ]);
// External markets are matched with those in https://github.com/blockworks-foundation/mango-client-v3/blob/main/src/ids.json
// and verified to have best liquidity for pair on https://openserum.io/
const MAINNET_SERUM3_MARKETS = new Map([
['BTC/USDC', 'A8YFbxQYFVqKZaoYJLLUVcQiWP7G2MeEgW5wsAQgMvFw'],
['SOL/USDC', '9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'],
]);
async function main() { async function main() {
const options = AnchorProvider.defaultOptions(); const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, options); const connection = new Connection(process.env.CLUSTER_URL!, options);
const admin = Keypair.fromSecretKey( const admin = Keypair.fromSecretKey(
Buffer.from( Buffer.from(
@ -42,6 +49,8 @@ async function main() {
adminProvider, adminProvider,
'mainnet-beta', 'mainnet-beta',
MANGO_V4_ID['mainnet-beta'], MANGO_V4_ID['mainnet-beta'],
{},
'get-program-accounts',
); );
// group // group
@ -61,7 +70,7 @@ async function main() {
console.log(`Creating stub oracle for ${name}...`); console.log(`Creating stub oracle for ${name}...`);
const mintPk = new PublicKey(mint); const mintPk = new PublicKey(mint);
try { try {
const price = STUB_PRICES.get(name); const price = STUB_PRICES.get(name)!;
await client.stubOracleCreate(group, mintPk, price); await client.stubOracleCreate(group, mintPk, price);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
@ -71,37 +80,6 @@ async function main() {
oracles.set(name, oracle.publicKey); oracles.set(name, oracle.publicKey);
} }
// register token 1
console.log(`Registering BTC...`);
const btcMainnetMint = new PublicKey(MAINNET_MINTS.get('BTC')!);
const btcMainnetOracle = oracles.get('BTC');
try {
await client.tokenRegister(
group,
btcMainnetMint,
btcMainnetOracle,
0.1,
1,
'BTC',
0.01,
0.4,
0.07,
0.7,
0.88,
1.5,
0.0,
0.0001,
0.9,
0.8,
1.1,
1.2,
0.05,
);
await group.reloadAll(client);
} catch (error) {
console.log(error);
}
// register token 0 // register token 0
console.log(`Registering USDC...`); console.log(`Registering USDC...`);
const usdcMainnetMint = new PublicKey(MAINNET_MINTS.get('USDC')!); const usdcMainnetMint = new PublicKey(MAINNET_MINTS.get('USDC')!);
@ -133,6 +111,37 @@ async function main() {
console.log(error); console.log(error);
} }
// register token 1
console.log(`Registering BTC...`);
const btcMainnetMint = new PublicKey(MAINNET_MINTS.get('BTC')!);
const btcMainnetOracle = oracles.get('BTC');
try {
await client.tokenRegister(
group,
btcMainnetMint,
btcMainnetOracle,
0.1,
1,
'BTC',
0.01,
0.4,
0.07,
0.7,
0.88,
1.5,
0.0,
0.0001,
0.9,
0.8,
1.1,
1.2,
0.05,
);
await group.reloadAll(client);
} catch (error) {
console.log(error);
}
// register token 2 // register token 2
console.log(`Registering SOL...`); console.log(`Registering SOL...`);
const solMainnetMint = new PublicKey(MAINNET_MINTS.get('SOL')!); const solMainnetMint = new PublicKey(MAINNET_MINTS.get('SOL')!);
@ -165,7 +174,7 @@ async function main() {
} }
// log tokens/banks // log tokens/banks
for (const bank of await group.banksMap.values()) { for (const bank of await group.banksMapByMint.values()) {
console.log(`${bank.toString()}`); console.log(`${bank.toString()}`);
} }

View File

@ -8,12 +8,12 @@ import { MANGO_V4_ID } from '../constants';
// This script deposits some tokens, so other liquidation scripts can borrow. // This script deposits some tokens, so other liquidation scripts can borrow.
// //
const GROUP_NUM = Number(process.env.GROUP_NUM || 1); const GROUP_NUM = Number(process.env.GROUP_NUM || 200);
const ACCOUNT_NUM = Number(process.env.ACCOUNT_NUM || 0); const ACCOUNT_NUM = Number(process.env.ACCOUNT_NUM || 0);
async function main() { async function main() {
const options = AnchorProvider.defaultOptions(); const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, options); const connection = new Connection(process.env.CLUSTER_URL!, options);
const admin = Keypair.fromSecretKey( const admin = Keypair.fromSecretKey(
Buffer.from( Buffer.from(
@ -28,6 +28,8 @@ async function main() {
userProvider, userProvider,
'mainnet-beta', 'mainnet-beta',
MANGO_V4_ID['mainnet-beta'], MANGO_V4_ID['mainnet-beta'],
{},
'get-program-accounts',
); );
console.log(`User ${userWallet.publicKey.toBase58()}`); console.log(`User ${userWallet.publicKey.toBase58()}`);
@ -37,26 +39,31 @@ async function main() {
// create + fetch account // create + fetch account
console.log(`Creating mangoaccount...`); console.log(`Creating mangoaccount...`);
const mangoAccount = await client.getOrCreateMangoAccount( const mangoAccount = (await client.getOrCreateMangoAccount(
group, group,
admin.publicKey, admin.publicKey,
ACCOUNT_NUM, ACCOUNT_NUM,
); 'LIQTEST, FUNDING',
))!;
console.log(`...created/found mangoAccount ${mangoAccount.publicKey}`); console.log(`...created/found mangoAccount ${mangoAccount.publicKey}`);
console.log(mangoAccount.toString()); console.log(mangoAccount.toString());
const usdcMint = group.banksMapByName.get('USDC')![0].mint;
const btcMint = group.banksMapByName.get('BTC')![0].mint;
const solMint = group.banksMapByName.get('SOL')![0].mint;
// deposit // deposit
try { try {
console.log(`...depositing 10 USDC`); console.log(`...depositing 10 USDC`);
await client.tokenDeposit(group, mangoAccount, 'USDC', 10); await client.tokenDeposit(group, mangoAccount, usdcMint, 10);
await mangoAccount.reload(client, group); await mangoAccount.reload(client, group);
console.log(`...depositing 0.0004 BTC`); console.log(`...depositing 0.0004 BTC`);
await client.tokenDeposit(group, mangoAccount, 'BTC', 0.0004); await client.tokenDeposit(group, mangoAccount, btcMint, 0.0004);
await mangoAccount.reload(client, group); await mangoAccount.reload(client, group);
console.log(`...depositing 0.25 SOL`); console.log(`...depositing 0.25 SOL`);
await client.tokenDeposit(group, mangoAccount, 'SOL', 0.25); await client.tokenDeposit(group, mangoAccount, solMint, 0.25);
await mangoAccount.reload(client, group); await mangoAccount.reload(client, group);
} catch (error) { } catch (error) {
console.log(error); console.log(error);

View File

@ -8,7 +8,7 @@ import { MANGO_V4_ID } from '../constants';
// This script creates liquidation candidates // This script creates liquidation candidates
// //
const GROUP_NUM = Number(process.env.GROUP_NUM || 1); const GROUP_NUM = Number(process.env.GROUP_NUM || 200);
// native prices // native prices
const PRICES = { const PRICES = {
@ -33,7 +33,7 @@ const SCENARIOS: [string, string, number, string, number][] = [
async function main() { async function main() {
const options = AnchorProvider.defaultOptions(); const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, options); const connection = new Connection(process.env.CLUSTER_URL!, options);
const admin = Keypair.fromSecretKey( const admin = Keypair.fromSecretKey(
Buffer.from( Buffer.from(
@ -48,6 +48,8 @@ async function main() {
userProvider, userProvider,
'mainnet-beta', 'mainnet-beta',
MANGO_V4_ID['mainnet-beta'], MANGO_V4_ID['mainnet-beta'],
{},
'get-program-accounts',
); );
console.log(`User ${userWallet.publicKey.toBase58()}`); console.log(`User ${userWallet.publicKey.toBase58()}`);
@ -66,34 +68,37 @@ async function main() {
// create account // create account
console.log(`Creating mangoaccount...`); console.log(`Creating mangoaccount...`);
let mangoAccount = await client.getOrCreateMangoAccount( let mangoAccount = (await client.getOrCreateMangoAccount(
group, group,
admin.publicKey, admin.publicKey,
maxAccountNum + 1, maxAccountNum + 1,
); ))!;
maxAccountNum = maxAccountNum + 1; maxAccountNum = maxAccountNum + 1;
console.log( console.log(
`...created mangoAccount ${mangoAccount.publicKey} for ${name}`, `...created mangoAccount ${mangoAccount.publicKey} for ${name}`,
); );
const assetMint = new PublicKey(MAINNET_MINTS.get(assetName)!);
const liabMint = new PublicKey(MAINNET_MINTS.get(liabName)!);
await client.tokenDepositNative( await client.tokenDepositNative(
group, group,
mangoAccount, mangoAccount,
assetName, assetMint,
assetAmount, assetAmount,
); );
await mangoAccount.reload(client, group); await mangoAccount.reload(client, group);
if (liabAmount > 0) { if (liabAmount > 0) {
// temporarily drop the borrowed token value, so the borrow goes through // temporarily drop the borrowed token value, so the borrow goes through
const oracle = group.banksMap.get(liabName).oracle; const oracle = group.banksMapByName.get(liabName)![0].oracle;
try { try {
await client.stubOracleSet(group, oracle, PRICES[liabName] / 2); await client.stubOracleSet(group, oracle, PRICES[liabName] / 2);
await client.tokenWithdrawNative( await client.tokenWithdrawNative(
group, group,
mangoAccount, mangoAccount,
liabName, liabMint,
liabAmount, liabAmount,
true, true,
); );

View File

@ -9,7 +9,7 @@ import { MANGO_V4_ID } from '../constants';
// by MANGO_MAINNET_PAYER_KEYPAIR in the group. // by MANGO_MAINNET_PAYER_KEYPAIR in the group.
// //
const GROUP_NUM = Number(process.env.GROUP_NUM || 2); const GROUP_NUM = Number(process.env.GROUP_NUM || 200);
const CLUSTER_URL = const CLUSTER_URL =
process.env.CLUSTER_URL || process.env.CLUSTER_URL ||
'https://mango.rpcpool.com/946ef7337da3f5b8d3e4a34e7f88'; 'https://mango.rpcpool.com/946ef7337da3f5b8d3e4a34e7f88';
@ -18,7 +18,7 @@ const MANGO_MAINNET_PAYER_KEYPAIR =
async function main() { async function main() {
const options = AnchorProvider.defaultOptions(); const options = AnchorProvider.defaultOptions();
const connection = new Connection(CLUSTER_URL, options); const connection = new Connection(CLUSTER_URL!, options);
const admin = Keypair.fromSecretKey( const admin = Keypair.fromSecretKey(
Buffer.from( Buffer.from(
@ -31,6 +31,8 @@ async function main() {
userProvider, userProvider,
'mainnet-beta', 'mainnet-beta',
MANGO_V4_ID['mainnet-beta'], MANGO_V4_ID['mainnet-beta'],
{},
'get-program-accounts'
); );
console.log(`User ${userWallet.publicKey.toBase58()}`); console.log(`User ${userWallet.publicKey.toBase58()}`);
@ -50,7 +52,7 @@ async function main() {
// first, settle all borrows // first, settle all borrows
for (let token of account.tokensActive()) { for (let token of account.tokensActive()) {
const bank = group.getFirstBankByTokenIndex(token.tokenIndex); const bank = group.getFirstBankByTokenIndex(token.tokenIndex);
const amount = token.native(bank).toNumber(); const amount = token.balance(bank).toNumber();
if (amount < 0) { if (amount < 0) {
try { try {
await client.tokenDepositNative( await client.tokenDepositNative(
@ -76,7 +78,7 @@ async function main() {
// withdraw all funds // withdraw all funds
for (let token of account.tokensActive()) { for (let token of account.tokensActive()) {
const bank = group.getFirstBankByTokenIndex(token.tokenIndex); const bank = group.getFirstBankByTokenIndex(token.tokenIndex);
const amount = token.native(bank).toNumber(); const amount = token.balance(bank).toNumber();
if (amount > 0) { if (amount > 0) {
try { try {
const allowBorrow = false; const allowBorrow = false;