Skip to content

Commit

Permalink
Merge pull request #2 from superfluid-finance/fallback
Browse files Browse the repository at this point in the history
This PR is the base of Graphinator Refactoring
  • Loading branch information
ngmachado authored Aug 31, 2024
2 parents 119309b + 6f14a9e commit 872fba9
Show file tree
Hide file tree
Showing 10 changed files with 674 additions and 526 deletions.
45 changes: 19 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,42 @@
# graphinator
# About

Graphinator is a small tool to execute liquidations based on graph data.
The **graphinator** is a lightweight alternative to the [superfluid-sentinel](https://github.com/superfluid-finance/superfluid-sentinel).
It looks for [critical or insolvent accounts](https://docs.superfluid.finance/docs/protocol/advanced-topics/solvency/liquidations-and-toga) and liquidates their outgoing flows (CFA and GDA).
Unlike the sentinel, it is stateless and relies on the [Superfluid Subgraph](https://console.superfluid.finance/subgraph) as data source.

By default, the graphinator operates in a _one-shot_ mode, meaning: it checks and liquidates once, then exits.
For continued operation, it's recommended to set up a cronjob.

## Prerequisites

- [Bun](https://bun.sh/)
Once graphinator instance operates for a to-be-specified chain.
By default, it operates on all [listed Super Token](https://console.superfluid.finance/supertokens), but also allows to operate only on a single Super Token.

## Install Bun
## Prerequisites

Install Bun:
```bash
curl -fsSL https://bun.sh/install | bash
```

To install dependencies:

Set up the repo and install dependencies:
```bash
git clone https://github.com/superfluid-finance/graphinator
cd graphinator
bun install
```

## Run

- Set your environment variables in a `.env` file. You'll need to provide your private key. (check ```.env.example```)
- Make the `grt.ts` file executable: `chmod +x grt.ts`

Fast run:

```bash
./grt.ts -t 0x1eff3dd78f4a14abfa9fa66579bd3ce9e1b30529
```

### OR

```bash
./grt.ts -t 0x1eff3dd78f4a14abfa9fa66579bd3ce9e1b30529 -l true
PRIVATE_KEY=... ./grt.ts -n <network>
```

### Options
_network_ needs to be the canonical name of a chain where Superfluid is deployed. See [metadata/networks.json](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/metadata/networks.json) (field _name_). For example `base-mainnet`.

You can also provide `PRIVATE_KEY` via an `.env` file.

- `--network`: The network to use. Defaults to `base-mainnet`.
- `--token`: The token to liquidate. This is a required option.
- `--batchSize`: The number of accounts to liquidate in each batch. Defaults to `15`.
- `--gasMultiplier`: A multiplier to apply to the estimated gas cost for each transaction. Defaults to `1.2`.
- `--loop`: If set, the script will run indefinitely, checking for new accounts to liquidate every 15min.
Make sure `grt.ts` is executable.

See `./grt.ts --help` for more config options.

## License

Expand Down
Binary file modified bun.lockb
Binary file not shown.
87 changes: 49 additions & 38 deletions grt.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,88 @@
#!/usr/bin/env bun

import dotenv from "dotenv";

import yargs from "yargs"
import { hideBin } from "yargs/helpers"
import Graphinator from './src/graphinator';


const log = (msg: string, lineDecorator="") => console.log(`${new Date().toISOString()} - ${lineDecorator} (Graphinator) ${msg}`);


dotenv.config();

const argv = await yargs(hideBin(process.argv))
.option('network', {
alias: 'n',
type: 'string',
description: 'Set the network',
default: 'base-mainnet'
demandOption: true,
default: process.env.NETWORK
})
.option('batchSize', {
alias: 'b',
/*
Note: there's currently no scientific way to determine a safe batch size.
That's because the gas consumed by an individual flow's liquidation can vary widely,
especially if SuperApp callbacks are involved.
The safe and default choice is thus 1.
Most of the time considerably higher values (e.g. 10) will work and may be used.
But since the logic is currently such that a failing batch could stall any progress,
setting this differently should be a conscious choice.
*/
.option('token', {
alias: 't',
type: 'string',
description: 'Address of the Super Token to process. If not set, all "listed" (curated) Super Tokens will be processed',
default: process.env.TOKEN
})
.option('maxGasPriceMwei', {
alias: 'm',
type: 'number',
description: 'Set the batch size',
default: 15
description: 'Set the max gas price in mwei (milli wei). Default: 10000 (10 gwei)',
default: process.env.MAX_GAS_PRICE_MWEI ? parseInt(process.env.MAX_GAS_PRICE_MWEI) : 10000
})
.option('gasMultiplier', {
alias: 'g',
type: 'number',
description: 'Set the gas multiplier',
default: 1.2
description: 'Set the gas multiplier - allows to define the gas limit margin set on top of the estimation',
default: process.env.GAS_MULTIPLIER ? parseFloat(process.env.GAS_MULTIPLIER) : 1.2
})
.option('token', {
alias: 't',
type: 'string',
description: 'Set the token to liquidate',
demandOption: true
.option('batchSize', {
alias: 'b',
type: 'number',
description: 'Set the batch size',
default: process.env.BATCH_SIZE ? parseInt(process.env.BATCH_SIZE) : 1
})
.option('loop', {
alias: 'l',
type: 'boolean',
description: 'Set to true to loop forever, false to run once',
default: false
})
.option('maxGasPrice', {
alias: 'm',
type: 'number',
description: 'Set the max gas price',
default: 500000000
description: 'Set to true to loop forever, false to run once.',
default: process.env.LOOP === 'true'
})
.parse();

const runAgainIn = 15 * 60 * 1000;
const runAgainIn = 30000 //15 * 60 * 1000;
const network = argv.network;
const batchSize = argv.batchSize;
const gasMultiplier = argv.gasMultiplier;
const token = argv.token.toLowerCase();
const token = argv.token;
const loop = argv.loop;
const maxGasPrice = BigInt(argv.maxGasPrice);


const config = {
batchContractAddress: '0x6b008BAc0e5846cB5d9Ca02ca0e801fCbF88B6f9',
gdaForwarderAddress: '0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08',
superTokenAddress: token
}
const maxGasPrice = argv.maxGasPriceMwei * 1000000;

const ghr = new Graphinator(network, config);
const ghr = new Graphinator(network, batchSize, gasMultiplier, maxGasPrice);
if(loop) {
log("run liquidations forever...", "🤖");
await ghr.run(batchSize, gasMultiplier, maxGasPrice, BigInt(0));
setInterval(async () => {
const executeLiquidations = async () => {
try {
await ghr.run(batchSize, gasMultiplier, maxGasPrice, BigInt(0));
await ghr.processAll(token);
} catch (error) {
console.error(error);
} finally {
log(`run again in ${runAgainIn}`);
setTimeout(executeLiquidations, runAgainIn); // Schedule the next run
}
}, runAgainIn);
};
await executeLiquidations();
} else {
log("run liquidations once...", "🤖");
await ghr.run(batchSize, gasMultiplier, maxGasPrice, BigInt(0));
log(new Date().toISOString() + " - run liquidations...");
await ghr.processAll(token);
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
},
"dependencies": {
"@superfluid-finance/ethereum-contracts": "^1.9.1",
"@superfluid-finance/metadata": "^1.5.0",
"@types/yargs": "^17.0.32",
"axios": "^1.7.1",
"dotenv": "^16.4.5",
"ethers": "^6.12.1",
"yargs": "^17.7.2"
}
Expand Down
Loading

0 comments on commit 872fba9

Please sign in to comment.