diff --git a/.github/workflows/scripts.yml b/.github/workflows/scripts.yml new file mode 100644 index 0000000..61a7117 --- /dev/null +++ b/.github/workflows/scripts.yml @@ -0,0 +1,42 @@ +name: Scripts + +on: + push: + branches: + - main + - perps + pull_request: + + +jobs: + coverage: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Required for coverage comparison + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + cache: 'yarn' + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + cache: 'yarn' # Specify yarn for caching + + - name: Install Dependencies + run: yarn install --frozen-lockfile + + - name: Run Tests + run: yarn test + + - name: Check Coverage + run: yarn test:coverage + + - name: Check Formatting + run: yarn format:check diff --git a/package.json b/package.json index 25e6f5a..fd6c7fc 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,11 @@ "scripts": { "test:integration": "yarn build && node build/test/redbank/integration/liquidationTest", "test:rover-integration": "yarn build && node build/test/rover/integration/liquidationTest", + "clean": "rimraf build", "build": "tsc", "start": "yarn build && node build/src/main", - "test": "jest", + "test": "yarn clean && yarn build && jest", + "test:coverage": "yarn clean && yarn build && jest --coverage", "lint": "yarn format-check && eslint . && yarn build", "format": "prettier --write .", "format-check": "prettier --ignore-path .gitignore --check ." diff --git a/src/query/routing/OsmosisRouteRequester.ts b/src/query/routing/OsmosisRouteRequester.ts index 70b77dc..ef746c5 100644 --- a/src/query/routing/OsmosisRouteRequester.ts +++ b/src/query/routing/OsmosisRouteRequester.ts @@ -1,10 +1,12 @@ import { RequestRouteResponse, RouteRequester } from './RouteRequesterInterface' export class OsmosisRouteRequester extends RouteRequester { - // @ts-ignore todo before deploying update on osmosis requestRoute( + //@ts-ignore tokenInDenom: string, + //@ts-ignore tokenOutDenom: string, + //@ts-ignore tokenInAmount: string, ): Promise { throw new Error('Method not implemented.') diff --git a/src/rover/RoverExecutor.ts b/src/rover/RoverExecutor.ts index bbac6b5..22a1a67 100644 --- a/src/rover/RoverExecutor.ts +++ b/src/rover/RoverExecutor.ts @@ -90,49 +90,55 @@ export class RoverExecutor extends BaseExecutor { } run = async () => { - // Pop latest unhealthy positions from the list - cap this by the number of liquidators we have available - const url = `${this.config.marsEndpoint!}/v2/unhealthy_positions?chain=${ - this.config.chainName - }&product=${this.config.productName}` - - const response = await fetch(url) - let targetAccountObjects: { - account_id: string - health_factor: string - total_debt: string - }[] = (await response.json())['data'] - - const targetAccounts = targetAccountObjects - .filter( - (account) => - Number(account.health_factor) < Number(process.env.MAX_LIQUIDATION_LTV) && - Number(account.health_factor) > Number(process.env.MIN_LIQUIDATION_LTV), - // To target specific accounts, filter here - ) - .sort((accountA, accountB) => Number(accountB.total_debt) - Number(accountA.total_debt)) - // Sleep to avoid spamming. + try { + // Pop latest unhealthy positions from the list - cap this by the number of liquidators we have available + const url = `${this.config.marsEndpoint!}/v2/unhealthy_positions?chain=${ + this.config.chainName + }&product=${this.config.productName}` + + const response = await fetch(url) + let targetAccountObjects: { + account_id: string + health_factor: string + total_debt: string + }[] = (await response.json())['data'] + + const targetAccounts = targetAccountObjects + .filter( + (account) => + Number(account.health_factor) < Number(process.env.MAX_LIQUIDATION_LTV) && + Number(account.health_factor) > Number(process.env.MIN_LIQUIDATION_LTV), + // To target specific accounts, filter here + ) + .sort((accountA, accountB) => Number(accountB.total_debt) - Number(accountA.total_debt)) + // Sleep to avoid spamming. - if (targetAccounts.length == 0) { - await sleep(2000) - return - } + if (targetAccounts.length == 0) { + await sleep(2000) + return + } - // create chunks of accounts to liquidate - const unhealthyAccountChunks = [] - for (let i = 0; i < targetAccounts.length; i += this.liquidatorAccounts.size) { - unhealthyAccountChunks.push(targetAccounts.slice(i, i + this.liquidatorAccounts.size)) - } - // iterate over chunks and liquidate - for (const chunk of unhealthyAccountChunks) { - const liquidatorAddressesIterator = this.liquidatorAccounts.keys() - const liquidationPromises: Promise[] = [] - for (const account of chunk) { - const nextLiquidator = liquidatorAddressesIterator.next() - console.log('liquidating: ', account.account_id, ' with ', nextLiquidator.value) - liquidationPromises.push(this.liquidate(account.account_id, nextLiquidator.value!)) + // create chunks of accounts to liquidate + const unhealthyAccountChunks = [] + for (let i = 0; i < targetAccounts.length; i += this.liquidatorAccounts.size) { + unhealthyAccountChunks.push(targetAccounts.slice(i, i + this.liquidatorAccounts.size)) + } + // iterate over chunks and liquidate + for (const chunk of unhealthyAccountChunks) { + const liquidatorAddressesIterator = this.liquidatorAccounts.keys() + const liquidationPromises: Promise[] = [] + for (const account of chunk) { + const nextLiquidator = liquidatorAddressesIterator.next() + console.log('liquidating: ', account.account_id, ' with ', nextLiquidator.value) + liquidationPromises.push(this.liquidate(account.account_id, nextLiquidator.value!)) + } + await Promise.all(liquidationPromises) + await sleep(4000) + } + } catch (ex) { + if (process.env.DEBUG) { + console.error(ex) } - await Promise.all(liquidationPromises) - await sleep(4000) } } diff --git a/test/liquidationGenerator.test.ts b/test/liquidationGenerator.test.ts index a2baa8b..575f532 100644 --- a/test/liquidationGenerator.test.ts +++ b/test/liquidationGenerator.test.ts @@ -14,7 +14,7 @@ describe('Liquidation Tx Generator Tests..', () => { const assets = [collateralA, collateralB] const largestIndex = collateralA.amount > collateralB.amount ? 0 : 1 const largestCollateral = getLargestCollateral(assets, prices) - expect(largestCollateral).toBe(assets[largestIndex].denom) + expect(largestCollateral.denom).toBe(assets[largestIndex].denom) }), test('Can get largest debt correctly', () => { const debtA: Debt = { ...generateRandomAsset(), uncollateralised: false } @@ -24,8 +24,8 @@ describe('Liquidation Tx Generator Tests..', () => { prices.set(debtB.denom, new BigNumber(2)) const assets = [debtA, debtB] const largestIndex = debtA.amount > debtB.amount ? 0 : 1 - const largestCollateral = getLargestDebt(assets, prices).denom + const largestDebt = getLargestDebt(assets, prices).denom - expect(largestCollateral).toBe(assets[largestIndex].denom) + expect(largestDebt).toBe(assets[largestIndex].denom) }) }) diff --git a/test/redbank/unit/redbankExecutor.test.ts b/test/redbank/unit/redbankExecutor.test.ts index 397a55c..0ccb17e 100644 --- a/test/redbank/unit/redbankExecutor.test.ts +++ b/test/redbank/unit/redbankExecutor.test.ts @@ -1,3 +1,4 @@ +import BigNumber from 'bignumber.js' import { calculateCollateralRatio, calculateLiquidationBonus, @@ -25,12 +26,12 @@ describe('Redbank Executor Tests', () => { { denom: 'untrn', amount: '1200' }, ] - const prices = new Map([ - ['uosmo', 3], - ['ujake', 1], - ['uatom', 8.2], - ['uusdc', 8.5], - ['untrn', 5.5], + const prices = new Map([ + ['uosmo', new BigNumber(3)], + ['ujake', new BigNumber(1)], + ['uatom', new BigNumber(8.2)], + ['uusdc', new BigNumber(8.5)], + ['untrn', new BigNumber(5.5)], ]) //@ts-ignore @@ -69,7 +70,6 @@ describe('Redbank Executor Tests', () => { targetHealthFactor, //@ts-ignore debts, - // @ts-ignore collaterals, assetLts, liquidationBonus, diff --git a/test/rover/unit/LiquidationActionGenerator.test.ts b/test/rover/unit/LiquidationActionGenerator.test.ts index 1f2221d..4a508bf 100644 --- a/test/rover/unit/LiquidationActionGenerator.test.ts +++ b/test/rover/unit/LiquidationActionGenerator.test.ts @@ -79,7 +79,6 @@ describe('Liquidation Action Generator Tests', () => { expect(denom).toBe('uatom') }) it('Action 1; Should select deposit usd collateral', () => { - console.log(actions[1]) // @ts-ignore let denom: String = actions[1].liquidate.request.deposit @@ -372,7 +371,6 @@ describe('Liquidation Action Generator Tests', () => { }) it('Should pick the usd collateral', () => { - console.log(actions[1]) // @ts-ignore let denom: String = actions[1].liquidate.request.deposit @@ -452,7 +450,6 @@ describe('Liquidation Action Generator Tests', () => { }) it('Should pick the usd collateral', () => { - console.log(actions[1]) // @ts-ignore let denom: String = actions[1].liquidate.request.deposit