Compare commits
5 Commits
1a957787e2
...
d4b6db7649
Author | SHA1 | Date |
---|---|---|
Riordan Panayides | d4b6db7649 | |
Riordan Panayides | 2a189ac952 | |
Riordan Panayides | 68d45dc7ab | |
Christian Kamm | 84c07c81e8 | |
Ricardo J. Mendez | 1e1d7c527e |
55
README.md
55
README.md
|
@ -1,15 +1,54 @@
|
||||||
# liquidator-v3
|
# liquidator-v3
|
||||||
A script for liquidating undercollateralized account on Mango Markets
|
A script for liquidating undercollateralized account on Mango Markets.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
To run the liquidator you will need:
|
To run the liquidator you will need:
|
||||||
* A Solana account with some SOL deposited to cover transaction fees
|
* A Solana account with some SOL deposited to cover transaction fees
|
||||||
* A Mango Account with some collateral deposited
|
* A Mango Account with some collateral deposited
|
||||||
* Your wallet keypair saved as a JSON file
|
* Your wallet keypair saved as a JSON file
|
||||||
* `node` and `yarn`
|
* `node` (v14+) and `yarn`
|
||||||
* A clone of this repository
|
* A clone of this repository
|
||||||
* Dependencies installed with `yarn install`
|
* Dependencies installed with `yarn install`
|
||||||
|
|
||||||
|
## Rebalancing
|
||||||
|
The liquidator will attempt to close all perp positions, and balance the tokens in the liqor account after each liquidation. By default it will sell all token assets into USDC. You can choose to maintain a certain amount of each asset through this process by editing the value in the `TARGETS` environment variable at the position of the asset. You can find the order of the assets in the 'oracles' property of the group in [ids.json](https://github.com/blockworks-foundation/mango-client-v3/blob/main/src/ids.json#L81) The program will attempt to make buy/sell orders during balancing to maintain this level.
|
||||||
|
|
||||||
|
## Advanced Orders Triggering
|
||||||
|
The liquidator triggers advanced orders for users when their trigger condition is met. Upon successfully triggering the order, the liquidator wallet will receive 100x the transaction fee as a reward.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
```
|
||||||
|
yarn liquidator
|
||||||
|
```
|
||||||
|
|
||||||
|
The liquidator can be run in two different modes:
|
||||||
|
|
||||||
|
### Mode 1: Scan for liquidatable accounts directly
|
||||||
|
|
||||||
|
The liquidator will connect to an RPC node websocket feed itself and request
|
||||||
|
snapshots occasionally. This is simpler to get started with, as no separate
|
||||||
|
service is needed to watch for potentially liquidatable accounts, but scanning
|
||||||
|
for accounts can be slow.
|
||||||
|
|
||||||
|
To use this mode, leave `LIQUIDATABLE_FEED_WEBSOCKET_ADDRESS` unset.
|
||||||
|
|
||||||
|
Only this mode allows advanced order triggering.
|
||||||
|
|
||||||
|
### Mode 2: Use a separate service to find liquidatable accounts
|
||||||
|
|
||||||
|
In this mode the https://github.com/blockworks-foundation/liquidatable-accounts-feed
|
||||||
|
service provides information about potentially liquidatable accounts to the liquidator.
|
||||||
|
|
||||||
|
The external service is much faster at scanning for newly liquidatable accounts
|
||||||
|
when the price cache is updated than Mode 1.
|
||||||
|
|
||||||
|
To use it, set up the liquidatable-accounts-feed service (probably on the same
|
||||||
|
machine) and then set the liquidator's `LIQUIDATABLE_FEED_WEBSOCKET_ADDRESS` to
|
||||||
|
the other service's `websocket_server_bind_address`.
|
||||||
|
|
||||||
|
This mode never triggers advanced orders.
|
||||||
|
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| -------- | ------- | ----------- |
|
| -------- | ------- | ----------- |
|
||||||
|
@ -25,6 +64,8 @@ To run the liquidator you will need:
|
||||||
| `LIQOR_PK` | N/A | Liqor Mango Account Public Key, by default uses the largest value account owned by the keypair |
|
| `LIQOR_PK` | N/A | Liqor Mango Account Public Key, by default uses the largest value account owned by the keypair |
|
||||||
| `WEBHOOK_URL` | N/A | Discord webhook URL to post liquidation events and errors to |
|
| `WEBHOOK_URL` | N/A | Discord webhook URL to post liquidation events and errors to |
|
||||||
| `LIAB_LIMIT` | `0.9` | Percentage of your available margin to use when taking on liabilities |
|
| `LIAB_LIMIT` | `0.9` | Percentage of your available margin to use when taking on liabilities |
|
||||||
|
| `MIN_EQUITY` | `0` | Minimum account equity required to liquidate |
|
||||||
|
| `LIQUIDATABLE_FEED_WEBSOCKET_ADDRESS` | N/A | Websocket URL of the liquidatable-accounts-feed service, see above |
|
||||||
|
|
||||||
You can add these variables to a `.env` file in the project root to load automatically on liquidator startup. For example:
|
You can add these variables to a `.env` file in the project root to load automatically on liquidator startup. For example:
|
||||||
```bash
|
```bash
|
||||||
|
@ -32,13 +73,3 @@ ENDPOINT_URL=https://solana-api.projectserum.com
|
||||||
KEYPAIR=${HOME}/.config/solana/my-keypair.json
|
KEYPAIR=${HOME}/.config/solana/my-keypair.json
|
||||||
TARGETS=500 0.1 0.75 0 0 0 0 0
|
TARGETS=500 0.1 0.75 0 0 0 0 0
|
||||||
```
|
```
|
||||||
## Rebalancing
|
|
||||||
The liquidator will attempt to close all perp positions, and balance the tokens in the liqor account after each liquidation. By default it will sell all token assets into USDC. You can choose to maintain a certain amount of each asset through this process by editing the value in the `TARGETS` environment variable at the position of the asset. You can find the order of the assets in the 'oracles' property of the group in [ids.json](https://github.com/blockworks-foundation/mango-client-v3/blob/main/src/ids.json#L81) The program will attempt to make buy/sell orders during balancing to maintain this level.
|
|
||||||
|
|
||||||
## Advanced Orders Triggering
|
|
||||||
The liquidator triggers advanced orders for users when their trigger condition is met. Upon successfully triggering the order, the liquidator wallet will receive 100x the transaction fee as a reward.
|
|
||||||
|
|
||||||
## Run
|
|
||||||
```
|
|
||||||
yarn liquidator
|
|
||||||
```
|
|
|
@ -65,6 +65,14 @@ const groupIds = config.getGroup(cluster, groupName) ?? (() => { throw new Error
|
||||||
const TARGETS = process.env.TARGETS?.replace(/\s+/g,' ').trim().split(' ').map((s) => parseFloat(s))
|
const TARGETS = process.env.TARGETS?.replace(/\s+/g,' ').trim().split(' ').map((s) => parseFloat(s))
|
||||||
?? [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
?? [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
|
// Do not liquidate accounts that have less than this much in value
|
||||||
|
const minEquity = parseInt(
|
||||||
|
process.env.MIN_EQUITY || '0',
|
||||||
|
);
|
||||||
|
if(minEquity > 0) {
|
||||||
|
console.log(`Minimum equity required to liquidate: ${minEquity}`);
|
||||||
|
}
|
||||||
|
|
||||||
const mangoProgramId = groupIds.mangoProgramId;
|
const mangoProgramId = groupIds.mangoProgramId;
|
||||||
const mangoGroupKey = groupIds.publicKey;
|
const mangoGroupKey = groupIds.publicKey;
|
||||||
|
|
||||||
|
@ -276,6 +284,13 @@ async function maybeLiquidateAccount(mangoAccount: MangoAccount): Promise<boolea
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const equity = mangoAccount.computeValue(mangoGroup, cache).toNumber()
|
||||||
|
if (equity < minEquity && minEquity > 0) {
|
||||||
|
// console.log(`Account ${mangoAccountKeyString} only has ${equity}, PASS`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const health = mangoAccount.getHealthRatio(mangoGroup, cache, 'Maint');
|
const health = mangoAccount.getHealthRatio(mangoGroup, cache, 'Maint');
|
||||||
const accountInfoString = mangoAccount.toPrettyString(
|
const accountInfoString = mangoAccount.toPrettyString(
|
||||||
groupIds,
|
groupIds,
|
||||||
|
|
Loading…
Reference in New Issue