From 6aa81787e72e3f6042e4d19e82e01f7b5ef2a358 Mon Sep 17 00:00:00 2001 From: valia fetisov Date: Thu, 4 Apr 2024 19:55:37 +0200 Subject: [PATCH] chore: Improve simulations (#616) --- bot/src/keepers/collateral.ts | 23 ++++-- core/simulations/configs/vaultLiquidation.ts | 75 +++++++++++--------- core/src/auctions.ts | 4 +- 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/bot/src/keepers/collateral.ts b/bot/src/keepers/collateral.ts index 5e7a9ead3..4c32dd1aa 100644 --- a/bot/src/keepers/collateral.ts +++ b/bot/src/keepers/collateral.ts @@ -1,6 +1,7 @@ import { AuctionInitialInfo } from 'auctions-core/src/types'; import { bidWithCallee, enrichAuction } from 'auctions-core/src/auctions'; import getSigner from 'auctions-core/src/signer'; +import { fetchVATbalanceDAI, fetchBalanceDAI } from 'auctions-core/src/wallet'; import { KEEPER_COLLATERAL_MINIMUM_NET_PROFIT_DAI } from '../variables'; import { checkAndAuthorizeCollateral, checkAndAuthorizeWallet } from '../authorisation'; import { setupWallet } from '../signer'; @@ -49,18 +50,22 @@ const checkAndParticipateIfPossible = async function (network: string, auction: return; } - // check auction's profit + // check auction's gross profit if (!auctionTransaction.transactionGrossProfit || auctionTransaction.transactionGrossProfit.isLessThan(0)) { if (auctionTransaction.transactionGrossProfit) { - const profit = `${auctionTransaction.transactionGrossProfit.toFixed(0)} DAI`; + const grossProfit = `${auctionTransaction.transactionGrossProfit.toFixed(0)} DAI`; console.info( - `collateral keeper: auction "${auction.id}" is not yet profitable (current profit: ${profit})` + `collateral keeper: auction "${auction.id}" is not yet executable (current gross profit: ${grossProfit})` ); } else { console.info(`collateral keeper: auction "${auction.id}" is not tradable`); } return; } + const grossProfit = `${auctionTransaction.transactionGrossProfit.toFixed(0)} DAI`; + console.info( + `collateral keeper: auction "${auction.id}" gross profit is ${grossProfit}, moving on to check net profit` + ); // check auction's net profit – profit without transaction fees if ( @@ -70,7 +75,7 @@ const checkAndParticipateIfPossible = async function (network: string, auction: console.info( `collateral keeper: auction "${ auction.id - }" net profit is smaller than min profit (${auctionTransaction.transactionNetProfit.toFixed( + }" net profit is smaller than min net profit (${auctionTransaction.transactionNetProfit.toFixed( 0 )} < ${KEEPER_COLLATERAL_MINIMUM_NET_PROFIT_DAI})` ); @@ -107,6 +112,10 @@ const checkAndParticipateIfPossible = async function (network: string, auction: return; } + // save previous balances + const preVatBalanceDai = await fetchVATbalanceDAI(network, walletAddress); + const preErcBalanceDai = await fetchBalanceDAI(network, walletAddress); + // bid on the Auction console.info(`collateral keeper: auction "${auctionTransaction.id}": attempting swap execution`); const bidHash = await bidWithCallee( @@ -118,6 +127,12 @@ const checkAndParticipateIfPossible = async function (network: string, auction: console.info( `collateral keeper: auction "${auctionTransaction.id}" was succesfully executed via "${bidHash}" transaction` ); + + // display profit + const postVatBalanceDai = await fetchVATbalanceDAI(network, walletAddress); + const postErcBalanceDai = await fetchBalanceDAI(network, walletAddress); + console.info(`DAI VAT profit from the transaction: ${postVatBalanceDai.minus(preVatBalanceDai).toFixed()}`); + console.info(`DAI ERC profit from the transaction: ${postErcBalanceDai.minus(preErcBalanceDai).toFixed()}`); }; const participateInAuction = async function (network: string, auction: AuctionInitialInfo) { diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index ebc8313a9..e93dd31ef 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -9,9 +9,11 @@ import createVaultWithCollateral, { } from '../helpers/createVaultWithCollateral'; import promptToSelectOneOption from '../helpers/promptToSelectOneOption'; import promptToGetBlockNumber from '../helpers/promptToGetBlockNumber'; +import getProvider from '../../src/provider'; -import { fetchMaximumAuctionDurationInSeconds } from '../../src/fetch'; +import fetchAuctionsByCollateralType, { fetchMaximumAuctionDurationInSeconds } from '../../src/fetch'; import { getAllCollateralTypes } from '../../src/constants/COLLATERALS'; +import { setCollateralDebtCeilingToGlobal } from '../../helpers/hardhat/contractParametrization'; const TWO_YEARS_IN_MINUTES = 60 * 24 * 30 * 12 * 2; @@ -23,8 +25,10 @@ const simulation: Simulation = { entry: async () => { const number = await promptToGetBlockNumber(); await resetNetworkAndSetupWallet(number); + await addDaiToBalance(); + await addMkrToBalance(); const collateralType = await promptToSelectOneOption( - 'Select the collateral symbol to add to the VAT.', + 'Select the collateral type', getAllCollateralTypes() ); return { @@ -33,34 +37,29 @@ const simulation: Simulation = { }, }, { - title: 'Create the vault', + title: 'Create underwater vault', entry: async context => { await adjustLimitsAndRates(context.collateralType); const collateralOwned = await calculateMinCollateralAmountToOpenVault(context.collateralType); console.info(`Minimum collateral amount to open vault: ${collateralOwned.toFixed()}`); - const latestVaultId = await createVaultWithCollateral(context.collateralType, collateralOwned); + await setCollateralDebtCeilingToGlobal(context.collateralType); + const latestVaultId = await createVaultWithCollateral( + context.collateralType, + collateralOwned.multipliedBy(1) + ); console.info(`Created Vault id: ${latestVaultId}`); - return { ...context, latestVaultId }; - }, - }, - { - title: 'Skip time', - entry: async context => { + + console.info(`Skipping ${TWO_YEARS_IN_MINUTES} minutes...`); await warpTime(TWO_YEARS_IN_MINUTES, 60); - return context; - }, - }, - { - title: 'Collect stability fees', - entry: async context => { - const collateralType = context.collateralType; - const latestVaultId = context.latestVaultId; + + console.info(`Collecting stability fees...`); const vaultBefore = await fetchVault(TEST_NETWORK, latestVaultId); - console.info(`stability fees before ${vaultBefore.stabilityFeeRate}`); - await collectStabilityFees(TEST_NETWORK, collateralType); + console.info(`Stability fee before ${vaultBefore.stabilityFeeRate}`); + await collectStabilityFees(TEST_NETWORK, context.collateralType); const vaultAfter = await fetchVault(TEST_NETWORK, latestVaultId); - console.info(`stability fees after ${vaultAfter.stabilityFeeRate}`); - return context; + console.info(`Stability fee after ${vaultAfter.stabilityFeeRate}`); + + return { ...context, latestVaultId }; }, }, { @@ -79,20 +78,26 @@ const simulation: Simulation = { TEST_NETWORK, context.collateralType ); - const warpSeconds = Math.floor(auctionLifetime / 2); - if (!warpSeconds) { - throw new Error('Auction lifetime is too short to warp time.'); - } - console.info(`Skipping time: ${warpSeconds} seconds`); + const INITIAL_WARP_PARTS = 1 / 13; + const warpSeconds = Math.floor(auctionLifetime * INITIAL_WARP_PARTS); + console.info(`Initial warp of ${INITIAL_WARP_PARTS} of an auction time: ${warpSeconds} seconds`); await warpTime(warpSeconds, 1); - return context; - }, - }, - { - title: 'Add DAI and MKR to the wallet', - entry: async () => { - await addDaiToBalance(); - await addMkrToBalance(); + const provider = await getProvider(TEST_NETWORK); + const STEP_SECONDS = 30; + while (true) { + const initialAuctions = await fetchAuctionsByCollateralType(TEST_NETWORK, context.collateralType); + if (!initialAuctions[0] || !initialAuctions[0].isActive) { + console.info('No active auctions are found, exiting the "evm_mine" loop'); + break; + } + console.info(`Gradually skipping time, one block every ${STEP_SECONDS} seconds`); + try { + await provider.send('evm_mine', []); + await new Promise(resolve => setTimeout(resolve, STEP_SECONDS * 1000)); + } catch (error) { + console.error('evm_mine failed with', error); + } + } }, }, ], diff --git a/core/src/auctions.ts b/core/src/auctions.ts index 5966e3944..6bdb647f2 100644 --- a/core/src/auctions.ts +++ b/core/src/auctions.ts @@ -82,12 +82,11 @@ export const enrichMarketDataRecordsWithValues = async function ( exchangeFees: ExchangeFees, amount: BigNumber = new BigNumber(1) ): Promise> { - const exchangeFeePerUnitDAI = exchangeFees.exchangeFeeDAI.dividedBy(amount); let enrichedMarketDataRecords = {}; for (const marketId in marketDataRecords) { let marketData = marketDataRecords[marketId]; // enrich with values dependent on marketUnitPrice - let marketUnitPrice = marketData.marketUnitPrice; + const marketUnitPrice = marketData.marketUnitPrice; if (marketUnitPrice.isNaN()) { enrichedMarketDataRecords = { ...enrichedMarketDataRecords, @@ -95,7 +94,6 @@ export const enrichMarketDataRecordsWithValues = async function ( }; continue; } - marketUnitPrice = marketUnitPrice.plus(exchangeFeePerUnitDAI); marketData = { ...marketData, marketUnitPrice,