From 0a742dd7a7d6bba45d809135ac6a084962d91e28 Mon Sep 17 00:00:00 2001 From: mootz12 Date: Mon, 7 Oct 2024 17:55:32 -0400 Subject: [PATCH 1/2] chore: document the configuration file --- README.md | 92 ++++++++++++++++++++++++++++++++++++++++++--- example.config.json | 48 +++++++++++++---------- 2 files changed, 116 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b9d1d85..3bb69d8 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,100 @@ The auctioneer bot monitors a Blend pool to create and bid on auctions. This includes user liquidation auctions, bad debt auctions, and interest auctions. The auctioneer focuses on completeness and pool safety over profit, but the existing code can be modified to meet any use case. +For more information please see [the Blend docs](https://docs.blend.capital/tech-docs/core-contracts/lending-pool). + +## Safety + +This software is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including Script3. You acknowledge that you are solely responsible for any use of this software and you assume all risks associated with any such use. + ## Getting Started -The auctioneer is packaged into a single docker container. To build the image, run: +It is recommended to run the auctioneer bot as a docker container. The image can be pulled with: + +```bash +docker pull script3/auctioneer-bot:latest +``` + +To run the container, you will need to provide a volume mount from the host to `/app/data` with a config file named `config.json` at the root of the volume. Please see [Configuration](#configuration) for documentation of the configuration file. + +The container will create a sqlite3 database that tracks bot activity and log files outputted by the bot in the mounted volume. ```bash -npm run build:docker-{'x86' or 'arm'} +docker run --restart always -d -v /path/on/host:/app/data script3/auctioneer-bot:latest ``` -To run the image, start with the following command: +The auctioneer bot requires access to a Soroban RPC server, and is fairly chatty. We recommend running an Soroban RPC server on the same host to avoid issues with rate limiting / usage. Please see the Stellar documentation for running a [Soroban RPC](https://developers.stellar.org/docs/data/rpc). We recommend running the [Soroban RPC as a docker container](https://developers.stellar.org/docs/data/rpc/admin-guide#docker-image). The Auctioneer bot itself is not very resource intensive, and should work fine alongside an RPC with the suggested hardware requirements for the Soroban RPC server. + +Auctions filled by the bot will have an entry populated in the `filled_auctions` table of the DB, with the bots estimated profit on the trade included. + +## Important Info + +This bot does not automatically unwind all positions it bids on. It is recommended to manually adjust your positions as necessary as auctions get filled. + +Certain auctions cause your filler to take on liabilities, and if these assets are not cleared in a timely manner, could result in the filler also getting liquidated. + +### Configuration + +For an example config file that is configured to interact with [Blend v1 mainnet protocol](https://docs.blend.capital/), please see [example.config.json](https://github.com/script3/auctioneer-bot/blob/main/example.config.json). + +#### General Settings + +| Field | Description | +|-------|-------------| +| `name` | A descriptive name for your bot instance. | +| `rpcURL` | The URL of the Soroban RPC endpoint. | +| `networkPassphrase` | The network passphrase identifying the Stellar network. | +| `poolAddress` | The address of the Blend pool contract this bot will be tracking. | +| `backstopAddress` | The address of the Blend backstop contract. | +| `backstopTokenAddress` | The address of the Blend backstop token contract. | +| `usdcAddress` | The address of the USDC token contract. | +| `blndAddress` | The address of the BLND token contract. | +| `keypair` | The secret key for the bot's auction creating account. This should be different from the fillers as auction creation and auction bidding can happen simultaneously. **Keep this secret and secure!** | +| `fillers` | A list of accounts that will bid and fill on auctions. | +| `priceSources` | A list of assets that will have prices sourced from exchanges instead of the pool oracle. | +| `slackWebhook` | (Optional) A slack webhook URL to post updates to (https://hooks.slack.com/services/). Leave undefined if no webhooks are required. | + +#### Fillers + +The `fillers` array contains configurations for individual filler accounts. The account chosen to fill an auction is the first filler in the list that supports all bid and lot assets in the auction. Each filler has the following properties: + +| Field | Description | +|-------|-------------| +| `name` | A unique name for this filler account. Used in logs and slack notifications. | +| `keypair` | The secret key for this filler account. **Keep this secret and secure!** | +| `minProfitPct` | The minimum profit percentage required for the filler to bid on an auction. | +| `minHealthFactor` | The minimum health factor the filler will take on during liquidation and bad debt auctions. | +| `forceFill` | Boolean flag to indicate if the bot should force fill auctions even if profit expectations aren't met to ensure pool health. | +| `supportedBid` | An array of asset addresses that this filler bot is allowed to bid with. Bids are taken as additional liabilities (dTokens) for liquidation and bad debt auctions, and tokens for interest auctions. Must include the `backstopTokenAddress` to bid on interest auctions. | +| `supportedLot` | An array of asset addresses that this filler bot is allowed to receive. Lots are given as collateral (bTokens) for liquidation auctions and tokens for interest and bad debt auctions. The filler should have trustlines to all assets that are Stellar assets. Must include `backstopTokenAddress` to bid on bad debt auctions. | + +#### Price Sources + +The `priceSources` array defines the additional sources for price data. If an asset has a price source, the oracle prices will not be used when calculating profit, and instead the price fetched from the price source will be. + +Prices are fetched from the following endpoints: +* Coinbase: https://api.coinbase.com/api/v3/brokerage/market/products?product_ids=SYMBOL +* Binance: https://api.binance.com/api/v3/ticker/price?symbols=[SYMBOL] + +Each price source has the following fields: + +| Field | Description | +|-------|-------------| +| `assetId` | The address of the asset for which this price source provides data. | +| `type` | The type of price source (e.g., "coinbase", "binance"). | +| `symbol` | The trading symbol used by the price source for this asset. | + +## Build + +If you make modifications to the bot, you can build a new dockerfile by running: ```bash -docker run --restart always -d -v /path/on/host:/app/data auctioneer-bot-{'architecture'} +npm run build:docker-{arm, x86} ``` -It is recommended to mount the `/app/data` directory to the host machine. This folder contains a sqlite database and system logs. +You can then follow the instructions in [Getting Started](#getting-started), but instead use `auctioneer-bot-{arm, x86}` as the docker image. + +The bot can also be run locally with node, but you will need to invoke `start.sh` to initialize a database at `./data` and a location to place logs at `./data/logs`. + + + diff --git a/example.config.json b/example.config.json index d9a9f89..9ffd4f9 100644 --- a/example.config.json +++ b/example.config.json @@ -1,32 +1,42 @@ { - "rpcURL": "https://example.com/rpc", - "networkPassphrase": "example-network-passphrase", + "name": "Example Bot", + "rpcURL": "http://localhost:8000", + "networkPassphrase": "Public Global Stellar Network ; September 2015", "poolAddress": "C...", - "backstopAddress": "C...", - "backstopTokenAddress": "C...", - "usdcAddress": "C...", - "blndAddress": "C...", - "auctioneers": [ + "backstopAddress": "CAO3AGAMZVRMHITL36EJ2VZQWKYRPWMQAPDQD5YEOF3GIF7T44U4JAL3", + "backstopTokenAddress": "CAS3FL6TLZKDGGSISDBWGGPXT3NRR4DYTZD7YOD3HMYO6LTJUVGRVEAM", + "usdcAddress": "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75", + "blndAddress": "CD25MNVTZDL4Y3XBCPCJXGXATV5WUHHOWMYFF4YBEGU5FCPGMYTVG5JY", + "keypair": "S...", + "fillers": [ { - "secret": "example-secret", - "minProfitPct": 0.05, - "minHealthFactor": 0.8, + "name": "example-liquidator", + "keypair": "S...", + "minProfitPct": 0.10, + "minHealthFactor": 1.5, "forceFill": true, - "supportedBid": ["bid1", "bid2"], - "supportedLot": ["lot1", "lot2"] - } + "supportedBid": [ + "CAS3FL6TLZKDGGSISDBWGGPXT3NRR4DYTZD7YOD3HMYO6LTJUVGRVEAM", + "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75", + "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA" + ], + "supportedLot": [ + "CAS3FL6TLZKDGGSISDBWGGPXT3NRR4DYTZD7YOD3HMYO6LTJUVGRVEAM", + "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75", + "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA" + ] + } ], "priceSources": [ { - "assetId": "C...", + "assetId": "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA", "type": "coinbase", - "symbol": "ETH-USD" + "symbol": "XLM-USD" }, { - "assetId": "C...", + "assetId": "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA", "type": "binance", - "symbol": "BTCUSDT" + "symbol": "XLMUSDT" } - ], - "slackWebhook": "https://example.com/slack-webhook" + ] } \ No newline at end of file From 4d8fdbae421f0a1d4aa5d555709fc98dfaaba757 Mon Sep 17 00:00:00 2001 From: mootz12 Date: Tue, 8 Oct 2024 14:03:02 -0400 Subject: [PATCH 2/2] chore: clean up getting started wording in readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3bb69d8..44ce641 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,11 @@ It is recommended to run the auctioneer bot as a docker container. The image can docker pull script3/auctioneer-bot:latest ``` -To run the container, you will need to provide a volume mount from the host to `/app/data` with a config file named `config.json` at the root of the volume. Please see [Configuration](#configuration) for documentation of the configuration file. +To run the container, you will need to mount a directory from the host to `/app/data` on the container. The directory must contain a config file named `config.json` at its root. Please see [Configuration](#configuration) for details on the configuration file. -The container will create a sqlite3 database that tracks bot activity and log files outputted by the bot in the mounted volume. +The container will create a sqlite3 database that tracks bot activity and log files in the mounted directory. +Use the following command to run the container: ```bash docker run --restart always -d -v /path/on/host:/app/data script3/auctioneer-bot:latest ```