Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ For an example config file that is configured to interact with [Blend 2 mainnet

**It is highly recommended to create a backup of the database file before attempting any migration.**

For auctioneers that were started before multi-pool functionality a db migration will be neccessary. On startup of the updated auctioneer bot a command line argument will be required to be inputed with `-p` or `--prev-pool-id` followed by the pool id that the single pool auctioneer bot was using. The migration will update the database to the new schema and will populate the pool id column with the one provided.
For auctioneers that were started before multi-pool functionality a db migration will be necessary. On startup of the updated auctioneer bot a command line argument will be required to be inputted with `-p` or `--prev-pool-id` followed by the pool id that the single pool auctioneer bot was using. The migration will update the database to the new schema and will populate the pool id column with the one provided.

#### General Settings

Expand All @@ -64,10 +64,13 @@ For auctioneers that were started before multi-pool functionality a db migration
| `blndAddress` | The address of the BLND token contract. |
| `interestFillerAddress` | A contract address used to help fill interest auctions. Must implement the same interface as [this example](https://github.com/script3/interest-auction-filler). |
| `workerKeypair` | The secret key for the bot's auction creating account. This should be different from the filler as auction creation and auction bidding can happen simultaneously. **Keep this secret and secure!** |
| `fillerKeypair` | The securet key for the bot's auction filler account. This should be different from the worker as auction creation and auction bidding can happen simultaneously. **Keep this secret and secure!** |
| `fillerKeypair` | The secret key for the bot's auction filler account. This should be different from the worker as auction creation and auction bidding can happen simultaneously. **Keep this secret and secure!** |
| `pools` | A list of pool configs that dictates what pools are monitored |
| `notificationLevel` | (Default - `med`) The severity level where notifications are sent to either the console or a webhook, if present. Can be one of `low`, `med`, or `high`. High notifications includes dropped actions, bad debt auctions, and critical errors. Med adds all successful auction fills, liquidation auctions, and retried errors. Low adds additional info notifications and interest auctions. |
| `baseFee` | (Default - `5000`) The minimum inclusion fee that will be specified for a normal transaction, otherwise feeStats p70. |
| `highBaseFee` | (Default - `10000`) The minimum inclusion fee that will be specified for a high priority transaction, otherwise feeStats p90. This is considered any auction fill where the estimated profit is over 10 oracle units (almost always $10). |
| `priceSources` | (Optional) A list of assets that will have prices sourced from exchanges instead of the pool oracle. |
| `profits` | (Optional) A list of auction profits to define different profit percentages used for matching auctions.
| `profits` | (Optional) A list of auction profits to define different profit percentages used for matching auctions. |
| `slackWebhook` | (Optional) A slack webhook URL to post updates to (https://hooks.slack.com/services/). Leave undefined if no webhooks are required. |
| `discordWebhook` | (Optional) A Discord webhook URL to post updates to. Leave undefined if no webhooks are required. |

Expand Down Expand Up @@ -120,7 +123,7 @@ Each DEX price source has the following fields:

#### Profits

The `profits` list defines target profit percentages based on the assets that make up the bid and lot of a given auction. This allows fillers to have flexability in the profit they target. The profit percentage chosen will be the first entry in the `profits` list that supports all bid and lot assets in the auction. If no profit entry is found, the `defaultProfitPct` value defined by the filler will be used.
The `profits` list defines target profit percentages based on the assets that make up the bid and lot of a given auction. This allows fillers to have flexibility in the profit they target. The profit percentage chosen will be the first entry in the `profits` list that supports all bid and lot assets in the auction. If no profit entry is found, the `defaultProfitPct` value defined by the filler will be used.

Each profit entry has the following fields:

Expand Down
3 changes: 3 additions & 0 deletions example.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"rpcURL": "http://localhost:8000",
"networkPassphrase": "Public Global Stellar Network ; September 2015",
"horizonURL": "http://horizon:8000",
"notificationLevel": "med",
"baseFee": 5000,
"highBaseFee": 10000,
"backstopAddress": "CAO3AGAMZVRMHITL36EJ2VZQWKYRPWMQAPDQD5YEOF3GIF7T44U4JAL3",
"backstopTokenAddress": "CAS3FL6TLZKDGGSISDBWGGPXT3NRR4DYTZD7YOD3HMYO6LTJUVGRVEAM",
"usdcAddress": "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
Expand Down
5 changes: 0 additions & 5 deletions example.env

This file was deleted.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "auctioneer-bot",
"version": "3.0.1",
"version": "3.1.0",
"main": "index.js",
"type": "module",
"scripts": {
Expand Down
7 changes: 5 additions & 2 deletions src/bidder_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { APP_CONFIG } from './utils/config.js';
import { AuctioneerDatabase, AuctionType } from './utils/db.js';
import { stringify } from './utils/json.js';
import { logger } from './utils/logger.js';
import { sendNotification } from './utils/notifier.js';
import { getNotificationLevelForAuction, sendNotification } from './utils/notifier.js';
import { SorobanHelper } from './utils/soroban_helper.js';

export class BidderHandler {
Expand Down Expand Up @@ -90,7 +90,10 @@ export class BidderHandler {
`Fill: ${stringify(fill, 2)}\n` +
`Ledgers To Fill In: ${fill.block - nextLedger}\n`;
if (auctionEntry.fill_block === 0) {
await sendNotification(logMessage);
await sendNotification(
logMessage,
getNotificationLevelForAuction(auction.type, false)
);
}
logger.info(logMessage);
auctionEntry.fill_block = fill.block;
Expand Down
20 changes: 15 additions & 5 deletions src/bidder_submitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { APP_CONFIG } from './utils/config.js';
import { AuctioneerDatabase, AuctionEntry, AuctionType } from './utils/db.js';
import { serializeError, stringify } from './utils/json.js';
import { logger } from './utils/logger.js';
import { sendNotification } from './utils/notifier.js';
import {
getNotificationLevelForAuction,
sendNotification,
NotificationLevel,
} from './utils/notifier.js';
import { SorobanHelper } from './utils/soroban_helper.js';
import { SubmissionQueue } from './utils/submission_queue.js';
import { InterestFillerContract } from './utils/interest_filler.js';
Expand Down Expand Up @@ -181,7 +185,10 @@ export class BidderSubmitter extends SubmissionQueue<BidderSubmission> {
`Fill Percent ${fill.percent}\n` +
`Ledger Fill Delta ${result.ledger - auctionBid.auctionEntry.start_block}\n` +
`Hash ${result.txHash}\n`;
await sendNotification(logMessage);
await sendNotification(
logMessage,
getNotificationLevelForAuction(auctionBid.auctionEntry.auction_type, true)
);
logger.info(logMessage);
return true;
} else {
Expand All @@ -203,7 +210,10 @@ export class BidderSubmitter extends SubmissionQueue<BidderSubmission> {
`User: ${auctionBid.auctionEntry.user_id}\n` +
`Filler: ${APP_CONFIG.fillerKeypair.publicKey()}\n` +
`Error: ${stringify(serializeError(e))}`;
await sendNotification(logMessage, true);
await sendNotification(
logMessage,
getNotificationLevelForAuction(auctionBid.auctionEntry.auction_type, false)
);
logger.error(logMessage, e);
return false;
}
Expand Down Expand Up @@ -310,7 +320,7 @@ export class BidderSubmitter extends SubmissionQueue<BidderSubmission> {
`Pool: ${fillerUnwind.poolId}\n` +
`Positions: ${stringify(filler_user.positions, 2)}`;
logger.info(logMessage);
await sendNotification(logMessage);
await sendNotification(logMessage, NotificationLevel.HIGH);
return true;
}

Expand Down Expand Up @@ -345,6 +355,6 @@ export class BidderSubmitter extends SubmissionQueue<BidderSubmission> {
break;
}
logger.error(logMessage);
await sendNotification(logMessage);
await sendNotification(logMessage, NotificationLevel.HIGH);
}
}
9 changes: 6 additions & 3 deletions src/filler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ export function getFillerProfitPct(poolConfig: PoolConfig, auctionData: AuctionD
let auctionProfits = APP_CONFIG.profits ?? [];
for (const profit of auctionProfits) {
if (
(!bidAssets.includes('*') &&
(!profit.supportedBid.includes('*') &&
bidAssets.some((address) => !profit.supportedBid.includes(address))) ||
(!lotAssets.includes('*') &&
(!profit.supportedLot.includes('*') &&
lotAssets.some((address) => !profit.supportedLot.includes(address)))
) {
// either some bid asset or some lot asset is not in the profit's supported assets, skip
Expand Down Expand Up @@ -172,7 +172,10 @@ export function managePositions(
// short circuit collateral withdrawal if close to min hf
// this avoids very small amout of dust collateral being withdrawn and
// causing unwind events to loop
if (poolConfig.minHealthFactor * 1.01 > effectiveCollateral / effectiveLiabilities) {
if (
effectiveLiabilities != 0 &&
poolConfig.minHealthFactor * 1.01 > effectiveCollateral / effectiveLiabilities
) {
return requests;
}

Expand Down
5 changes: 2 additions & 3 deletions src/liquidations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { AuctioneerDatabase, AuctionType } from './utils/db.js';
import { logger } from './utils/logger.js';
import { SorobanHelper } from './utils/soroban_helper.js';
import { WorkSubmission, WorkSubmissionType } from './work_submitter.js';
import { sendNotification } from './utils/notifier.js';
import { stringify } from './utils/json.js';
import { sendNotification, NotificationLevel } from './utils/notifier.js';

/**
* A representation of a position taking into account the oracle price.
Expand Down Expand Up @@ -257,7 +256,7 @@ export async function scanUsers(
} catch (e) {
const errorLog = `Error scanning for liquidations: ${poolConfig.poolAddress}\nError: ${e}`;
logger.error(errorLog);
sendNotification(errorLog);
sendNotification(errorLog, NotificationLevel.MED);
}
}
return submissions;
Expand Down
29 changes: 22 additions & 7 deletions src/pool_event_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AuctioneerDatabase, AuctionEntry, AuctionType } from './utils/db.js';
import { stringify } from './utils/json.js';
import { logger } from './utils/logger.js';
import { deadletterEvent, sendEvent } from './utils/messages.js';
import { sendNotification } from './utils/notifier.js';
import { getNotificationLevelForAuction, sendNotification } from './utils/notifier.js';
import { SorobanHelper } from './utils/soroban_helper.js';
import { WorkSubmission } from './work_submitter.js';

Expand Down Expand Up @@ -100,7 +100,10 @@ export class PoolEventHandler {
`Pool: ${pool.id}\n` +
`User: ${poolEvent.event.user}\n` +
`Auction Data: ${stringify(poolEvent.event.auctionData, 2)}\n`;
await sendNotification(logMessage);
await sendNotification(
logMessage,
getNotificationLevelForAuction(poolEvent.event.auctionType, false)
);
logger.info(logMessage);
return;
}
Expand All @@ -122,7 +125,10 @@ export class PoolEventHandler {
`Pool: ${pool.id}\n` +
`User: ${poolEvent.event.user}\n` +
`Auction Data: ${stringify(poolEvent.event.auctionData, 2)}\n`;
await sendNotification(logMessage);
await sendNotification(
logMessage,
getNotificationLevelForAuction(poolEvent.event.auctionType, false)
);
logger.info(logMessage);
break;
}
Expand All @@ -138,7 +144,10 @@ export class PoolEventHandler {
`Liquidation Auction Deleted\n` +
`Pool: ${pool.id}\n` +
`User: ${poolEvent.event.user}\n`;
await sendNotification(logMessage);
await sendNotification(
logMessage,
getNotificationLevelForAuction(AuctionType.Liquidation, false)
);
logger.info(logMessage);
}
break;
Expand All @@ -153,7 +162,10 @@ export class PoolEventHandler {
`User: ${poolEvent.event.user}\n` +
`Fill Percent: ${poolEvent.event.fillAmount}\n` +
`Tx Hash: ${poolEvent.event.txHash}\n`;
await sendNotification(logMessage);
await sendNotification(
logMessage,
getNotificationLevelForAuction(poolEvent.event.auctionType, false)
);
logger.info(logMessage);
if (poolEvent.event.fillAmount === BigInt(100)) {
// auction was fully filled, remove from ongoing auctions
Expand Down Expand Up @@ -211,11 +223,14 @@ export class PoolEventHandler {
let runResult = this.db.deleteAuctionEntry(pool.id, user, auctionType);
if (runResult.changes !== 0) {
const logMessage =
`Stale Auction Deleted\n` +
`Auction Deleted Before Fill\n` +
`Type: ${AuctionType[auctionType]}\n` +
`Pool: ${pool.id}\n` +
`User: ${user}`;
await sendNotification(logMessage);
await sendNotification(
logMessage,
getNotificationLevelForAuction(poolEvent.event.auctionType, false)
);
logger.info(logMessage);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/utils/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Keypair } from '@stellar/stellar-sdk';
import { readFileSync } from 'fs';
import { parse } from './json.js';
import { NotificationLevel } from './notifier.js';

export enum PriceSourceType {
BINANCE = 'binance',
Expand Down Expand Up @@ -57,6 +58,7 @@ export interface AppConfig {
fillerKeypair: Keypair;
pools: PoolConfig[];
// optional fields
notificationLevel: NotificationLevel | undefined;
horizonURL: string | undefined;
priceSources: PriceSource[] | undefined;
profits: AuctionProfit[] | undefined;
Expand Down Expand Up @@ -94,6 +96,9 @@ export function validateAppConfig(config: any): boolean {
typeof config.workerKeypair !== 'string' ||
typeof config.fillerKeypair !== 'string' ||
!Array.isArray(config.pools) ||
// default fields
(config.notificationLevel !== undefined &&
!Object.values(NotificationLevel).includes(config.notificationLevel)) ||
// optional fields
(config.horizonURL !== undefined && typeof config.horizonURL !== 'string') ||
(config.priceSources !== undefined && !Array.isArray(config.priceSources)) ||
Expand Down
Loading