From f1c5edd6d9566d9118daeac007436f84d2586c3d Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 30 Sep 2024 12:00:57 +0200 Subject: [PATCH 01/28] add vscode settings --- .vscode/settings.json | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..7a1093c9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,70 @@ +{ + // Disable the default formatter, use eslint instead + "prettier.enable": false, + "editor.formatOnSave": false, + // Auto fix + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + // Silent the stylistic rules in you IDE, but still auto fix them + "eslint.rules.customizations": [ + { + "rule": "style/*", + "severity": "off" + }, + { + "rule": "format/*", + "severity": "off" + }, + { + "rule": "*-indent", + "severity": "off" + }, + { + "rule": "*-spacing", + "severity": "off" + }, + { + "rule": "*-spaces", + "severity": "off" + }, + { + "rule": "*-order", + "severity": "off" + }, + { + "rule": "*-dangle", + "severity": "off" + }, + { + "rule": "*-newline", + "severity": "off" + }, + { + "rule": "*quotes", + "severity": "off" + }, + { + "rule": "*semi", + "severity": "off" + } + ], + // Enable eslint for all supported languages + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "jsonc", + "yaml", + "toml", + "gql", + "graphql" + ], + "typescript.tsdk": "node_modules/typescript/lib", +} From e981f4181d0d4bd4d0e7ae1b9469b6e1de8f3132 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 30 Sep 2024 12:11:00 +0200 Subject: [PATCH 02/28] extend collateral config with contracts object to list relevant chainlog keys --- core/src/constants/COLLATERALS.ts | 280 ++++++++++++++++++++++++++++++ core/src/contracts.ts | 23 +-- core/src/params.ts | 5 +- core/src/types.ts | 9 + core/src/vaults.ts | 27 ++- 5 files changed, 317 insertions(+), 27 deletions(-) diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index f2e06032..344e821f 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -21,6 +21,13 @@ const COLLATERALS: Record = { ilk: 'AAVE-A', symbol: 'AAVE', decimals: 18, + contracts: { + token: 'AAVE', + pip: 'PIP_AAVE', + join: 'MCD_JOIN_AAVE_A', + clip: 'MCD_CLIP_AAVE_A', + calc: 'MCD_CLIP_CALC_AAVE_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -42,6 +49,13 @@ const COLLATERALS: Record = { ilk: 'BAL-A', symbol: 'BAL', decimals: 18, + contracts: { + token: 'BAL', + pip: 'PIP_BAL', + join: 'MCD_JOIN_BAL_A', + clip: 'MCD_CLIP_BAL_A', + calc: 'MCD_CLIP_CALC_BAL_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -63,6 +77,13 @@ const COLLATERALS: Record = { ilk: 'BAT-A', symbol: 'BAT', decimals: 18, + contracts: { + token: 'BAT', + pip: 'PIP_BAT', + join: 'MCD_JOIN_BAT_A', + clip: 'MCD_CLIP_BAT_A', + calc: 'MCD_CLIP_CALC_BAT_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -84,6 +105,13 @@ const COLLATERALS: Record = { ilk: 'COMP-A', symbol: 'COMP', decimals: 18, + contracts: { + token: 'COMP', + pip: 'PIP_COMP', + join: 'MCD_JOIN_COMP_A', + clip: 'MCD_CLIP_COMP_A', + calc: 'MCD_CLIP_CALC_COMP_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -105,6 +133,13 @@ const COLLATERALS: Record = { ilk: 'GNO-A', symbol: 'GNO', decimals: 18, + contracts: { + token: 'GNO', + pip: 'PIP_GNO', + join: 'MCD_JOIN_GNO_A', + clip: 'MCD_CLIP_GNO_A', + calc: 'MCD_CLIP_CALC_GNO_A', + }, exchanges: { 'Uniswap V3': { callee: 'UniswapV3Callee', @@ -122,6 +157,13 @@ const COLLATERALS: Record = { ilk: 'ETH-A', symbol: 'ETH', decimals: 18, + contracts: { + token: 'ETH', + pip: 'PIP_ETH', + join: 'MCD_JOIN_ETH_A', + clip: 'MCD_CLIP_ETH_A', + calc: 'MCD_CLIP_CALC_ETH_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -143,6 +185,13 @@ const COLLATERALS: Record = { ilk: 'ETH-B', symbol: 'ETH', decimals: 18, + contracts: { + token: 'ETH', + pip: 'PIP_ETH', + join: 'MCD_JOIN_ETH_B', + clip: 'MCD_CLIP_ETH_B', + calc: 'MCD_CLIP_CALC_ETH_B', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -164,6 +213,13 @@ const COLLATERALS: Record = { ilk: 'ETH-C', symbol: 'ETH', decimals: 18, + contracts: { + token: 'ETH', + pip: 'PIP_ETH', + join: 'MCD_JOIN_ETH_C', + clip: 'MCD_CLIP_ETH_C', + calc: 'MCD_CLIP_CALC_ETH_C', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -185,6 +241,13 @@ const COLLATERALS: Record = { ilk: 'GUSD-A', symbol: 'GUSD', decimals: 2, + contracts: { + token: 'GUSD', + pip: 'PIP_GUSD', + join: 'MCD_JOIN_GUSD_A', + clip: 'MCD_CLIP_GUSD_A', + calc: 'MCD_CLIP_CALC_GUSD_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -206,6 +269,13 @@ const COLLATERALS: Record = { ilk: 'KNC-A', symbol: 'KNC', decimals: 18, + contracts: { + token: 'KNC', + pip: 'PIP_KNC', + join: 'MCD_JOIN_KNC_A', + clip: 'MCD_CLIP_KNC_A', + calc: 'MCD_CLIP_CALC_KNC_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -227,6 +297,13 @@ const COLLATERALS: Record = { ilk: 'LINK-A', symbol: 'LINK', decimals: 18, + contracts: { + token: 'LINK', + pip: 'PIP_LINK', + join: 'MCD_JOIN_LINK_A', + clip: 'MCD_CLIP_LINK_A', + calc: 'MCD_CLIP_CALC_LINK_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -248,6 +325,13 @@ const COLLATERALS: Record = { ilk: 'LRC-A', symbol: 'LRC', decimals: 18, + contracts: { + token: 'LRC', + pip: 'PIP_LRC', + join: 'MCD_JOIN_LRC_A', + clip: 'MCD_CLIP_LRC_A', + calc: 'MCD_CLIP_CALC_LRC_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -269,6 +353,13 @@ const COLLATERALS: Record = { ilk: 'MANA-A', symbol: 'MANA', decimals: 18, + contracts: { + token: 'MANA', + pip: 'PIP_MANA', + join: 'MCD_JOIN_MANA_A', + clip: 'MCD_CLIP_MANA_A', + calc: 'MCD_CLIP_CALC_MANA_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -290,6 +381,13 @@ const COLLATERALS: Record = { ilk: 'PAXUSD-A', symbol: 'PAXUSD', decimals: 18, + contracts: { + token: 'PAXUSD', + pip: 'PIP_PAXUSD', + join: 'MCD_JOIN_PAXUSD_A', + clip: 'MCD_CLIP_PAXUSD_A', + calc: 'MCD_CLIP_CALC_PAXUSD_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -312,6 +410,13 @@ const COLLATERALS: Record = { ilk: 'RENBTC-A', symbol: 'RENBTC', decimals: 8, + contracts: { + token: 'RENBTC', + pip: 'PIP_RENBTC', + join: 'MCD_JOIN_RENBTC_A', + clip: 'MCD_CLIP_RENBTC_A', + calc: 'MCD_CLIP_CALC_RENBTC_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -333,6 +438,13 @@ const COLLATERALS: Record = { ilk: 'TUSD-A', symbol: 'TUSD', decimals: 18, + contracts: { + token: 'TUSD', + pip: 'PIP_TUSD', + join: 'MCD_JOIN_TUSD_A', + clip: 'MCD_CLIP_TUSD_A', + calc: 'MCD_CLIP_CALC_TUSD_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -354,6 +466,13 @@ const COLLATERALS: Record = { ilk: 'UNI-A', symbol: 'UNI', decimals: 18, + contracts: { + token: 'UNI', + pip: 'PIP_UNI', + join: 'MCD_JOIN_UNI_A', + clip: 'MCD_CLIP_UNI_A', + calc: 'MCD_CLIP_CALC_UNI_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -375,6 +494,13 @@ const COLLATERALS: Record = { ilk: 'USDC-A', symbol: 'USDC', decimals: 6, + contracts: { + token: 'USDC', + pip: 'PIP_USDC', + join: 'MCD_JOIN_USDC_A', + clip: 'MCD_CLIP_USDC_A', + calc: 'MCD_CLIP_CALC_USDC_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -396,6 +522,13 @@ const COLLATERALS: Record = { ilk: 'USDC-B', symbol: 'USDC', decimals: 6, + contracts: { + token: 'USDC', + pip: 'PIP_USDC', + join: 'MCD_JOIN_USDC_A', + clip: 'MCD_CLIP_USDC_B', + calc: 'MCD_CLIP_CALC_USDC_B', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -417,6 +550,13 @@ const COLLATERALS: Record = { ilk: 'USDT-A', symbol: 'USDT', decimals: 6, + contracts: { + token: 'USDT', + pip: 'PIP_USDT', + join: 'MCD_JOIN_USDT_A', + clip: 'MCD_CLIP_USDT_A', + calc: 'MCD_CLIP_CALC_USDT_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -438,6 +578,13 @@ const COLLATERALS: Record = { ilk: 'WBTC-A', symbol: 'WBTC', decimals: 8, + contracts: { + token: 'WBTC', + pip: 'PIP_WBTC', + join: 'MCD_JOIN_WBTC_A', + clip: 'MCD_CLIP_WBTC_A', + calc: 'MCD_CLIP_CALC_WBTC_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -459,6 +606,13 @@ const COLLATERALS: Record = { ilk: 'WBTC-B', symbol: 'WBTC', decimals: 8, + contracts: { + token: 'WBTC', + pip: 'PIP_WBTC', + join: 'MCD_JOIN_WBTC_B', + clip: 'MCD_CLIP_WBTC_B', + calc: 'MCD_CLIP_CALC_WBTC_B', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -480,6 +634,13 @@ const COLLATERALS: Record = { ilk: 'WBTC-C', symbol: 'WBTC', decimals: 8, + contracts: { + token: 'WBTC', + pip: 'PIP_WBTC', + join: 'MCD_JOIN_WBTC_C', + clip: 'MCD_CLIP_WBTC_C', + calc: 'MCD_CLIP_CALC_WBTC_C', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -501,6 +662,13 @@ const COLLATERALS: Record = { ilk: 'YFI-A', symbol: 'YFI', decimals: 18, + contracts: { + token: 'YFI', + pip: 'PIP_YFI', + join: 'MCD_JOIN_YFI_A', + clip: 'MCD_CLIP_YFI_A', + calc: 'MCD_CLIP_CALC_YFI_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -522,6 +690,13 @@ const COLLATERALS: Record = { ilk: 'ZRX-A', symbol: 'ZRX', decimals: 18, + contracts: { + token: 'ZRX', + pip: 'PIP_ZRX', + join: 'MCD_JOIN_ZRX_A', + clip: 'MCD_CLIP_ZRX_A', + calc: 'MCD_CLIP_CALC_ZRX_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -543,6 +718,13 @@ const COLLATERALS: Record = { ilk: 'MATIC-A', symbol: 'MATIC', decimals: 18, + contracts: { + token: 'MATIC', + pip: 'PIP_MATIC', + join: 'MCD_JOIN_MATIC_A', + clip: 'MCD_CLIP_MATIC_A', + calc: 'MCD_CLIP_CALC_MATIC_A', + }, exchanges: { 'Uniswap V3 Autorouter': { callee: 'UniswapV3Callee', @@ -564,6 +746,13 @@ const COLLATERALS: Record = { ilk: 'WSTETH-A', symbol: 'WSTETH', decimals: 18, + contracts: { + token: 'WSTETH', + pip: 'PIP_WSTETH', + join: 'MCD_JOIN_WSTETH_A', + clip: 'MCD_CLIP_WSTETH_A', + calc: 'MCD_CLIP_CALC_WSTETH_A', + }, exchanges: { 'Curve wstETH V3': { callee: 'WstETHCurveUniv3Callee', @@ -577,6 +766,13 @@ const COLLATERALS: Record = { ilk: 'WSTETH-B', symbol: 'WSTETH', decimals: 18, + contracts: { + token: 'WSTETH', + pip: 'PIP_WSTETH', + join: 'MCD_JOIN_WSTETH_B', + clip: 'MCD_CLIP_WSTETH_B', + calc: 'MCD_CLIP_CALC_WSTETH_B', + }, exchanges: { 'Curve wstETH V3': { callee: 'WstETHCurveUniv3Callee', @@ -590,6 +786,13 @@ const COLLATERALS: Record = { ilk: 'CRVV1ETHSTETH-A', symbol: 'CRVV1ETHSTETH', decimals: 18, + contracts: { + token: 'CRVV1ETHSTETH', + pip: 'PIP_CRVV1ETHSTETH', + join: 'MCD_JOIN_CRVV1ETHSTETH_A', + clip: 'MCD_CLIP_CRVV1ETHSTETH_A', + calc: 'MCD_CLIP_CALC_CRVV1ETHSTETH_A', + }, exchanges: { 'Curve Token V3': { callee: 'CurveLpTokenUniv3Callee', @@ -603,6 +806,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2DAIETH-A', symbol: 'UNIV2DAIETH', decimals: 18, + contracts: { + token: 'UNIV2DAIETH', + pip: 'PIP_UNIV2DAIETH', + join: 'MCD_JOIN_UNIV2DAIETH_A', + clip: 'MCD_CLIP_UNIV2DAIETH_A', + calc: 'MCD_CLIP_CALC_UNIV2DAIETH_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -617,6 +827,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2USDCETH-A', symbol: 'UNIV2USDCETH', decimals: 18, + contracts: { + token: 'UNIV2USDCETH', + pip: 'PIP_UNIV2USDCETH', + join: 'MCD_JOIN_UNIV2USDCETH_A', + clip: 'MCD_CLIP_UNIV2USDCETH_A', + calc: 'MCD_CLIP_CALC_UNIV2USDCETH_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -631,6 +848,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2ETHUSDT-A', symbol: 'UNIV2ETHUSDT', decimals: 18, + contracts: { + token: 'UNIV2ETHUSDT', + pip: 'PIP_UNIV2ETHUSDT', + join: 'MCD_JOIN_UNIV2ETHUSDT_A', + clip: 'MCD_CLIP_UNIV2ETHUSDT_A', + calc: 'MCD_CLIP_CALC_UNIV2ETHUSDT_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -645,6 +869,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2WBTCDAI-A', symbol: 'UNIV2WBTCDAI', decimals: 18, + contracts: { + token: 'UNIV2WBTCDAI', + pip: 'PIP_UNIV2WBTCDAI', + join: 'MCD_JOIN_UNIV2WBTCDAI_A', + clip: 'MCD_CLIP_UNIV2WBTCDAI_A', + calc: 'MCD_CLIP_CALC_UNIV2WBTCDAI_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -659,6 +890,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2WBTCETH-A', symbol: 'UNIV2WBTCETH', decimals: 18, + contracts: { + token: 'UNIV2WBTCETH', + pip: 'PIP_UNIV2WBTCETH', + join: 'MCD_JOIN_UNIV2WBTCETH_A', + clip: 'MCD_CLIP_UNIV2WBTCETH_A', + calc: 'MCD_CLIP_CALC_UNIV2WBTCETH_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -673,6 +911,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2LINKETH-A', symbol: 'UNIV2LINKETH', decimals: 18, + contracts: { + token: 'UNIV2LINKETH', + pip: 'PIP_UNIV2LINKETH', + join: 'MCD_JOIN_UNIV2LINKETH_A', + clip: 'MCD_CLIP_UNIV2LINKETH_A', + calc: 'MCD_CLIP_CALC_UNIV2LINKETH_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -687,6 +932,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2UNIETH-A', symbol: 'UNIV2UNIETH', decimals: 18, + contracts: { + token: 'UNIV2UNIETH', + pip: 'PIP_UNIV2UNIETH', + join: 'MCD_JOIN_UNIV2UNIETH_A', + clip: 'MCD_CLIP_UNIV2UNIETH_A', + calc: 'MCD_CLIP_CALC_UNIV2UNIETH_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -701,6 +953,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2AAVEETH-A', symbol: 'UNIV2AAVEETH', decimals: 18, + contracts: { + token: 'UNIV2AAVEETH', + pip: 'PIP_UNIV2AAVEETH', + join: 'MCD_JOIN_UNIV2AAVEETH_A', + clip: 'MCD_CLIP_UNIV2AAVEETH_A', + calc: 'MCD_CLIP_CALC_UNIV2AAVEETH_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -715,6 +974,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2DAIUSDT-A', symbol: 'UNIV2DAIUSDT', decimals: 18, + contracts: { + token: 'UNIV2DAIUSDT', + pip: 'PIP_UNIV2DAIUSDT', + join: 'MCD_JOIN_UNIV2DAIUSDT_A', + clip: 'MCD_CLIP_UNIV2DAIUSDT_A', + calc: 'MCD_CLIP_CALC_UNIV2DAIUSDT_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -729,6 +995,13 @@ const COLLATERALS: Record = { ilk: 'UNIV2DAIUSDC-A', symbol: 'UNIV2DAIUSDC', decimals: 18, + contracts: { + token: 'UNIV2DAIUSDC', + pip: 'PIP_UNIV2DAIUSDC', + join: 'MCD_JOIN_UNIV2DAIUSDC_A', + clip: 'MCD_CLIP_UNIV2DAIUSDC_A', + calc: 'MCD_CLIP_CALC_UNIV2DAIUSDC_A', + }, exchanges: { 'Uniswap Token V2': { callee: 'UniswapV2LpTokenCalleeDai', @@ -743,6 +1016,13 @@ const COLLATERALS: Record = { ilk: 'RETH-A', symbol: 'RETH', decimals: 18, + contracts: { + token: 'RETH', + pip: 'PIP_RETH', + join: 'MCD_JOIN_RETH_A', + clip: 'MCD_CLIP_RETH_A', + calc: 'MCD_CLIP_CALC_RETH_A', + }, exchanges: { 'Curve rETH V3': { callee: 'rETHCurveUniv3Callee', diff --git a/core/src/contracts.ts b/core/src/contracts.ts index 8f9e2e07..78172120 100644 --- a/core/src/contracts.ts +++ b/core/src/contracts.ts @@ -6,6 +6,7 @@ import getSigner from './signer'; import BigNumber from '../src/bignumber'; import { RAD_NUMBER_OF_DIGITS, RAY_NUMBER_OF_DIGITS, WAD_NUMBER_OF_DIGITS } from '../src/constants/UNITS'; import { fetchContractAddressByNetwork } from './addresses'; +import { getCollateralConfigByType } from './constants/COLLATERALS'; import MCD_DAI from './abis/MCD_DAI.json'; import MCD_VAT from './abis/MCD_VAT.json'; import MCD_JOIN_DAI from './abis/MCD_JOIN_DAI.json'; @@ -37,13 +38,13 @@ import MCD_PAUSE from './abis/MCD_PAUSE.json'; const ERC20_SYMBOL_CALL_CACHE_TIME_MS = 1000 * 60 * 60 * 24; // 1 day export const getClipperNameByCollateralType = function (collateralType: string): string { - const suffix = collateralType.toUpperCase().replace('-', '_'); - return `MCD_CLIP_${suffix}`; + const config = getCollateralConfigByType(collateralType); + return config.contracts.clip; }; -export const getJoinNameByCollateralType = function (collateralType: string): string { - const suffix = collateralType.toUpperCase().replace('-', '_'); - return `MCD_JOIN_${suffix}`; +export const getJoinNameByCollateralType = function (collateralType: string): string | undefined { + const config = getCollateralConfigByType(collateralType); + return config.contracts.join; }; export const getContractAddressByName = async function (network: string, contractName: string): Promise { @@ -101,12 +102,6 @@ const _getContract = async function (network: string, contractName: string, useS return contract; }; -export const getErc20Contract = async function (network: string, contractAddress: string, useSigner = false) { - const signerOrProvider = useSigner ? await getSigner(network) : await getProvider(network); - const contract = await new ethers.Contract(contractAddress, ERC20, signerOrProvider); - return contract; -}; - const getContract = memoizee(_getContract, { promise: true, length: 3, @@ -136,6 +131,12 @@ export const getContractValue = async function ( return new BigNumber(variableHex._hex).shiftedBy(-decimals); }; +export const getErc20Contract = async function (network: string, contractAddress: string, useSigner = false) { + const signerOrProvider = useSigner ? await getSigner(network) : await getProvider(network); + const contract = await new ethers.Contract(contractAddress, ERC20, signerOrProvider); + return contract; +}; + const _getErc20SymbolByAddress = async function (network: string, address: string): Promise { const contract = await getErc20Contract(network, address); return await contract.symbol(); diff --git a/core/src/params.ts b/core/src/params.ts index 84435060..ca2f5fb9 100644 --- a/core/src/params.ts +++ b/core/src/params.ts @@ -6,12 +6,13 @@ import getProvider from './provider'; import MCD_CLIP_CALC from './abis/MCD_CLIP_CALC.json'; import { RAY_NUMBER_OF_DIGITS } from './constants/UNITS'; import { fetchContractAddressByNetwork, getSupportedCollateralTypes } from './addresses'; +import { getCollateralConfigByType } from './constants/COLLATERALS'; const PARAMS_CACHE = 24 * 60 * 60 * 1000; const getCalcAddressByCollateralType = async function (network: string, collateralType: string): Promise { - const suffix = collateralType.replace('-', '_'); - const calcAddress = await fetchContractAddressByNetwork(network, `MCD_CLIP_CALC_${suffix}`); + const config = getCollateralConfigByType(collateralType); + const calcAddress = await fetchContractAddressByNetwork(network, config.contracts.calc); if (!calcAddress) { throw new Error(`"${collateralType}" contract is not found on the "${network}" network`); } diff --git a/core/src/types.ts b/core/src/types.ts index d6c3944f..81b8277e 100644 --- a/core/src/types.ts +++ b/core/src/types.ts @@ -148,6 +148,14 @@ export declare interface ValueSlotAddressAndOffset { offset: number; } +export declare interface CollateralAddresses { + token: string; + join: string; + pip: string; + clip: string; + calc: string; +} + export type CalleeConfig = | RegularCalleeConfig | AutoRouterCalleeConfig @@ -160,6 +168,7 @@ export declare interface CollateralConfig { decimals: number; exchanges: Record; oracle: CollateralPriceSourceConfig; + contracts: CollateralAddresses; } interface OracleConfigBase { diff --git a/core/src/vaults.ts b/core/src/vaults.ts index 6b6df377..3a44deb0 100644 --- a/core/src/vaults.ts +++ b/core/src/vaults.ts @@ -406,21 +406,20 @@ export const openVaultWithProxiedContractAndDrawDebt = async ( const proxyContract = new ethers.Contract(proxyAddress, DS_PROXY, signer); const method = getMethodSignature('openLockGemAndDraw(address,address,address,bytes32,uint256,uint256)'); const jugContractAddress = await getContractAddressByName(network, 'MCD_JUG'); - const joinContractCollateralAddress = await getContractAddressByName( - network, - getJoinNameByCollateralType(collateralType) - ); + const joinName = getJoinNameByCollateralType(collateralType); const joinContractDaiAddress = await getContractAddressByName(network, 'MCD_JOIN_DAI'); - const args = [ - jugContractAddress, - joinContractCollateralAddress, - joinContractDaiAddress, - ethers.utils.formatBytes32String(collateralType), - collateralAmount.shiftedBy(WAD_NUMBER_OF_DIGITS).toFixed(0), - debtAmountDai.shiftedBy(DAI_NUMBER_OF_DIGITS).toFixed(0), - ]; - const typesArray = ['address', 'address', 'address', 'bytes32', 'uint256', 'uint256']; - const encodedArgs = ethers.utils.defaultAbiCoder.encode(typesArray, args); + const joinContractCollateralAddress = await getContractAddressByName(network, joinName); + const encodedArgs = ethers.utils.defaultAbiCoder.encode( + ['address', 'address', 'address', 'bytes32', 'uint256', 'uint256'], + [ + jugContractAddress, + joinContractCollateralAddress, + joinContractDaiAddress, + ethers.utils.formatBytes32String(collateralType), + collateralAmount.shiftedBy(WAD_NUMBER_OF_DIGITS).toFixed(0), + debtAmountDai.shiftedBy(DAI_NUMBER_OF_DIGITS).toFixed(0), + ] + ); const transactionData = method + encodedArgs.substring(2); const target = (await getContract(network, `PROXY_ACTIONS_${proxyType}`)).address; const transaction = await proxyContract['execute(address,bytes)'](target, transactionData); From 0501b2ad5ca7d8c9d5b542beba605282b30e06e0 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 30 Sep 2024 13:52:21 +0200 Subject: [PATCH 03/28] add LOCKSTAKE collateral config + handle joinless collaterals with error --- core/simulations/configs/vaultLiquidation.ts | 2 +- .../helpers/createVaultWithCollateral.ts | 36 ++++--- core/src/constants/COLLATERALS.ts | 98 +++++++++++-------- core/src/contracts.ts | 2 +- core/src/types.ts | 2 +- core/src/vaults.ts | 51 +++++----- 6 files changed, 106 insertions(+), 85 deletions(-) diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index e93dd31e..a3b88788 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -78,7 +78,7 @@ const simulation: Simulation = { TEST_NETWORK, context.collateralType ); - const INITIAL_WARP_PARTS = 1 / 13; + const INITIAL_WARP_PARTS = 1 / 12; 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); diff --git a/core/simulations/helpers/createVaultWithCollateral.ts b/core/simulations/helpers/createVaultWithCollateral.ts index 1217e537..02622a7e 100644 --- a/core/simulations/helpers/createVaultWithCollateral.ts +++ b/core/simulations/helpers/createVaultWithCollateral.ts @@ -61,11 +61,12 @@ const setAndCheckCollateralInVat = async (collateralType: CollateralType, collat }; const checkAndWithdrawCollateralFromVat = async (collateralConfig: CollateralConfig, collateralOwned: BigNumber) => { + const joinName = getJoinNameByCollateralType(collateralConfig.ilk); + if (!joinName) { + throw new Error('checkAndWithdrawCollateralFromVat: there is no vat collateral for joinless collateral'); + } const tokenContractAddress = await getContractAddressByName(TEST_NETWORK, collateralConfig.symbol); - const addressJoin = await getContractAddressByName( - TEST_NETWORK, - getJoinNameByCollateralType(collateralConfig.ilk) - ); + const addressJoin = await getContractAddressByName(TEST_NETWORK, joinName); const joinBalance = await fetchERC20TokenBalance( TEST_NETWORK, tokenContractAddress, @@ -164,11 +165,12 @@ export const checkAvailableDebtForAmountAndMinUnitPrice = async ( }; const giveJoinContractAllowance = async (collateralConfig: CollateralConfig, amount?: BigNumber) => { + const joinName = getJoinNameByCollateralType(collateralConfig.ilk); + if (!joinName) { + throw new Error('giveJoinContractAllowance: joinless contract allowance can not be given'); + } const tokenContractAddress = await getContractAddressByName(TEST_NETWORK, collateralConfig.symbol); - const addressJoin = await getContractAddressByName( - TEST_NETWORK, - getJoinNameByCollateralType(collateralConfig.ilk) - ); + const addressJoin = await getContractAddressByName(TEST_NETWORK, joinName); const contract = await getErc20Contract(TEST_NETWORK, tokenContractAddress, true); const amountRaw = amount ? amount.shiftedBy(collateralConfig.decimals).toFixed(0) : MAX.toFixed(0); await contract.approve(addressJoin, amountRaw); @@ -209,15 +211,17 @@ const createVaultWithCollateral = async (collateralType: CollateralType, collate } await ensureWalletBalance(collateralConfig, collateralOwned); - const joinContractAddress = await getContractAddressByName( - TEST_NETWORK, - getJoinNameByCollateralType(collateralType) - ); - const proxyTarget = await detectProxyTarget(TEST_NETWORK, joinContractAddress); - if (!proxyTarget) { - return await createDefaultVaultWithCollateral(collateralType, collateralOwned); + const joinName = getJoinNameByCollateralType(collateralType); + if (joinName) { + const joinContractAddress = await getContractAddressByName(TEST_NETWORK, joinName); + const proxyTarget = await detectProxyTarget(TEST_NETWORK, joinContractAddress); + if (!proxyTarget) { + return await createDefaultVaultWithCollateral(collateralType, collateralOwned); + } + return await createProxiedVaultWithCollateral(collateralType, collateralOwned); + } else { + throw new Error('createVaultWithCollateral: joinless vault creation is not yet implemented'); } - return await createProxiedVaultWithCollateral(collateralType, collateralOwned); }; export const adjustLimitsAndRates = async (collateralType: CollateralType) => { diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index 344e821f..34bc3e9f 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -1,13 +1,13 @@ import type { CollateralConfig, OracleCurrentAndNextPrices, OracleCurrentPriceOnly } from '../types'; -export const CONFIG_WITH_NEXT_PRICE: OracleCurrentAndNextPrices = { +export const ORACLE_WITH_NEXT_PRICE: OracleCurrentAndNextPrices = { type: 'CurrentAndNextPrice', currentPriceSlotAddress: '0x3', nextPriceSlotAddress: '0x4', hasDelay: true, slotPriceValueBeginsAtPosition: 34, }; -export const CONFIG_WITHOUT_NEXT_PRICE: OracleCurrentPriceOnly = { +export const ORACLE_WITHOUT_NEXT_PRICE: OracleCurrentPriceOnly = { type: 'CurrentPriceOnly', currentPriceSlotAddress: '0x2', hasDelay: false, @@ -42,7 +42,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'BAL-A': { title: 'Balancer', @@ -70,7 +70,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'BAT-A': { title: 'Basic Attention Token', @@ -98,7 +98,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'COMP-A': { title: 'Compound', @@ -126,7 +126,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'GNO-A': { title: 'Gnosis Token', @@ -150,7 +150,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'ETH-A': { title: 'Ether', @@ -178,7 +178,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'ETH-B': { title: 'Ether', @@ -206,7 +206,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'ETH-C': { title: 'Ether', @@ -234,7 +234,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'GUSD-A': { title: 'Gemini Dollar', @@ -262,7 +262,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_NEXT_PRICE, }, 'KNC-A': { title: 'Kyber Network Crystal', @@ -290,7 +290,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'LINK-A': { title: 'Chainlink', @@ -318,7 +318,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'LRC-A': { title: 'Loopring', @@ -346,7 +346,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'MANA-A': { title: 'Decentraland', @@ -374,7 +374,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'PAXUSD-A': { title: 'Paxos Standard', @@ -403,7 +403,7 @@ const COLLATERALS: Record = { }, }, - oracle: CONFIG_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_NEXT_PRICE, }, 'RENBTC-A': { title: 'renBTC', @@ -431,7 +431,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'TUSD-A': { title: 'True USD', @@ -459,7 +459,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_NEXT_PRICE, }, 'UNI-A': { title: 'Uniswap', @@ -487,7 +487,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'USDC-A': { title: 'USD Coin', @@ -515,7 +515,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_NEXT_PRICE, }, 'USDC-B': { title: 'USD Coin', @@ -543,7 +543,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_NEXT_PRICE, }, 'USDT-A': { title: 'Tether USD', @@ -571,7 +571,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'WBTC-A': { title: 'Wrapped Bitcoin', @@ -599,7 +599,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'WBTC-B': { title: 'Wrapped BTC', @@ -627,7 +627,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'WBTC-C': { title: 'Wrapped BTC', @@ -655,7 +655,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'YFI-A': { title: 'yearn.finance', @@ -683,7 +683,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'ZRX-A': { title: '0x', @@ -711,7 +711,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'MATIC-A': { title: 'Matic', @@ -739,7 +739,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'WSTETH-A': { title: 'Lido wstETH', @@ -759,7 +759,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'WSTETH-B': { title: 'Lido wstETH', @@ -779,7 +779,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'CRVV1ETHSTETH-A': { title: 'Curve stETH', @@ -799,7 +799,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2DAIETH-A': { title: 'UNIV2DAIETH LP', @@ -820,7 +820,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2USDCETH-A': { title: 'UNIV2USDCETH LP', @@ -841,7 +841,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2ETHUSDT-A': { title: 'UNIV2ETHUSDT LP', @@ -862,7 +862,7 @@ const COLLATERALS: Record = { token1: 'USDT', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2WBTCDAI-A': { title: 'UNIV2WBTCDAI LP', @@ -883,7 +883,7 @@ const COLLATERALS: Record = { token1: 'DAI', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2WBTCETH-A': { title: 'UNIV2WBTCETH LP', @@ -904,7 +904,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2LINKETH-A': { title: 'UNIV2LINKETH LP', @@ -925,7 +925,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2UNIETH-A': { title: 'UNIV2UNIETH LP', @@ -946,7 +946,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2AAVEETH-A': { title: 'UNIV2AAVEETH LP', @@ -967,7 +967,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2DAIUSDT-A': { title: 'UNIV2DAIUSDT LP', @@ -988,7 +988,7 @@ const COLLATERALS: Record = { token1: 'USDT', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'UNIV2DAIUSDC-A': { title: 'UNIV2DAIUSDC LP', @@ -1009,7 +1009,7 @@ const COLLATERALS: Record = { token1: 'USDC', }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, }, 'RETH-A': { title: 'Rocket Pool ETH', @@ -1029,7 +1029,21 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: CONFIG_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_NEXT_PRICE, + }, + LOCKSTAKE: { + title: 'Lockstake MKR', + ilk: 'LOCKSTAKE', + symbol: 'MCD_GOV', + decimals: 18, + exchanges: {}, + oracle: ORACLE_WITH_NEXT_PRICE, + contracts: { + token: 'MCD_GOV', + pip: 'PIP_MKR', + clip: 'LOCKSTAKE_CLIP', + calc: 'LOCKSTAKE_CLIP_CALC', + }, }, }; diff --git a/core/src/contracts.ts b/core/src/contracts.ts index 78172120..1fac6b27 100644 --- a/core/src/contracts.ts +++ b/core/src/contracts.ts @@ -85,7 +85,7 @@ export const getContractInterfaceByName = async function (contractName: string): if (contractName.startsWith('MCD_CLIP_CALC_')) { return MCD_CLIP_CALC; } - if (contractName.startsWith('MCD_CLIP_')) { + if (contractName.startsWith('MCD_CLIP_') || contractName.endsWith('_CLIP')) { return MCD_CLIP; } if (contractName.startsWith('PROXY_ACTIONS_')) { diff --git a/core/src/types.ts b/core/src/types.ts index 81b8277e..13f565ef 100644 --- a/core/src/types.ts +++ b/core/src/types.ts @@ -150,7 +150,7 @@ export declare interface ValueSlotAddressAndOffset { export declare interface CollateralAddresses { token: string; - join: string; + join?: string; pip: string; clip: string; calc: string; diff --git a/core/src/vaults.ts b/core/src/vaults.ts index 3a44deb0..5fde4cc7 100644 --- a/core/src/vaults.ts +++ b/core/src/vaults.ts @@ -401,35 +401,38 @@ export const openVaultWithProxiedContractAndDrawDebt = async ( const proxyAddress = existingProxyAddress ? existingProxyAddress : await createProxyAndGiveAllowance(network, collateralType, collateralAmount); - const signer = await getSigner(network); const proxyContract = new ethers.Contract(proxyAddress, DS_PROXY, signer); const method = getMethodSignature('openLockGemAndDraw(address,address,address,bytes32,uint256,uint256)'); const jugContractAddress = await getContractAddressByName(network, 'MCD_JUG'); - const joinName = getJoinNameByCollateralType(collateralType); const joinContractDaiAddress = await getContractAddressByName(network, 'MCD_JOIN_DAI'); - const joinContractCollateralAddress = await getContractAddressByName(network, joinName); - const encodedArgs = ethers.utils.defaultAbiCoder.encode( - ['address', 'address', 'address', 'bytes32', 'uint256', 'uint256'], - [ - jugContractAddress, - joinContractCollateralAddress, - joinContractDaiAddress, - ethers.utils.formatBytes32String(collateralType), - collateralAmount.shiftedBy(WAD_NUMBER_OF_DIGITS).toFixed(0), - debtAmountDai.shiftedBy(DAI_NUMBER_OF_DIGITS).toFixed(0), - ] - ); - const transactionData = method + encodedArgs.substring(2); - const target = (await getContract(network, `PROXY_ACTIONS_${proxyType}`)).address; - const transaction = await proxyContract['execute(address,bytes)'](target, transactionData); - const events = await extractEventFromTransaction( - transaction, - 'NewCdpRegistered(address,address,uint256)', - new ethers.utils.Interface(CDP_REGISTRY) - ); - const vaultId = events[0].args.cdp.toNumber(); - return vaultId; + const joinName = getJoinNameByCollateralType(collateralType); + if (joinName) { + const joinContractCollateralAddress = await getContractAddressByName(network, joinName); + const encodedArgs = ethers.utils.defaultAbiCoder.encode( + ['address', 'address', 'address', 'bytes32', 'uint256', 'uint256'], + [ + jugContractAddress, + joinContractCollateralAddress, + joinContractDaiAddress, + ethers.utils.formatBytes32String(collateralType), + collateralAmount.shiftedBy(WAD_NUMBER_OF_DIGITS).toFixed(0), + debtAmountDai.shiftedBy(DAI_NUMBER_OF_DIGITS).toFixed(0), + ] + ); + const transactionData = method + encodedArgs.substring(2); + const target = (await getContract(network, `PROXY_ACTIONS_${proxyType}`)).address; + const transaction = await proxyContract['execute(address,bytes)'](target, transactionData); + const events = await extractEventFromTransaction( + transaction, + 'NewCdpRegistered(address,address,uint256)', + new ethers.utils.Interface(CDP_REGISTRY) + ); + const vaultId = events[0].args.cdp.toNumber(); + return vaultId; + } else { + throw new Error('openVaultWithProxiedContractAndDrawDebt: joinless vault creation is not yet implemented'); + } }; export const openVault = async (network: string, ownerAddress: string, collateralType: CollateralType) => { From 3516a7f2c02bc7a363e0961c854678cbb6ba8574 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 30 Sep 2024 18:00:23 +0200 Subject: [PATCH 04/28] working createLockstakeVaultWithCollateral --- .../helpers/createVaultWithCollateral.ts | 50 +- core/src/abis/LOCKSTAKE_ENGINE.json | 1516 +++++++++++++++++ core/src/contracts.ts | 2 + 3 files changed, 1557 insertions(+), 11 deletions(-) create mode 100644 core/src/abis/LOCKSTAKE_ENGINE.json diff --git a/core/simulations/helpers/createVaultWithCollateral.ts b/core/simulations/helpers/createVaultWithCollateral.ts index 02622a7e..5a7047aa 100644 --- a/core/simulations/helpers/createVaultWithCollateral.ts +++ b/core/simulations/helpers/createVaultWithCollateral.ts @@ -8,9 +8,10 @@ import { openVault, fetchVaultCollateralParameters, openVaultWithProxiedContractAndDrawDebt, + collectStabilityFees, } from '../../src/vaults'; import { HARDHAT_PUBLIC_KEY, TEST_NETWORK } from '../../helpers/constants'; -import { +import getContract, { getContractValue, getContractAddressByName, getErc20Contract, @@ -23,7 +24,7 @@ import { fetchCollateralInVat, withdrawCollateralFromVat, } from '../../src/wallet'; -import { MAX } from '../../src/constants/UNITS'; +import { MAX, WAD_NUMBER_OF_DIGITS } from '../../src/constants/UNITS'; import { CollateralConfig, CollateralType } from '../../src/types'; import { roundDownToFirstSignificantDecimal, roundUpToFirstSignificantDecimal } from '../../helpers/hex'; import { determineBalanceSlot, setCollateralInWallet } from '../../helpers/hardhat/erc20'; @@ -36,6 +37,7 @@ import { } from '../../helpers/hardhat/contractParametrization'; import { overwriteStabilityFeeAccumulationRate } from '../../helpers/hardhat/overwrites'; import detectProxyTarget from '../../helpers/detectProxyTarget'; +import getSigner from '../../src/signer'; const UNSUPPORTED_COLLATERAL_TYPES = [ 'GNO-A', @@ -199,6 +201,33 @@ const createDefaultVaultWithCollateral = async (collateralType: CollateralType, return vaultId; }; +const createLockstakeVaultWithCollateral = async (collateralType: CollateralType, collateralOwned: BigNumber) => { + const collateralConfig = getCollateralConfigByType(collateralType); + const walletAddress = await (await getSigner(TEST_NETWORK)).getAddress(); + const engine = await getContract(TEST_NETWORK, 'LOCKSTAKE_ENGINE', true); + const vaultIndex = 1; + const refId = 0; + + // Open engine vault + await engine.open(vaultIndex); + + // Lock + const collateralOwnedInt = collateralOwned.shiftedBy(collateralConfig.decimals).toFixed(0); + const mkr = await getContract(TEST_NETWORK, 'MCD_GOV', true); + await mkr['approve(address,uint256)'](engine.address, collateralOwnedInt); + await engine.lock(walletAddress, vaultIndex, collateralOwnedInt, refId); + + // Draw + await collectStabilityFees(TEST_NETWORK, collateralType); + const { minUnitPrice, stabilityFeeRate } = await fetchVaultCollateralParameters(TEST_NETWORK, collateralType); + const drawnDebtExact = collateralOwned.multipliedBy(minUnitPrice).dividedBy(stabilityFeeRate); + const drawnDebt = roundDownToFirstSignificantDecimal(drawnDebtExact); + const drawnDebtInt = drawnDebt.shiftedBy(WAD_NUMBER_OF_DIGITS).toFixed(0); + await engine.draw(walletAddress, vaultIndex, walletAddress, drawnDebtInt); + + return vaultIndex; +}; + const createVaultWithCollateral = async (collateralType: CollateralType, collateralOwned: BigNumber) => { const collateralConfig = getCollateralConfigByType(collateralType); const [balanceSlot, languageFormat] = await determineBalanceSlot(collateralType); @@ -212,16 +241,15 @@ const createVaultWithCollateral = async (collateralType: CollateralType, collate await ensureWalletBalance(collateralConfig, collateralOwned); const joinName = getJoinNameByCollateralType(collateralType); - if (joinName) { - const joinContractAddress = await getContractAddressByName(TEST_NETWORK, joinName); - const proxyTarget = await detectProxyTarget(TEST_NETWORK, joinContractAddress); - if (!proxyTarget) { - return await createDefaultVaultWithCollateral(collateralType, collateralOwned); - } - return await createProxiedVaultWithCollateral(collateralType, collateralOwned); - } else { - throw new Error('createVaultWithCollateral: joinless vault creation is not yet implemented'); + if (!joinName) { + return await createLockstakeVaultWithCollateral(collateralType, collateralOwned); + } + const joinContractAddress = await getContractAddressByName(TEST_NETWORK, joinName); + const proxyTarget = await detectProxyTarget(TEST_NETWORK, joinContractAddress); + if (!proxyTarget) { + return await createDefaultVaultWithCollateral(collateralType, collateralOwned); } + return await createProxiedVaultWithCollateral(collateralType, collateralOwned); }; export const adjustLimitsAndRates = async (collateralType: CollateralType) => { diff --git a/core/src/abis/LOCKSTAKE_ENGINE.json b/core/src/abis/LOCKSTAKE_ENGINE.json new file mode 100644 index 00000000..2df209ad --- /dev/null +++ b/core/src/abis/LOCKSTAKE_ENGINE.json @@ -0,0 +1,1516 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "voteDelegateFactory_", + "type": "address" + }, + { + "internalType": "address", + "name": "usdsJoin_", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "ilk_", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "mkrSky_", + "type": "address" + }, + { + "internalType": "address", + "name": "lsmkr_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "name": "AddFarm", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "name": "DelFarm", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Deny", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Draw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "data", + "type": "address" + } + ], + "name": "File", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "name": "File", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "freed", + "type": "uint256" + } + ], + "name": "Free", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "FreeNoFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "skyWad", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "skyFreed", + "type": "uint256" + } + ], + "name": "FreeSky", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "farm", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "GetReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Hope", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "ref", + "type": "uint16" + } + ], + "name": "Lock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "skyWad", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "ref", + "type": "uint16" + } + ], + "name": "LockSky", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Nope", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "urn", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "OnKick", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "urn", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sold", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "burn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "refund", + "type": "uint256" + } + ], + "name": "OnRemove", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "urn", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "OnTake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "urn", + "type": "address" + } + ], + "name": "Open", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Rely", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "farm", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "ref", + "type": "uint16" + } + ], + "name": "SelectFarm", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "voteDelegate", + "type": "address" + } + ], + "name": "SelectVoteDelegate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "Wipe", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "name": "addFarm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "name": "delFarm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "deny", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "draw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "name": "farms", + "outputs": [ + { + "internalType": "enum LockstakeEngine.FarmStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "name": "file", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "data", + "type": "address" + } + ], + "name": "file", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "free", + "outputs": [ + { + "internalType": "uint256", + "name": "freed", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "freeNoFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "skyWad", + "type": "uint256" + } + ], + "name": "freeSky", + "outputs": [ + { + "internalType": "uint256", + "name": "skyFreed", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "farm", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "getReward", + "outputs": [ + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "hope", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ilk", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "isUrnAuth", + "outputs": [ + { + "internalType": "bool", + "name": "ok", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "jug", + "outputs": [ + { + "internalType": "contract JugLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "ref", + "type": "uint16" + } + ], + "name": "lock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "skyWad", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "ref", + "type": "uint16" + } + ], + "name": "lockSky", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lsmkr", + "outputs": [ + { + "internalType": "contract GemLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mkr", + "outputs": [ + { + "internalType": "contract GemLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mkrSky", + "outputs": [ + { + "internalType": "contract MkrSkyLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mkrSkyRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "nope", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "onKick", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "sold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "left", + "type": "uint256" + } + ], + "name": "onRemove", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + }, + { + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "onTake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "open", + "outputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "ownerUrns", + "outputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ownerUrnsCount", + "outputs": [ + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "rely", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "farm", + "type": "address" + }, + { + "internalType": "uint16", + "name": "ref", + "type": "uint16" + } + ], + "name": "selectFarm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "voteDelegate", + "type": "address" + } + ], + "name": "selectVoteDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sky", + "outputs": [ + { + "internalType": "contract GemLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + } + ], + "name": "urnAuctions", + "outputs": [ + { + "internalType": "uint256", + "name": "auctionsCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + }, + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "urnCan", + "outputs": [ + { + "internalType": "uint256", + "name": "allowed", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + } + ], + "name": "urnFarms", + "outputs": [ + { + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "urnImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + } + ], + "name": "urnOwners", + "outputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "urn", + "type": "address" + } + ], + "name": "urnVoteDelegates", + "outputs": [ + { + "internalType": "address", + "name": "voteDelegate", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "usds", + "outputs": [ + { + "internalType": "contract GemLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "usdsJoin", + "outputs": [ + { + "internalType": "contract UsdsJoinLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vat", + "outputs": [ + { + "internalType": "contract VatLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voteDelegateFactory", + "outputs": [ + { + "internalType": "contract VoteDelegateFactoryLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "wards", + "outputs": [ + { + "internalType": "uint256", + "name": "allowed", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "wipe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "wipeAll", + "outputs": [ + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/core/src/contracts.ts b/core/src/contracts.ts index 1fac6b27..e679ddcf 100644 --- a/core/src/contracts.ts +++ b/core/src/contracts.ts @@ -34,6 +34,7 @@ import MCD_ADM from './abis/MCD_ADM.json'; import PROXY_FACTORY from './abis/PROXY_FACTORY.json'; import PROXY_ACTIONS from './abis/PROXY_ACTIONS.json'; import MCD_PAUSE from './abis/MCD_PAUSE.json'; +import LOCKSTAKE_ENGINE from './abis/LOCKSTAKE_ENGINE.json'; const ERC20_SYMBOL_CALL_CACHE_TIME_MS = 1000 * 60 * 60 * 24; // 1 day @@ -75,6 +76,7 @@ export const getContractInterfaceByName = async function (contractName: string): MCD_ADM, PROXY_FACTORY, MCD_PAUSE, + LOCKSTAKE_ENGINE, }; if (Object.keys(ABIs).includes(contractName)) { return ABIs[contractName]; From 07ae133cab7dac1b14dccf2beeb29becb39975df Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 1 Oct 2024 09:57:32 +0200 Subject: [PATCH 05/28] renaming --- core/src/constants/COLLATERALS.ts | 94 +++++++++++++++---------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index 34bc3e9f..2402f568 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -1,18 +1,18 @@ import type { CollateralConfig, OracleCurrentAndNextPrices, OracleCurrentPriceOnly } from '../types'; -export const ORACLE_WITH_NEXT_PRICE: OracleCurrentAndNextPrices = { +export const ORACLE_WITH_DELAY: OracleCurrentAndNextPrices = { type: 'CurrentAndNextPrice', - currentPriceSlotAddress: '0x3', - nextPriceSlotAddress: '0x4', hasDelay: true, + currentPriceSlotAddress: '0x3', slotPriceValueBeginsAtPosition: 34, + nextPriceSlotAddress: '0x4', }; -export const ORACLE_WITHOUT_NEXT_PRICE: OracleCurrentPriceOnly = { +export const ORACLE_WITHOUT_DELAY: OracleCurrentPriceOnly = { type: 'CurrentPriceOnly', - currentPriceSlotAddress: '0x2', hasDelay: false, - currentPriceValiditySlotAndOffset: { slot: '0x1', offset: 25 }, + currentPriceSlotAddress: '0x2', slotPriceValueBeginsAtPosition: 0, + currentPriceValiditySlotAndOffset: { slot: '0x1', offset: 25 }, }; const COLLATERALS: Record = { @@ -42,7 +42,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'BAL-A': { title: 'Balancer', @@ -70,7 +70,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'BAT-A': { title: 'Basic Attention Token', @@ -98,7 +98,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'COMP-A': { title: 'Compound', @@ -126,7 +126,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'GNO-A': { title: 'Gnosis Token', @@ -150,7 +150,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'ETH-A': { title: 'Ether', @@ -178,7 +178,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'ETH-B': { title: 'Ether', @@ -206,7 +206,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'ETH-C': { title: 'Ether', @@ -234,7 +234,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'GUSD-A': { title: 'Gemini Dollar', @@ -262,7 +262,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_DELAY, }, 'KNC-A': { title: 'Kyber Network Crystal', @@ -290,7 +290,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'LINK-A': { title: 'Chainlink', @@ -318,7 +318,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'LRC-A': { title: 'Loopring', @@ -346,7 +346,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'MANA-A': { title: 'Decentraland', @@ -374,7 +374,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'PAXUSD-A': { title: 'Paxos Standard', @@ -403,7 +403,7 @@ const COLLATERALS: Record = { }, }, - oracle: ORACLE_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_DELAY, }, 'RENBTC-A': { title: 'renBTC', @@ -431,7 +431,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'TUSD-A': { title: 'True USD', @@ -459,7 +459,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_DELAY, }, 'UNI-A': { title: 'Uniswap', @@ -487,7 +487,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'USDC-A': { title: 'USD Coin', @@ -515,7 +515,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_DELAY, }, 'USDC-B': { title: 'USD Coin', @@ -543,7 +543,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITHOUT_NEXT_PRICE, + oracle: ORACLE_WITHOUT_DELAY, }, 'USDT-A': { title: 'Tether USD', @@ -571,7 +571,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'WBTC-A': { title: 'Wrapped Bitcoin', @@ -599,7 +599,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'WBTC-B': { title: 'Wrapped BTC', @@ -627,7 +627,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'WBTC-C': { title: 'Wrapped BTC', @@ -655,7 +655,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'YFI-A': { title: 'yearn.finance', @@ -683,7 +683,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'ZRX-A': { title: '0x', @@ -711,7 +711,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'MATIC-A': { title: 'Matic', @@ -739,7 +739,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'WSTETH-A': { title: 'Lido wstETH', @@ -759,7 +759,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'WSTETH-B': { title: 'Lido wstETH', @@ -779,7 +779,7 @@ const COLLATERALS: Record = { route: [], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'CRVV1ETHSTETH-A': { title: 'Curve stETH', @@ -799,7 +799,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2DAIETH-A': { title: 'UNIV2DAIETH LP', @@ -820,7 +820,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2USDCETH-A': { title: 'UNIV2USDCETH LP', @@ -841,7 +841,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2ETHUSDT-A': { title: 'UNIV2ETHUSDT LP', @@ -862,7 +862,7 @@ const COLLATERALS: Record = { token1: 'USDT', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2WBTCDAI-A': { title: 'UNIV2WBTCDAI LP', @@ -883,7 +883,7 @@ const COLLATERALS: Record = { token1: 'DAI', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2WBTCETH-A': { title: 'UNIV2WBTCETH LP', @@ -904,7 +904,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2LINKETH-A': { title: 'UNIV2LINKETH LP', @@ -925,7 +925,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2UNIETH-A': { title: 'UNIV2UNIETH LP', @@ -946,7 +946,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2AAVEETH-A': { title: 'UNIV2AAVEETH LP', @@ -967,7 +967,7 @@ const COLLATERALS: Record = { token1: 'ETH', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2DAIUSDT-A': { title: 'UNIV2DAIUSDT LP', @@ -988,7 +988,7 @@ const COLLATERALS: Record = { token1: 'USDT', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'UNIV2DAIUSDC-A': { title: 'UNIV2DAIUSDC LP', @@ -1009,7 +1009,7 @@ const COLLATERALS: Record = { token1: 'USDC', }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, 'RETH-A': { title: 'Rocket Pool ETH', @@ -1029,7 +1029,7 @@ const COLLATERALS: Record = { route: ['ETH'], }, }, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, }, LOCKSTAKE: { title: 'Lockstake MKR', @@ -1037,7 +1037,7 @@ const COLLATERALS: Record = { symbol: 'MCD_GOV', decimals: 18, exchanges: {}, - oracle: ORACLE_WITH_NEXT_PRICE, + oracle: ORACLE_WITH_DELAY, contracts: { token: 'MCD_GOV', pip: 'PIP_MKR', From e0d9a6842500712fce36666238ee178a8317de1e Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 1 Oct 2024 11:23:10 +0200 Subject: [PATCH 06/28] liquidatable lockstake vault --- .../configs/onboardNewCollateral.ts | 4 +-- core/simulations/configs/vaultLiquidation.ts | 30 ++++++++++++++----- .../helpers/createVaultWithCollateral.ts | 9 ++++-- core/src/oracles.ts | 2 +- core/src/vaults.ts | 5 ++-- core/test/vault-test.ts | 2 +- 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/core/simulations/configs/onboardNewCollateral.ts b/core/simulations/configs/onboardNewCollateral.ts index b7b6bb64..deb64981 100644 --- a/core/simulations/configs/onboardNewCollateral.ts +++ b/core/simulations/configs/onboardNewCollateral.ts @@ -50,10 +50,10 @@ const simulation: Simulation = { console.info(`New ${collateralType} oracle price is ${oraclePrice.toFixed()} DAI`); // create and liquidate vault const collateralOwned = await calculateMinCollateralAmountToOpenVault(collateralType); - const vaultId = await createVaultWithCollateral(collateralType, collateralOwned); + const { vaultIndex } = await createVaultWithCollateral(collateralType, collateralOwned); await warpTime(60 * 24 * 30, 60); await collectStabilityFees(TEST_NETWORK, collateralType); - const vault = await fetchVault(TEST_NETWORK, vaultId); + const vault = await fetchVault(TEST_NETWORK, vaultIndex); await liquidateVault(TEST_NETWORK, vault.collateralType, vault.address); }, }, diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index a3b88788..206c3c74 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -14,6 +14,8 @@ import getProvider from '../../src/provider'; import fetchAuctionsByCollateralType, { fetchMaximumAuctionDurationInSeconds } from '../../src/fetch'; import { getAllCollateralTypes } from '../../src/constants/COLLATERALS'; import { setCollateralDebtCeilingToGlobal } from '../../helpers/hardhat/contractParametrization'; +// import { getCurrentOraclePriceByCollateralType } from '../../src/oracles'; +// import { overwriteCurrentOraclePrice } from '../../helpers/hardhat/overwrites'; const TWO_YEARS_IN_MINUTES = 60 * 24 * 30 * 12 * 2; @@ -43,31 +45,43 @@ const simulation: Simulation = { const collateralOwned = await calculateMinCollateralAmountToOpenVault(context.collateralType); console.info(`Minimum collateral amount to open vault: ${collateralOwned.toFixed()}`); await setCollateralDebtCeilingToGlobal(context.collateralType); - const latestVaultId = await createVaultWithCollateral( + const { vaultIndex, vaultAddress } = await createVaultWithCollateral( context.collateralType, collateralOwned.multipliedBy(1) ); - console.info(`Created Vault id: ${latestVaultId}`); + console.info(`Created Vault id: ${vaultIndex} and address ${vaultAddress}`); console.info(`Skipping ${TWO_YEARS_IN_MINUTES} minutes...`); await warpTime(TWO_YEARS_IN_MINUTES, 60); console.info(`Collecting stability fees...`); - const vaultBefore = await fetchVault(TEST_NETWORK, latestVaultId); + const vaultBefore = await fetchVault(TEST_NETWORK, vaultIndex); console.info(`Stability fee before ${vaultBefore.stabilityFeeRate}`); await collectStabilityFees(TEST_NETWORK, context.collateralType); - const vaultAfter = await fetchVault(TEST_NETWORK, latestVaultId); + const vaultAfter = await fetchVault(TEST_NETWORK, vaultIndex); console.info(`Stability fee after ${vaultAfter.stabilityFeeRate}`); - return { ...context, latestVaultId }; + // // overwrite oracle price + // const initialOraclePrice = await getCurrentOraclePriceByCollateralType( + // TEST_NETWORK, + // context.collateralType + // ); + // console.info(`Initial oracle price is ${initialOraclePrice.toFixed()} DAI`); + // await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, initialOraclePrice.div(2)); + // const newOraclePrice = await getCurrentOraclePriceByCollateralType( + // TEST_NETWORK, + // context.collateralType + // ); + // console.info(`New oracle price is ${newOraclePrice.toFixed()} DAI`); + // await collectStabilityFees(TEST_NETWORK, context.collateralType); + + return { ...context, vaultIndex, vaultAddress }; }, }, { title: 'Liquidate the vault', entry: async context => { - const liquidatedId = context.latestVaultId; - const vault = await fetchVault(TEST_NETWORK, liquidatedId); - await liquidateVault(TEST_NETWORK, vault.collateralType, vault.address); + await liquidateVault(TEST_NETWORK, context.collateralType, context.vaultAddress); return context; }, }, diff --git a/core/simulations/helpers/createVaultWithCollateral.ts b/core/simulations/helpers/createVaultWithCollateral.ts index 5a7047aa..e56c4ff9 100644 --- a/core/simulations/helpers/createVaultWithCollateral.ts +++ b/core/simulations/helpers/createVaultWithCollateral.ts @@ -198,17 +198,17 @@ const createDefaultVaultWithCollateral = async (collateralType: CollateralType, collateralOwned ); await putCollateralIntoVaultAndWithdrawDai(vaultId, roundedCollateralOwned); - return vaultId; + return { vaultIndex: vaultId, vaultAddress: vault.address }; }; const createLockstakeVaultWithCollateral = async (collateralType: CollateralType, collateralOwned: BigNumber) => { const collateralConfig = getCollateralConfigByType(collateralType); const walletAddress = await (await getSigner(TEST_NETWORK)).getAddress(); - const engine = await getContract(TEST_NETWORK, 'LOCKSTAKE_ENGINE', true); const vaultIndex = 1; const refId = 0; // Open engine vault + const engine = await getContract(TEST_NETWORK, 'LOCKSTAKE_ENGINE', true); await engine.open(vaultIndex); // Lock @@ -225,7 +225,10 @@ const createLockstakeVaultWithCollateral = async (collateralType: CollateralType const drawnDebtInt = drawnDebt.shiftedBy(WAD_NUMBER_OF_DIGITS).toFixed(0); await engine.draw(walletAddress, vaultIndex, walletAddress, drawnDebtInt); - return vaultIndex; + // Get vault address + const vaultAddress = await engine.ownerUrns(walletAddress, vaultIndex); + + return { vaultIndex, vaultAddress }; }; const createVaultWithCollateral = async (collateralType: CollateralType, collateralOwned: BigNumber) => { diff --git a/core/src/oracles.ts b/core/src/oracles.ts index 47cc7994..a4a04f6f 100644 --- a/core/src/oracles.ts +++ b/core/src/oracles.ts @@ -18,7 +18,7 @@ const CACHE_EXPIRY_MS = 60 * 1000; export const getOracleAddressByCollateralType = async function (network: string, collateralType: string) { const collateralConfig = getCollateralConfigByType(collateralType); - return await getContractAddressByName(network, `PIP_${collateralConfig.symbol}`); + return await getContractAddressByName(network, collateralConfig.contracts.pip); }; const getOraclePriceSameSlotValidity = async ( diff --git a/core/src/vaults.ts b/core/src/vaults.ts index 5fde4cc7..b21fef5b 100644 --- a/core/src/vaults.ts +++ b/core/src/vaults.ts @@ -428,8 +428,9 @@ export const openVaultWithProxiedContractAndDrawDebt = async ( 'NewCdpRegistered(address,address,uint256)', new ethers.utils.Interface(CDP_REGISTRY) ); - const vaultId = events[0].args.cdp.toNumber(); - return vaultId; + const vaultIndex = events[0].args.cdp.toNumber(); + const vault = await fetchVault(network, vaultIndex); + return { vaultIndex, vaultAddress: vault.address }; } else { throw new Error('openVaultWithProxiedContractAndDrawDebt: joinless vault creation is not yet implemented'); } diff --git a/core/test/vault-test.ts b/core/test/vault-test.ts index df9b8a6c..28354c23 100644 --- a/core/test/vault-test.ts +++ b/core/test/vault-test.ts @@ -436,7 +436,7 @@ describe(`Collateral vault simulation liquidation `, () => { } let vaultId: number; try { - vaultId = await createVaultWithCollateral(collateralType, collateralOwned); + vaultId = (await createVaultWithCollateral(collateralType, collateralOwned)).vaultIndex; } catch (e) { if (e instanceof Error && e.message === 'Could not borrow dai because debt ceiling is exceeded.') { return; From aabb872f60b6d3badedda99b3a707a9ca4b9dc81 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 1 Oct 2024 11:33:15 +0200 Subject: [PATCH 07/28] adjust isCollateralTypeSupported to the new collateral config structure --- core/src/addresses.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/addresses.ts b/core/src/addresses.ts index 50d7821a..f4be2a55 100644 --- a/core/src/addresses.ts +++ b/core/src/addresses.ts @@ -1,7 +1,7 @@ import type { Contract } from 'ethers'; import { ethers } from 'ethers'; import memoizee from 'memoizee'; -import COLLATERALS, { getAllCollateralTypes } from './constants/COLLATERALS'; +import COLLATERALS, { getAllCollateralTypes, getCollateralConfigByType } from './constants/COLLATERALS'; import getProvider from './provider'; import CHAINLOG from './abis/CHAINLOG.json'; @@ -48,8 +48,8 @@ export const isCollateralSymbolSupported = async function ( }; export const isCollateralTypeSupported = async function (network: string, collateralType: string): Promise { - const suffix = collateralType.toUpperCase().replace('-', '_'); - const clipContractName = `MCD_CLIP_${suffix}`; + const collateralConfig = getCollateralConfigByType(collateralType); + const clipContractName = collateralConfig.contracts.clip; try { const collateralAddress = await fetchContractAddressByNetwork(network, clipContractName); return !!collateralAddress; From cd3f84445a22a4f36434f39bdcdb827e9ebf3ca4 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 1 Oct 2024 17:21:31 +0200 Subject: [PATCH 08/28] add exchange callee config + update collateral config route format --- core/README.md | 2 +- core/src/calleeFunctions/helpers/pools.ts | 4 +- core/src/calleeFunctions/helpers/uniswapV2.ts | 8 +- core/src/calleeFunctions/index.ts | 2 + core/src/constants/CALLEES.ts | 1 + core/src/constants/COLLATERALS.ts | 121 +++++++++--------- core/src/types.ts | 4 +- .../collateral/MarketPriceSelection.vue | 3 +- 8 files changed, 78 insertions(+), 67 deletions(-) diff --git a/core/README.md b/core/README.md index e4ececf5..fab603bb 100644 --- a/core/README.md +++ b/core/README.md @@ -32,7 +32,7 @@ The process of adding new collaterals depends on the token type used. This is du 5. Add new exchange file to the [`calleeFunctions` folder](./src/calleeFunctions) - The file should be named using the name from `1.` - The file should export `CalleeFunctions` - - The file should be imported in the [`calleeFunctions/index.ts`](./src/calleeFunctions/index.ts) + 6. Import exchange file inside [`calleeFunctions/index.ts`](./src/calleeFunctions/index.ts) and export under `allCalleeFunctions` 3. Adding price oracle configurations for the token: 1. Get the source code of the price oracle contract: - read value `ilks(collateralType)` from [`Spot` contract](https://etherscan.io/address/0x65c79fcb50ca1594b025960e539ed7a9a6d434a3#code) via "Read Contract" tabl - and receive the address of the oracle for the specified collateral. The linked conract is responsible for updating the unit prices for collaterals. diff --git a/core/src/calleeFunctions/helpers/pools.ts b/core/src/calleeFunctions/helpers/pools.ts index 85d94832..26a6ceea 100644 --- a/core/src/calleeFunctions/helpers/pools.ts +++ b/core/src/calleeFunctions/helpers/pools.ts @@ -16,8 +16,8 @@ export const routeToPool = async ( uniswapFees?: number[] ): Promise => { const fees = uniswapFees || Array.from({ length: route.length + 2 }, () => 3000); - const fullRoute = [collateralSymbol, ...route, 'DAI']; - const routeSteps = getRouteSteps(fullRoute, fees); + collateralSymbol; + const routeSteps = getRouteSteps(route, fees); return await Promise.all( routeSteps.map(async step => ({ addresses: await Promise.all( diff --git a/core/src/calleeFunctions/helpers/uniswapV2.ts b/core/src/calleeFunctions/helpers/uniswapV2.ts index f8e3fec5..27637ab4 100644 --- a/core/src/calleeFunctions/helpers/uniswapV2.ts +++ b/core/src/calleeFunctions/helpers/uniswapV2.ts @@ -21,12 +21,14 @@ const getCalleeConfig = function (collateral: CollateralConfig, _marketId: strin // TODO: remove _marketId from the all uniswapV2 functions, since they have to always use 'Uniswap V2' config const marketData = collateral.exchanges['Uniswap V2']; const isUniswapTokenNonAutoRouted = - (marketData?.callee === 'UniswapV2CalleeDai' || marketData?.callee === 'UniswapV3Callee') && + (marketData?.callee === 'UniswapV2CalleeDai' || + marketData?.callee === 'UniswapV3Callee' || + marketData?.callee === 'UniswapV2LockstakeCallee') && !('automaticRouter' in marketData); if (isUniswapTokenNonAutoRouted) { return marketData; } - throw new Error(`"${collateral.symbol}" is not an UniSwap token`); + throw new Error(`"${collateral.symbol}" is not an Uniswap token`); }; export const getCompleteExchangePathBySymbol = function (symbol: string, marketId: string, useExchangeRoute = true) { @@ -35,7 +37,7 @@ export const getCompleteExchangePathBySymbol = function (symbol: string, marketI return ['DAI']; } const collateral = getCollateralConfigBySymbol(symbol); - return !useExchangeRoute ? [symbol, 'DAI'] : [symbol, ...getCalleeConfig(collateral, marketId).route, 'DAI']; + return !useExchangeRoute ? [symbol, 'DAI'] : getCalleeConfig(collateral, marketId).route; }; export const getUniswapRouteAddressesBySymbol = async function ( diff --git a/core/src/calleeFunctions/index.ts b/core/src/calleeFunctions/index.ts index 785e6bff..91b5180a 100644 --- a/core/src/calleeFunctions/index.ts +++ b/core/src/calleeFunctions/index.ts @@ -17,6 +17,7 @@ import CurveLpTokenUniv3Callee from './CurveLpTokenUniv3Callee'; import UniswapV3Callee from './UniswapV3Callee'; import OneInchCallee from './OneInchCallee'; import rETHCurveUniv3Callee from './rETHCurveUniv3Callee'; +import UniswapV2LockstakeCallee from './UniswapV2LockstakeCallee'; import { getCollateralConfigByType, getCollateralConfigBySymbol } from '../constants/COLLATERALS'; import { routeToPool } from './helpers/pools'; import { getOneInchMarketData } from './helpers/oneInch'; @@ -31,6 +32,7 @@ const allCalleeFunctions: Record = { UniswapV3Callee, rETHCurveUniv3Callee, OneInchCallee, + UniswapV2LockstakeCallee, }; export const getCalleeData = async function ( diff --git a/core/src/constants/CALLEES.ts b/core/src/constants/CALLEES.ts index 45303f1d..3b84310d 100644 --- a/core/src/constants/CALLEES.ts +++ b/core/src/constants/CALLEES.ts @@ -11,6 +11,7 @@ const CALLEES: Record = { UniswapV3Callee: '0xdB9C76109d102d2A1E645dCa3a7E671EBfd8e11A', rETHCurveUniv3Callee: '0x7cdAb0fE16efb1EFE89e53B141347D7F299d6610', OneInchCallee: '0x19c916CDAFB41FAdd4CEd3dCf412e0302291563A', + UniswapV2LockstakeCallee: '0xf68424845e4Af5b771356d504965A3c9257805f3', }, '0x5': { UniswapV2CalleeDai: '0x6d9139ac89ad2263f138633de20e47bcae253938', diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index 2402f568..74fd32cd 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -35,11 +35,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['AAVE', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['AAVE', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -63,11 +63,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['BAL', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['BAL', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -91,11 +91,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['BAL', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['BAL', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -119,11 +119,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['COMP', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['COMP', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -143,11 +143,11 @@ const COLLATERALS: Record = { exchanges: { 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['GNO', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['GNO', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -171,11 +171,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: [], + route: ['ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: [], + route: ['ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -199,11 +199,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: [], + route: ['ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: [], + route: ['ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -227,11 +227,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: [], + route: ['ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: [], + route: ['ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -255,11 +255,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['GUSD', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['GUSD', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITHOUT_DELAY, @@ -283,11 +283,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['KNC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['KNC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -311,11 +311,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['LINK', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['LINK', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -339,11 +339,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['LRC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['LRC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -367,11 +367,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['MANA', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['MANA', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -395,11 +395,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['PAXUSD', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['PAXUSD', 'ETH', 'DAI'], }, }, @@ -424,11 +424,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['RENBTC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['RENBTC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -452,11 +452,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['TUSD', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['TUSD', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITHOUT_DELAY, @@ -480,11 +480,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['UNI', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['UNI', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -508,11 +508,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['USDC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['USDC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITHOUT_DELAY, @@ -536,11 +536,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['USDC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['USDC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITHOUT_DELAY, @@ -564,11 +564,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['USDT', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['USDT', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -592,11 +592,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['WBTC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['WBTC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -620,11 +620,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['WBTC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['WBTC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -648,11 +648,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['WBTC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['WBTC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -676,11 +676,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['YFI', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['YFI', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -704,11 +704,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['ZRX', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['ZRX', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -732,11 +732,11 @@ const COLLATERALS: Record = { }, 'Uniswap V3': { callee: 'UniswapV3Callee', - route: ['ETH'], + route: ['MATIC', 'ETH', 'DAI'], }, 'Uniswap V2': { callee: 'UniswapV2CalleeDai', - route: ['ETH'], + route: ['MATIC', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -756,7 +756,7 @@ const COLLATERALS: Record = { exchanges: { 'Curve wstETH V3': { callee: 'WstETHCurveUniv3Callee', - route: [], + route: ['WSTETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -776,7 +776,7 @@ const COLLATERALS: Record = { exchanges: { 'Curve wstETH V3': { callee: 'WstETHCurveUniv3Callee', - route: [], + route: ['WSTETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -796,7 +796,7 @@ const COLLATERALS: Record = { exchanges: { 'Curve Token V3': { callee: 'CurveLpTokenUniv3Callee', - route: ['ETH'], + route: ['ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -1026,7 +1026,7 @@ const COLLATERALS: Record = { exchanges: { 'Curve rETH V3': { callee: 'rETHCurveUniv3Callee', - route: ['ETH'], + route: ['RETH', 'ETH', 'DAI'], }, }, oracle: ORACLE_WITH_DELAY, @@ -1036,14 +1036,19 @@ const COLLATERALS: Record = { ilk: 'LOCKSTAKE', symbol: 'MCD_GOV', decimals: 18, - exchanges: {}, - oracle: ORACLE_WITH_DELAY, contracts: { token: 'MCD_GOV', pip: 'PIP_MKR', clip: 'LOCKSTAKE_CLIP', calc: 'LOCKSTAKE_CLIP_CALC', }, + exchanges: { + 'Uniswap V2': { + callee: 'UniswapV2LockstakeCallee', + route: ['MCD_GOV', 'DAI'], + }, + }, + oracle: ORACLE_WITH_DELAY, }, }; diff --git a/core/src/types.ts b/core/src/types.ts index 13f565ef..73e824d4 100644 --- a/core/src/types.ts +++ b/core/src/types.ts @@ -84,7 +84,8 @@ export declare interface RegularCalleeConfig { | 'WstETHCurveUniv3Callee' | 'CurveLpTokenUniv3Callee' | 'UniswapV3Callee' - | 'rETHCurveUniv3Callee'; + | 'rETHCurveUniv3Callee' + | 'UniswapV2LockstakeCallee'; route: string[]; } @@ -207,6 +208,7 @@ export declare interface CalleeAddresses { UniswapV3Callee?: string; rETHCurveUniv3Callee?: string; OneInchCallee?: string; + UniswapV2LockstakeCallee?: string; } export type CalleeNames = keyof CalleeAddresses; diff --git a/frontend/components/auction/collateral/MarketPriceSelection.vue b/frontend/components/auction/collateral/MarketPriceSelection.vue index bb1f0754..65a6a38d 100644 --- a/frontend/components/auction/collateral/MarketPriceSelection.vue +++ b/frontend/components/auction/collateral/MarketPriceSelection.vue @@ -138,8 +138,7 @@ export default Vue.extend({ if (!pools || !pools?.length) { return ''; } - const fullRoute = [...pools.map(pool => pool.routes[0]), 'DAI']; - return fullRoute.join(' → '); + return pools.map(pool => pool.routes[0]).join(' → '); }, getRouteFromMarketData(marketData: MarketData) { if (!marketData) { From 0d3d9b996d16843978c33ca09721b8b25077d0c1 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 1 Oct 2024 17:21:53 +0200 Subject: [PATCH 09/28] add exchange callee config + update collateral config route format --- .../UniswapV2LockstakeCallee.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 core/src/calleeFunctions/UniswapV2LockstakeCallee.ts diff --git a/core/src/calleeFunctions/UniswapV2LockstakeCallee.ts b/core/src/calleeFunctions/UniswapV2LockstakeCallee.ts new file mode 100644 index 00000000..5dfabf97 --- /dev/null +++ b/core/src/calleeFunctions/UniswapV2LockstakeCallee.ts @@ -0,0 +1,47 @@ +import type { CalleeFunctions, CollateralConfig, Pool } from '../types'; +import { ethers } from 'ethers'; +import BigNumber from '../bignumber'; +import { getUniswapRouteAddressesBySymbol, getRegularTokenExchangeRateBySymbol } from './helpers/uniswapV2'; +import { routeToPool } from './helpers/pools'; + +const getCalleeData = async function ( + network: string, + collateral: CollateralConfig, + marketId: string, + profitAddress: string +): Promise { + const marketData = collateral.exchanges[marketId]; + if (marketData?.callee !== 'UniswapV2LockstakeCallee') { + throw new Error(`getCalleeData called with invalid collateral type "${collateral.ilk}"`); + } + const minProfit = 1; + const typesArray = ['address', 'uint256', 'address[]']; + return ethers.utils.defaultAbiCoder.encode(typesArray, [ + profitAddress, + minProfit, + await getUniswapRouteAddressesBySymbol(network, collateral.symbol, marketId), + ]); +}; + +const getMarketPrice = async function ( + network: string, + collateral: CollateralConfig, + marketId: string, + amount: BigNumber +): Promise<{ price: BigNumber; pools: Pool[] }> { + const marketData = collateral.exchanges[marketId]; + if (marketData.callee !== 'UniswapV2LockstakeCallee') { + throw new Error(`Can not get market price for the "${collateral.ilk}"`); + } + return { + price: await getRegularTokenExchangeRateBySymbol(network, collateral.symbol, marketId, amount), + pools: await routeToPool(network, marketData.route, collateral.symbol), + }; +}; + +const UniswapV2CalleeDai: CalleeFunctions = { + getCalleeData, + getMarketPrice, +}; + +export default UniswapV2CalleeDai; From 247d36bbc284244bfe8e4548fd433053dd409f78 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 1 Oct 2024 22:17:13 +0200 Subject: [PATCH 10/28] fix LSE auction start and end dates --- core/simulations/configs/vaultLiquidation.ts | 37 +- core/src/abis/LOCKSTAKE_CLIP.json | 761 +++++++++++++++++++ core/src/contracts.ts | 4 +- core/src/fetch.ts | 13 +- 4 files changed, 784 insertions(+), 31 deletions(-) create mode 100644 core/src/abis/LOCKSTAKE_CLIP.json diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index 206c3c74..97b3541f 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -1,7 +1,7 @@ import { warpTime, resetNetworkAndSetupWallet } from '../../helpers/hardhat/network'; import { addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat/balance'; import { Simulation } from '../types'; -import { collectStabilityFees, fetchVault, liquidateVault } from '../../src/vaults'; +import { collectStabilityFees, liquidateVault } from '../../src/vaults'; import { TEST_NETWORK } from '../../helpers/constants'; import createVaultWithCollateral, { adjustLimitsAndRates, @@ -14,8 +14,8 @@ import getProvider from '../../src/provider'; import fetchAuctionsByCollateralType, { fetchMaximumAuctionDurationInSeconds } from '../../src/fetch'; import { getAllCollateralTypes } from '../../src/constants/COLLATERALS'; import { setCollateralDebtCeilingToGlobal } from '../../helpers/hardhat/contractParametrization'; -// import { getCurrentOraclePriceByCollateralType } from '../../src/oracles'; -// import { overwriteCurrentOraclePrice } from '../../helpers/hardhat/overwrites'; +import { getCurrentOraclePriceByCollateralType } from '../../src/oracles'; +import { overwriteCurrentOraclePrice } from '../../helpers/hardhat/overwrites'; const TWO_YEARS_IN_MINUTES = 60 * 24 * 30 * 12 * 2; @@ -54,26 +54,19 @@ const simulation: Simulation = { console.info(`Skipping ${TWO_YEARS_IN_MINUTES} minutes...`); await warpTime(TWO_YEARS_IN_MINUTES, 60); - console.info(`Collecting stability fees...`); - const vaultBefore = await fetchVault(TEST_NETWORK, vaultIndex); - console.info(`Stability fee before ${vaultBefore.stabilityFeeRate}`); + // overwrite oracle price + const initialOraclePrice = await getCurrentOraclePriceByCollateralType( + TEST_NETWORK, + context.collateralType + ); + console.info(`Initial oracle price is ${initialOraclePrice.toFixed()} DAI`); + await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, initialOraclePrice.times(0.5)); + const newOraclePrice = await getCurrentOraclePriceByCollateralType( + TEST_NETWORK, + context.collateralType + ); + console.info(`New oracle price is ${newOraclePrice.toFixed()} DAI`); await collectStabilityFees(TEST_NETWORK, context.collateralType); - const vaultAfter = await fetchVault(TEST_NETWORK, vaultIndex); - console.info(`Stability fee after ${vaultAfter.stabilityFeeRate}`); - - // // overwrite oracle price - // const initialOraclePrice = await getCurrentOraclePriceByCollateralType( - // TEST_NETWORK, - // context.collateralType - // ); - // console.info(`Initial oracle price is ${initialOraclePrice.toFixed()} DAI`); - // await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, initialOraclePrice.div(2)); - // const newOraclePrice = await getCurrentOraclePriceByCollateralType( - // TEST_NETWORK, - // context.collateralType - // ); - // console.info(`New oracle price is ${newOraclePrice.toFixed()} DAI`); - // await collectStabilityFees(TEST_NETWORK, context.collateralType); return { ...context, vaultIndex, vaultAddress }; }, diff --git a/core/src/abis/LOCKSTAKE_CLIP.json b/core/src/abis/LOCKSTAKE_CLIP.json new file mode 100644 index 00000000..725221f2 --- /dev/null +++ b/core/src/abis/LOCKSTAKE_CLIP.json @@ -0,0 +1,761 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "vat_", + "type": "address" + }, + { + "internalType": "address", + "name": "spotter_", + "type": "address" + }, + { + "internalType": "address", + "name": "dog_", + "type": "address" + }, + { + "internalType": "address", + "name": "engine_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Deny", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "name": "File", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "data", + "type": "address" + } + ], + "name": "File", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "top", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tab", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lot", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "kpr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "coin", + "type": "uint256" + } + ], + "name": "Kick", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "top", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tab", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lot", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "kpr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "coin", + "type": "uint256" + } + ], + "name": "Redo", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Rely", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "max", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "owe", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tab", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lot", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Take", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "Yank", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "active", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "buf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "calc", + "outputs": [ + { + "internalType": "contract AbacusLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chip", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "count", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cusp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "deny", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dog", + "outputs": [ + { + "internalType": "contract DogLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "engine", + "outputs": [ + { + "internalType": "contract LockstakeEngineLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "name": "file", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "data", + "type": "address" + } + ], + "name": "file", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "getStatus", + "outputs": [ + { + "internalType": "bool", + "name": "needsRedo", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tab", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ilk", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tab", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lot", + "type": "uint256" + }, + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "address", + "name": "kpr", + "type": "address" + } + ], + "name": "kick", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "kicks", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "list", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "kpr", + "type": "address" + } + ], + "name": "redo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "rely", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "sales", + "outputs": [ + { + "internalType": "uint256", + "name": "pos", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tab", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tot", + "type": "uint256" + }, + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint96", + "name": "tic", + "type": "uint96" + }, + { + "internalType": "uint256", + "name": "top", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "spotter", + "outputs": [ + { + "internalType": "contract SpotterLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stopped", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tail", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + }, + { + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "take", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tip", + "outputs": [ + { + "internalType": "uint192", + "name": "", + "type": "uint192" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "upchost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vat", + "outputs": [ + { + "internalType": "contract VatLike", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vow", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "wards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "yank", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/core/src/contracts.ts b/core/src/contracts.ts index e679ddcf..c951d70b 100644 --- a/core/src/contracts.ts +++ b/core/src/contracts.ts @@ -35,6 +35,7 @@ import PROXY_FACTORY from './abis/PROXY_FACTORY.json'; import PROXY_ACTIONS from './abis/PROXY_ACTIONS.json'; import MCD_PAUSE from './abis/MCD_PAUSE.json'; import LOCKSTAKE_ENGINE from './abis/LOCKSTAKE_ENGINE.json'; +import LOCKSTAKE_CLIP from './abis/LOCKSTAKE_CLIP.json'; const ERC20_SYMBOL_CALL_CACHE_TIME_MS = 1000 * 60 * 60 * 24; // 1 day @@ -77,6 +78,7 @@ export const getContractInterfaceByName = async function (contractName: string): PROXY_FACTORY, MCD_PAUSE, LOCKSTAKE_ENGINE, + LOCKSTAKE_CLIP, }; if (Object.keys(ABIs).includes(contractName)) { return ABIs[contractName]; @@ -87,7 +89,7 @@ export const getContractInterfaceByName = async function (contractName: string): if (contractName.startsWith('MCD_CLIP_CALC_')) { return MCD_CLIP_CALC; } - if (contractName.startsWith('MCD_CLIP_') || contractName.endsWith('_CLIP')) { + if (contractName.startsWith('MCD_CLIP_')) { return MCD_CLIP; } if (contractName.startsWith('PROXY_ACTIONS_')) { diff --git a/core/src/fetch.ts b/core/src/fetch.ts index e7161715..8d310022 100644 --- a/core/src/fetch.ts +++ b/core/src/fetch.ts @@ -41,8 +41,8 @@ export const fetchAuctionStatus = async function ( collateralType: string, auctionIndex: number ): Promise { - const contract = await getContract(network, getClipperNameByCollateralType(collateralType)); - const statusData = await contract.getStatus(convertNumberTo32Bytes(auctionIndex)); + const clipper = await getContract(network, getClipperNameByCollateralType(collateralType)); + const statusData = await clipper.getStatus(convertNumberTo32Bytes(auctionIndex)); const unitPrice = new BigNumber(statusData.price._hex).div(RAY); const collateralAmount = new BigNumber(statusData.lot._hex).div(WAD); const debtDAI = new BigNumber(statusData.tab._hex).div(RAD); @@ -67,9 +67,6 @@ export const fetchAuctionByCollateralTypeAndAuctionIndex = async function ( if (startUnixTimestamp === 0) { throw new Error('No active auction found with this id'); } - const startTimestamp = new BigNumber(auctionData.tic._hex).times(1000).toNumber(); - const endDate = new Date(startTimestamp + maximumAuctionDurationInSeconds * 1000); - const fetchedAt = new Date(); return { network, id: `${collateralType}:${auctionIndex}`, @@ -80,12 +77,12 @@ export const fetchAuctionByCollateralTypeAndAuctionIndex = async function ( initialPrice: new BigNumber(auctionData.top._hex).div(RAY), vaultAddress: auctionData.usr, debtDAI: new BigNumber(auctionData.tab._hex).div(RAD), - startDate: new Date(startTimestamp), - endDate, + startDate: new Date(startUnixTimestamp * 1000), + endDate: new Date((startUnixTimestamp + maximumAuctionDurationInSeconds) * 1000), isActive: true, isFinished: false, isRestarting: false, - fetchedAt, + fetchedAt: new Date(), }; }; From 379a030ec7d375685b71633579c4310803142e28 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Wed, 2 Oct 2024 09:43:21 +0200 Subject: [PATCH 11/28] improve simulation --- bot/src/keepers/collateral.ts | 4 +- core/simulations/configs/specificBlockFork.ts | 2 +- core/simulations/configs/vaultLiquidation.ts | 64 +++++++++++-------- .../helpers/promptToGetBlockNumber.ts | 29 --------- core/simulations/helpers/promptToGetNumber.ts | 36 +++++++++++ core/src/vaults.ts | 8 +-- 6 files changed, 81 insertions(+), 62 deletions(-) delete mode 100644 core/simulations/helpers/promptToGetBlockNumber.ts create mode 100644 core/simulations/helpers/promptToGetNumber.ts diff --git a/bot/src/keepers/collateral.ts b/bot/src/keepers/collateral.ts index 4c32dd1a..e90bd616 100644 --- a/bot/src/keepers/collateral.ts +++ b/bot/src/keepers/collateral.ts @@ -131,8 +131,8 @@ const checkAndParticipateIfPossible = async function (network: string, auction: // 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()}`); + console.info(`DAI VAT profit from the transaction: ${postVatBalanceDai.minus(preVatBalanceDai).toFixed()}`); + console.info(`DAI ERC20 profit from the transaction: ${postErcBalanceDai.minus(preErcBalanceDai).toFixed()}`); }; const participateInAuction = async function (network: string, auction: AuctionInitialInfo) { diff --git a/core/simulations/configs/specificBlockFork.ts b/core/simulations/configs/specificBlockFork.ts index c669ae9a..a93e41fa 100644 --- a/core/simulations/configs/specificBlockFork.ts +++ b/core/simulations/configs/specificBlockFork.ts @@ -1,6 +1,6 @@ import { addDaiToBalance, addMkrToBalance } from '../../helpers/hardhat/balance'; import { warpTime, resetNetworkAndSetupWallet } from '../../helpers/hardhat/network'; -import promptToGetBlockNumber from '../helpers/promptToGetBlockNumber'; +import { promptToGetBlockNumber } from '../helpers/promptToGetNumber'; import { Simulation } from '../types'; const simulation: Simulation = { diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index 97b3541f..2f32b5ee 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -8,16 +8,15 @@ import createVaultWithCollateral, { calculateMinCollateralAmountToOpenVault, } from '../helpers/createVaultWithCollateral'; import promptToSelectOneOption from '../helpers/promptToSelectOneOption'; -import promptToGetBlockNumber from '../helpers/promptToGetBlockNumber'; +import { promptToGetNumber, promptToGetBlockNumber } from '../helpers/promptToGetNumber'; import getProvider from '../../src/provider'; - import fetchAuctionsByCollateralType, { fetchMaximumAuctionDurationInSeconds } from '../../src/fetch'; import { getAllCollateralTypes } from '../../src/constants/COLLATERALS'; import { setCollateralDebtCeilingToGlobal } from '../../helpers/hardhat/contractParametrization'; import { getCurrentOraclePriceByCollateralType } from '../../src/oracles'; import { overwriteCurrentOraclePrice } from '../../helpers/hardhat/overwrites'; - -const TWO_YEARS_IN_MINUTES = 60 * 24 * 30 * 12 * 2; +import BigNumber from 'bignumber.js'; +import { enrichAuction } from '../../src/auctions'; const simulation: Simulation = { title: 'Create collateral auction', @@ -41,6 +40,14 @@ const simulation: Simulation = { { title: 'Create underwater vault', entry: async context => { + // set oracle price + await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, new BigNumber(1000)); + const initialOraclePrice = await getCurrentOraclePriceByCollateralType( + TEST_NETWORK, + context.collateralType + ); + console.info(`Initial oracle price is ${initialOraclePrice.toFixed()} DAI`); + await adjustLimitsAndRates(context.collateralType); const collateralOwned = await calculateMinCollateralAmountToOpenVault(context.collateralType); console.info(`Minimum collateral amount to open vault: ${collateralOwned.toFixed()}`); @@ -49,16 +56,9 @@ const simulation: Simulation = { context.collateralType, collateralOwned.multipliedBy(1) ); - console.info(`Created Vault id: ${vaultIndex} and address ${vaultAddress}`); + console.info(`Created Vault with id ${vaultIndex} and address ${vaultAddress}`); - console.info(`Skipping ${TWO_YEARS_IN_MINUTES} minutes...`); - await warpTime(TWO_YEARS_IN_MINUTES, 60); - - // overwrite oracle price - const initialOraclePrice = await getCurrentOraclePriceByCollateralType( - TEST_NETWORK, - context.collateralType - ); + // drop oracle price console.info(`Initial oracle price is ${initialOraclePrice.toFixed()} DAI`); await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, initialOraclePrice.times(0.5)); const newOraclePrice = await getCurrentOraclePriceByCollateralType( @@ -68,13 +68,14 @@ const simulation: Simulation = { console.info(`New oracle price is ${newOraclePrice.toFixed()} DAI`); await collectStabilityFees(TEST_NETWORK, context.collateralType); - return { ...context, vaultIndex, vaultAddress }; + return { ...context, vaultIndex, vaultAddress, initialOraclePrice }; }, }, { title: 'Liquidate the vault', entry: async context => { await liquidateVault(TEST_NETWORK, context.collateralType, context.vaultAddress); + await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, context.initialOraclePrice); return context; }, }, @@ -85,25 +86,36 @@ const simulation: Simulation = { TEST_NETWORK, context.collateralType ); - const INITIAL_WARP_PARTS = 1 / 12; - 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); + let proposedSecondsToWarp = Math.floor(auctionLifetime / 12); const provider = await getProvider(TEST_NETWORK); - const STEP_SECONDS = 30; while (true) { + proposedSecondsToWarp = await promptToGetNumber({ + title: 'Number of seconds to warp', + initial: proposedSecondsToWarp, + max: auctionLifetime, + }); + if (proposedSecondsToWarp === 0) { + try { + await provider.send('evm_mine', []); + console.info(`Mined one block without skipping any time`); + } catch (error) { + console.error('evm_mine failed with', error); + } + } else { + await warpTime(proposedSecondsToWarp, 1); + console.info(`Skipped ${proposedSecondsToWarp} seconds`); + } const initialAuctions = await fetchAuctionsByCollateralType(TEST_NETWORK, context.collateralType); - if (!initialAuctions[0] || !initialAuctions[0].isActive) { + if (!initialAuctions[0]) { 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); + const auction = await enrichAuction(TEST_NETWORK, initialAuctions[0]); + if (!auction?.isActive) { + console.info('No active auctions are found, exiting the "evm_mine" loop'); + break; } + console.info(`One active auction is still present: ${auction.id}`); } }, }, diff --git a/core/simulations/helpers/promptToGetBlockNumber.ts b/core/simulations/helpers/promptToGetBlockNumber.ts deleted file mode 100644 index 4fc8a1dc..00000000 --- a/core/simulations/helpers/promptToGetBlockNumber.ts +++ /dev/null @@ -1,29 +0,0 @@ -import prompts from 'prompts'; - -import hre from 'hardhat'; - -interface BlockNumberPromt { - title?: string; - initial?: number; - max?: number; - min?: number; -} -const promptToGetBlockNumber = async (params?: BlockNumberPromt) => { - const title: string = params?.title || 'Block number to fork from'; - const min = params?.min || 0; - const initial = params?.initial; - const max = params?.max ?? (await hre.ethers.provider.getBlockNumber()); - const { number } = await prompts([ - { - type: 'number', - name: 'number', - message: title, - initial: initial ?? max, - min, - max, - }, - ]); - return number; -}; - -export default promptToGetBlockNumber; diff --git a/core/simulations/helpers/promptToGetNumber.ts b/core/simulations/helpers/promptToGetNumber.ts new file mode 100644 index 00000000..efdda2f8 --- /dev/null +++ b/core/simulations/helpers/promptToGetNumber.ts @@ -0,0 +1,36 @@ +import prompts from 'prompts'; + +import hre from 'hardhat'; + +interface NumberPromt { + title: string; + initial?: number; + min?: number; + max?: number; +} + +export const promptToGetNumber = async (params: NumberPromt) => { + const { number } = await prompts([ + { + type: 'number', + name: 'number', + message: params.title, + initial: params?.initial ?? 0, + min: params?.min ?? 0, + max: params?.max, + }, + ]); + if (!number) { + throw new Error('No number was provided'); + } + return number; +}; + +export const promptToGetBlockNumber = async () => { + const latestBlock = await hre.ethers.provider.getBlockNumber(); + return promptToGetNumber({ + title: 'Block number to fork from', + initial: latestBlock, + max: latestBlock, + }); +}; diff --git a/core/src/vaults.ts b/core/src/vaults.ts index b21fef5b..fea5fbe0 100644 --- a/core/src/vaults.ts +++ b/core/src/vaults.ts @@ -103,9 +103,9 @@ export const fetchVaultCollateralParameters = async ( network: string, collateralType: CollateralType ): Promise => { - const contract = await getContract(network, 'MCD_VAT'); + const vat = await getContract(network, 'MCD_VAT'); const typeHex = ethers.utils.formatBytes32String(collateralType); - const { rate, spot } = await contract.ilks(typeHex); + const { rate, spot } = await vat.ilks(typeHex); return { stabilityFeeRate: new BigNumber(rate._hex).shiftedBy(-RAY_NUMBER_OF_DIGITS), minUnitPrice: new BigNumber(spot._hex).shiftedBy(-RAY_NUMBER_OF_DIGITS), @@ -117,9 +117,9 @@ export const fetchVaultAmount = async ( collateralType: CollateralType, vaultAddress: string ): Promise => { - const contract = await getContract(network, 'MCD_VAT'); + const vat = await getContract(network, 'MCD_VAT'); const typeHex = ethers.utils.formatBytes32String(collateralType); - const { ink, art } = await contract.urns(typeHex, vaultAddress); + const { ink, art } = await vat.urns(typeHex, vaultAddress); return { initialDebtDai: new BigNumber(art._hex).shiftedBy(-DAI_NUMBER_OF_DIGITS), collateralAmount: new BigNumber(ink._hex).shiftedBy(-WAD_NUMBER_OF_DIGITS), From afc0adb797d00eab6da865814676069b84f8fddb Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Wed, 2 Oct 2024 13:17:55 +0200 Subject: [PATCH 12/28] working simulation --- core/simulations/configs/vaultLiquidation.ts | 18 +++++++++++++++--- core/src/contracts.ts | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index 2f32b5ee..b8d6d18f 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -11,12 +11,15 @@ import promptToSelectOneOption from '../helpers/promptToSelectOneOption'; import { promptToGetNumber, promptToGetBlockNumber } from '../helpers/promptToGetNumber'; import getProvider from '../../src/provider'; import fetchAuctionsByCollateralType, { fetchMaximumAuctionDurationInSeconds } from '../../src/fetch'; -import { getAllCollateralTypes } from '../../src/constants/COLLATERALS'; +import { getAllCollateralTypes, getCollateralConfigByType } from '../../src/constants/COLLATERALS'; import { setCollateralDebtCeilingToGlobal } from '../../helpers/hardhat/contractParametrization'; import { getCurrentOraclePriceByCollateralType } from '../../src/oracles'; import { overwriteCurrentOraclePrice } from '../../helpers/hardhat/overwrites'; import BigNumber from 'bignumber.js'; import { enrichAuction } from '../../src/auctions'; +import { overwriteUintValue } from '../../helpers/hardhat/slotOverwrite'; +import getContract from '../../src/contracts'; +import { RAY } from '../../src/constants/UNITS'; const simulation: Simulation = { title: 'Create collateral auction', @@ -41,7 +44,7 @@ const simulation: Simulation = { title: 'Create underwater vault', entry: async context => { // set oracle price - await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, new BigNumber(1000)); + await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, new BigNumber(10)); const initialOraclePrice = await getCurrentOraclePriceByCollateralType( TEST_NETWORK, context.collateralType @@ -74,8 +77,17 @@ const simulation: Simulation = { { title: 'Liquidate the vault', entry: async context => { + const collateralConfig = getCollateralConfigByType(context.collateralType); + try { + // overwrite calc.tau (linear auction price reduction duration) + await overwriteUintValue(collateralConfig.contracts.calc, '0x1', new BigNumber(3000)); + } catch {} + try { + // overwrite clip.buf (initial auction price multiplier) + await overwriteUintValue(collateralConfig.contracts.clip, '0x5', RAY.dividedBy(10)); + } catch {} + // liquidate await liquidateVault(TEST_NETWORK, context.collateralType, context.vaultAddress); - await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, context.initialOraclePrice); return context; }, }, diff --git a/core/src/contracts.ts b/core/src/contracts.ts index c951d70b..23d969b8 100644 --- a/core/src/contracts.ts +++ b/core/src/contracts.ts @@ -86,7 +86,7 @@ export const getContractInterfaceByName = async function (contractName: string): if (contractName.startsWith('MCD_JOIN_')) { return MCD_JOIN; } - if (contractName.startsWith('MCD_CLIP_CALC_')) { + if (contractName.startsWith('MCD_CLIP_CALC_') || contractName.endsWith('_CLIP_CALC')) { return MCD_CLIP_CALC; } if (contractName.startsWith('MCD_CLIP_')) { From 1210913f42b3b5d44ec87961ceb124609e8d072e Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Wed, 2 Oct 2024 23:08:41 +0200 Subject: [PATCH 13/28] remove overcomplicated getCollateralPriceOracleConfig --- core/README.md | 17 +-- core/package.json | 4 +- core/src/getCollateralPriceOracleConfig.ts | 160 --------------------- 3 files changed, 6 insertions(+), 175 deletions(-) delete mode 100644 core/src/getCollateralPriceOracleConfig.ts diff --git a/core/README.md b/core/README.md index fab603bb..4ed12875 100644 --- a/core/README.md +++ b/core/README.md @@ -33,18 +33,11 @@ The process of adding new collaterals depends on the token type used. This is du - The file should be named using the name from `1.` - The file should export `CalleeFunctions` 6. Import exchange file inside [`calleeFunctions/index.ts`](./src/calleeFunctions/index.ts) and export under `allCalleeFunctions` -3. Adding price oracle configurations for the token: - 1. Get the source code of the price oracle contract: - - read value `ilks(collateralType)` from [`Spot` contract](https://etherscan.io/address/0x65c79fcb50ca1594b025960e539ed7a9a6d434a3#code) via "Read Contract" tabl - and receive the address of the oracle for the specified collateral. The linked conract is responsible for updating the unit prices for collaterals. - 2. Read the contract and determine the slot address of the variable: - - Generally a slot number can be determined by counting definition of variables in the contract source code, but there are exceptions, [please read the docs on the solidity version the contract was compiled with](https://docs.soliditylang.org/en/v0.8.13/internals/layout_in_storage.html) - - Experimenting with blockchain fork (e.g. hardhat) helps: try to fetch the value you're looking for / overwrite it / ... and validate that it's correct via some public method or comparing against your expectation. See section [Overwriting values of price oracles](./README.md#overwriting-values-of-price-oracles) - 3. Extend collateral config with the proper slot addresses. - 4. If needed, add the oracle type to `types` file if the existing types are not sufficient to cover for the set of values you need. -4. Run `npm run collateral:onboard` to run the script that helps to choose the oracle config. - - when the script outputs the json with the config, add it to the `oracle` key of the collateral configuration in `COLLATERALS.ts` - - if the script terminates with an error, please submit the report to the repository at https://github.com/sidestream-tech/unified-auctions-ui via an issue so that the support could be added. - - Read more about the collateral oracle configurations at `./README.md#collateral-oracle-configs` + +3. Adding price oracle configurations for the new collateral type: + + 1. Get the source code of the price oracle contract. Read value `ilks(collateralType)` from the [`MCD_SPOT` contract](https://etherscan.io/address/0x65c79fcb50ca1594b025960e539ed7a9a6d434a3#code) via "Read Contract" tab and get the address of the oracle for the specified collateral. The linked conract is responsible for updating the unit prices for collaterals + 2. If the contract resembles OSM ([Oracle Security Module](https://github.com/makerdao/osm)) `ORACLE_WITH_DELAY` needs to be used, otherwise `ORACLE_WITHOUT_DELAY` ### Onboarding not yet deployed collateral diff --git a/core/package.json b/core/package.json index 7efdcf25..b83da092 100644 --- a/core/package.json +++ b/core/package.json @@ -12,9 +12,7 @@ "hardhat:silent": "npx hardhat node &> /dev/null", "hardhat": "npx hardhat node", "hardhat:simulations": "npx hardhat --network testnetwork --config local.hardhat.config.ts run ./simulations/index.ts", - "simulate": "npm-run-all --parallel hardhat:silent hardhat:simulations", - "collateral:validate": "npx hardhat --network testnetwork --config local.hardhat.config.ts run ./src/getCollateralPriceOracleConfig.ts", - "collateral:onboard": "npm-run-all --parallel hardhat:silent collateral:validate" + "simulate": "npm-run-all --parallel hardhat:silent hardhat:simulations" }, "engines": { "node": ">=16.0.0", diff --git a/core/src/getCollateralPriceOracleConfig.ts b/core/src/getCollateralPriceOracleConfig.ts deleted file mode 100644 index fe84ae84..00000000 --- a/core/src/getCollateralPriceOracleConfig.ts +++ /dev/null @@ -1,160 +0,0 @@ -import prompts from 'prompts'; -import { getContractAddressByName } from './contracts'; -import contractCollateralToOracleInterface from './abis/MCD_SPOT.json'; -import contractOracleInterface from './abis/OSM.json'; -import { ethers } from 'ethers'; -import BigNumber from './bignumber'; -import { HARDHAT_PUBLIC_KEY, TEST_NETWORK } from '../helpers/constants'; -import { CONFIG_WITH_NEXT_PRICE, CONFIG_WITHOUT_NEXT_PRICE } from './constants/COLLATERALS'; -import { CollateralPriceSourceConfig, CollateralType } from './types'; -import getSigner from './signer'; -import keypress from '../helpers/keypress'; -import { resetNetworkAndSetupWallet } from '../helpers/hardhat/network'; -import { generateMappingSlotAddress, overwriteUintValueInAddress } from '../helpers/hardhat/slotOverwrite'; - -const choicesYesNo = [ - { title: 'yes', value: true }, - { title: 'no', value: false }, -]; -const choicesNetwork = [{ title: 'custom', value: 'custom' }]; - -const promptCollateralType = async () => { - const { collateralType }: { collateralType: CollateralType } = await prompts([ - { - type: 'text', - name: 'collateralType', - message: 'State the collateral type. E.g. ETH-A', - choices: choicesNetwork, - }, - ]); - return collateralType; -}; - -const promptBasicInformation = async () => { - const { hasNextPrice }: { hasNextPrice: string } = await prompts([ - { - type: 'select', - name: 'hasNextPrice', - choices: choicesYesNo, - message: 'Does contract provide future price?', - }, - ]); - return { - hasNextPrice, - }; -}; - -const getOracleAddressAndContract = async (collateralType: string) => { - const signer = await getSigner(TEST_NETWORK); - const contractOracleMapAdderss = await getContractAddressByName(TEST_NETWORK, 'MCD_SPOT'); - const contractOracleMap = new ethers.Contract( - contractOracleMapAdderss, - contractCollateralToOracleInterface, - signer - ); - const address: string = (await contractOracleMap.ilks(ethers.utils.formatBytes32String(collateralType))).pip; - const contract = new ethers.Contract(address, contractOracleInterface, signer); - return { contract, address }; -}; - -const overwriteValue = async (contractAddress: string, newValue: BigNumber, slot: string) => { - await overwriteUintValueInAddress(contractAddress, slot, newValue); -}; - -const callContractFunctionOrThrow = async (contract: ethers.Contract, functionName: string, ...args: any[]) => { - try { - return await contract[functionName](...args); - } catch (e) { - throw new Error(`Failed to run the function ${functionName}: ${e}`); - } -}; - -const callFunction = async (contract: ethers.Contract, functionName: string, ...args: any[]): Promise => { - const returnedValueHex = await callContractFunctionOrThrow(contract, functionName, ...args); - return returnedValueHex; -}; - -const addToWhitelist = async (contractAddress: string, whitelistSlot: number) => { - const slotAddress = generateMappingSlotAddress(`0x${whitelistSlot.toString(16)}`, HARDHAT_PUBLIC_KEY); - await overwriteUintValueInAddress(contractAddress, slotAddress, new BigNumber(1)); -}; - -const runOverwriteStep = async ( - contract: ethers.Contract, - address: string, - functionName: string, - slot: string, - valueIndex?: number, - valueToWrite?: BigNumber -) => { - const previousValueRaw = await callFunction(contract, functionName); - const previousValue = new BigNumber(valueIndex !== undefined ? previousValueRaw[valueIndex] : previousValueRaw); - await overwriteValue(address, valueToWrite || previousValue.plus(1), slot); - const currentValueRaw = await callFunction(contract, functionName); - const currentValue = new BigNumber(valueIndex !== undefined ? currentValueRaw[valueIndex] : currentValueRaw); - const isUnchanged = previousValue.eq(currentValue); - if (isUnchanged) { - throw new Error('Slot was not specified correctly.'); - } -}; - -const validateConfigWithNextPriceIsValid = async (contract: ethers.Contract, address: string) => { - const priceValiditySlotValue = await contract.provider.getStorageAt( - address, - CONFIG_WITH_NEXT_PRICE.currentPriceSlotAddress - ); - if (priceValiditySlotValue[CONFIG_WITH_NEXT_PRICE.slotPriceValueBeginsAtPosition - 1] !== '1') { - throw new Error('Failed to discover the price validity boolean position'); - } - await runOverwriteStep(contract, address, 'peek', CONFIG_WITH_NEXT_PRICE.currentPriceSlotAddress, 0); - await runOverwriteStep(contract, address, 'peep', CONFIG_WITH_NEXT_PRICE.nextPriceSlotAddress, 0); -}; - -const validateConfigWithoutNextPriceIsValid = async (contract: ethers.Contract, address: string) => { - const valueAtSlot = await contract.provider.getStorageAt( - address, - CONFIG_WITHOUT_NEXT_PRICE.currentPriceValiditySlotAndOffset.slot - ); - if (valueAtSlot[CONFIG_WITHOUT_NEXT_PRICE.currentPriceValiditySlotAndOffset.offset] !== '1') { - throw new Error('Failed to discover the price validity boolean position'); - } - await runOverwriteStep( - contract, - address, - 'peek', - CONFIG_WITHOUT_NEXT_PRICE.currentPriceSlotAddress, - CONFIG_WITHOUT_NEXT_PRICE.slotPriceValueBeginsAtPosition - ); -}; - -const run = async () => { - await keypress('Press enter to start collateral config generation'); - console.info('Resetting network and setting the wallet up...'); - await resetNetworkAndSetupWallet(); - const basicInfo = await promptBasicInformation(); - const config: CollateralPriceSourceConfig = basicInfo.hasNextPrice - ? CONFIG_WITH_NEXT_PRICE - : CONFIG_WITHOUT_NEXT_PRICE; - console.info(`Config ${basicInfo.hasNextPrice ? 'with' : 'without'} next price is chosen.`); - const collateralType = await promptCollateralType(); - const { contract, address } = await getOracleAddressAndContract(collateralType); - console.info(`Price oracle contract address: ${address}`); - if (basicInfo.hasNextPrice) { - console.info('Whitelisting the wallet address...'); - const whitelistSlot = 5; - const whitelistFunction = 'bud'; - await addToWhitelist(address, whitelistSlot); - const isWhitelisted = await callFunction(contract, whitelistFunction, HARDHAT_PUBLIC_KEY); - if (isWhitelisted === '0x00') { - throw new Error('Failed to whitelist the wallet on the fork'); - } - } - console.info('Validating the correctness of the config...'); - if (basicInfo.hasNextPrice) { - await validateConfigWithNextPriceIsValid(contract, address); - } else { - await validateConfigWithoutNextPriceIsValid(contract, address); - } - console.info(`The config is validated: \n ${JSON.stringify(config)}`); -}; -run(); From 903823c2414cca01747e0ea9df6cadfc7b373067 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Wed, 2 Oct 2024 23:09:04 +0200 Subject: [PATCH 14/28] fix ./core build --- core/simulations/configs/vaultLiquidation.ts | 3 +-- .../src/calleeFunctions/CurveLpTokenUniv3Callee.ts | 6 +++++- core/src/calleeFunctions/OneInchCallee.ts | 6 +++++- core/src/calleeFunctions/UniswapV2CalleeDai.ts | 6 +++++- .../calleeFunctions/UniswapV2LpTokenCalleeDai.ts | 6 +++++- core/src/calleeFunctions/UniswapV3Callee.ts | 6 +++++- core/src/calleeFunctions/WstETHCurveUniv3Callee.ts | 6 +++++- core/src/calleeFunctions/rETHCurveUniv3Callee.ts | 6 +++++- core/src/wallet.ts | 14 ++++++++++---- 9 files changed, 46 insertions(+), 13 deletions(-) diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index b8d6d18f..a013896c 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -18,7 +18,6 @@ import { overwriteCurrentOraclePrice } from '../../helpers/hardhat/overwrites'; import BigNumber from 'bignumber.js'; import { enrichAuction } from '../../src/auctions'; import { overwriteUintValue } from '../../helpers/hardhat/slotOverwrite'; -import getContract from '../../src/contracts'; import { RAY } from '../../src/constants/UNITS'; const simulation: Simulation = { @@ -44,7 +43,7 @@ const simulation: Simulation = { title: 'Create underwater vault', entry: async context => { // set oracle price - await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, new BigNumber(10)); + await overwriteCurrentOraclePrice(TEST_NETWORK, context.collateralType, new BigNumber(1000)); const initialOraclePrice = await getCurrentOraclePriceByCollateralType( TEST_NETWORK, context.collateralType diff --git a/core/src/calleeFunctions/CurveLpTokenUniv3Callee.ts b/core/src/calleeFunctions/CurveLpTokenUniv3Callee.ts index 56478169..d06aa452 100644 --- a/core/src/calleeFunctions/CurveLpTokenUniv3Callee.ts +++ b/core/src/calleeFunctions/CurveLpTokenUniv3Callee.ts @@ -23,9 +23,13 @@ const getCalleeData = async function ( if (!preloadedPools) { throw new Error(`Can not encode route for the "${collateral.ilk}" without preloaded pools`); } + const joinName = getJoinNameByCollateralType(collateral.ilk); + if (!joinName) { + throw new Error(`Collateral "${collateral.ilk}" does not have join contract`); + } + const joinAdapterAddress = await getContractAddressByName(network, joinName); const route = await encodePools(network, preloadedPools); const curveData = [CURVE_POOL_ADDRESS, CURVE_COIN_INDEX]; - const joinAdapterAddress = await getContractAddressByName(network, getJoinNameByCollateralType(collateral.ilk)); const minProfit = 1; const typesArray = ['address', 'address', 'uint256', 'bytes', 'address', 'tuple(address,uint256)']; return ethers.utils.defaultAbiCoder.encode(typesArray, [ diff --git a/core/src/calleeFunctions/OneInchCallee.ts b/core/src/calleeFunctions/OneInchCallee.ts index 0aca3cde..b71c8f76 100644 --- a/core/src/calleeFunctions/OneInchCallee.ts +++ b/core/src/calleeFunctions/OneInchCallee.ts @@ -20,7 +20,11 @@ const getCalleeData = async function ( if (!oneInchParams) { throw new Error(`getCalleeData called with invalid txData`); } - const joinAdapterAddress = await getContractAddressByName(network, getJoinNameByCollateralType(collateral.ilk)); + const joinName = getJoinNameByCollateralType(collateral.ilk); + if (!joinName) { + throw new Error(`Collateral "${collateral.ilk}" does not have join contract`); + } + const joinAdapterAddress = await getContractAddressByName(network, joinName); const minProfit = 1; const typesArray = ['address', 'address', 'uint256', 'address', 'address', 'bytes']; return ethers.utils.defaultAbiCoder.encode(typesArray, [ diff --git a/core/src/calleeFunctions/UniswapV2CalleeDai.ts b/core/src/calleeFunctions/UniswapV2CalleeDai.ts index d3a22cdf..75c1e296 100644 --- a/core/src/calleeFunctions/UniswapV2CalleeDai.ts +++ b/core/src/calleeFunctions/UniswapV2CalleeDai.ts @@ -15,7 +15,11 @@ const getCalleeData = async function ( if (marketData?.callee !== 'UniswapV2CalleeDai') { throw new Error(`getCalleeData called with invalid collateral type "${collateral.ilk}"`); } - const joinAdapterAddress = await getContractAddressByName(network, getJoinNameByCollateralType(collateral.ilk)); + const joinName = getJoinNameByCollateralType(collateral.ilk); + if (!joinName) { + throw new Error(`Collateral "${collateral.ilk}" does not have join contract`); + } + const joinAdapterAddress = await getContractAddressByName(network, joinName); const minProfit = 1; const typesArray = ['address', 'address', 'uint256', 'address[]']; return ethers.utils.defaultAbiCoder.encode(typesArray, [ diff --git a/core/src/calleeFunctions/UniswapV2LpTokenCalleeDai.ts b/core/src/calleeFunctions/UniswapV2LpTokenCalleeDai.ts index d50fa30f..710b665b 100644 --- a/core/src/calleeFunctions/UniswapV2LpTokenCalleeDai.ts +++ b/core/src/calleeFunctions/UniswapV2LpTokenCalleeDai.ts @@ -20,7 +20,11 @@ const getCalleeData = async function ( if (marketData?.callee !== 'UniswapV2LpTokenCalleeDai') { throw new Error(`getCalleeData called with invalid collateral type "${collateral.ilk}"`); } - const joinAdapterAddress = await getContractAddressByName(network, getJoinNameByCollateralType(collateral.ilk)); + const joinName = getJoinNameByCollateralType(collateral.ilk); + if (!joinName) { + throw new Error(`Collateral "${collateral.ilk}" does not have join contract`); + } + const joinAdapterAddress = await getContractAddressByName(network, joinName); const minProfit = 1; const typesArray = ['address', 'address', 'uint256', 'address[]', 'address[]']; return ethers.utils.defaultAbiCoder.encode(typesArray, [ diff --git a/core/src/calleeFunctions/UniswapV3Callee.ts b/core/src/calleeFunctions/UniswapV3Callee.ts index 9d292873..21a16b81 100644 --- a/core/src/calleeFunctions/UniswapV3Callee.ts +++ b/core/src/calleeFunctions/UniswapV3Callee.ts @@ -18,12 +18,16 @@ const getCalleeData = async function ( if (marketData?.callee !== 'UniswapV3Callee') { throw new Error(`getCalleeData called with invalid collateral type "${collateral.ilk}"`); } + const joinName = getJoinNameByCollateralType(collateral.ilk); + if (!joinName) { + throw new Error(`collateral "${collateral.ilk}" does not have join contract`); + } const preloadedPools = !!params && 'pools' in params ? params.pools : undefined; const pools = preloadedPools || (await getPools(network, collateral, marketId)); if (!pools) { throw new Error(`getCalleeData called with invalid pools`); } - const joinAdapterAddress = await getContractAddressByName(network, getJoinNameByCollateralType(collateral.ilk)); + const joinAdapterAddress = await getContractAddressByName(network, joinName); const minProfit = 1; const uniswapV3pools = await encodePools(network, pools); const typesArray = ['address', 'address', 'uint256', 'bytes', 'address']; diff --git a/core/src/calleeFunctions/WstETHCurveUniv3Callee.ts b/core/src/calleeFunctions/WstETHCurveUniv3Callee.ts index 7b81d006..c3c42dbf 100644 --- a/core/src/calleeFunctions/WstETHCurveUniv3Callee.ts +++ b/core/src/calleeFunctions/WstETHCurveUniv3Callee.ts @@ -13,7 +13,11 @@ const getCalleeData = async function ( _marketId: string, profitAddress: string ): Promise { - const joinAdapterAddress = await getContractAddressByName(network, getJoinNameByCollateralType(collateral.ilk)); + const joinName = getJoinNameByCollateralType(collateral.ilk); + if (!joinName) { + throw new Error(`Collateral "${collateral.ilk}" does not have join contract`); + } + const joinAdapterAddress = await getContractAddressByName(network, joinName); const minProfit = 1; const typesArray = ['address', 'address', 'uint256', 'uint24', 'address']; return ethers.utils.defaultAbiCoder.encode(typesArray, [ diff --git a/core/src/calleeFunctions/rETHCurveUniv3Callee.ts b/core/src/calleeFunctions/rETHCurveUniv3Callee.ts index 9f7d0e5f..9094b2d7 100644 --- a/core/src/calleeFunctions/rETHCurveUniv3Callee.ts +++ b/core/src/calleeFunctions/rETHCurveUniv3Callee.ts @@ -24,8 +24,12 @@ const getCalleeData = async function ( if (!preloadedPools) { throw new Error(`Can not encode route for the "${collateral.ilk}" without preloaded pools`); } + const joinName = getJoinNameByCollateralType(collateral.ilk); + if (!joinName) { + throw new Error(`Collateral "${collateral.ilk}" does not have join contract`); + } const route = await encodePools(network, preloadedPools.slice(1)); - const joinAdapterAddress = await getContractAddressByName(network, getJoinNameByCollateralType(collateral.ilk)); + const joinAdapterAddress = await getContractAddressByName(network, joinName); const minProfit = 1; const typesArray = ['address', 'address', 'uint256', 'bytes', 'address']; return ethers.utils.defaultAbiCoder.encode(typesArray, [ diff --git a/core/src/wallet.ts b/core/src/wallet.ts index 101bb184..4b33bd13 100644 --- a/core/src/wallet.ts +++ b/core/src/wallet.ts @@ -103,8 +103,11 @@ export const withdrawCollateralFromVat = async function ( const withdrawalAmount = amount || (await fetchCollateralVatBalance(network, walletAddress, collateralType)); const decimals = COLLATERALS[collateralType].decimals; const withdrawalAmountRounded = withdrawalAmount.shiftedBy(decimals).toFixed(0, BigNumber.ROUND_DOWN); - const contractName = getJoinNameByCollateralType(collateralType); - await executeTransaction(network, contractName, 'exit', [walletAddress, withdrawalAmountRounded], { + const joinName = getJoinNameByCollateralType(collateralType); + if (!joinName) { + throw new Error(`Collateral "${collateralType}" does not store tokens inside vat`); + } + await executeTransaction(network, joinName, 'exit', [walletAddress, withdrawalAmountRounded], { notifier, confirmTransaction: true, }); @@ -120,8 +123,11 @@ export const depositCollateralToVat = async function ( console.info(`Deposit ${amount.toFixed(2)} ${collateralType} to the VAT`); const collateralConfig = getCollateralConfigByType(collateralType); const depositRounded = amount.shiftedBy(collateralConfig.decimals).toFixed(0, BigNumber.ROUND_DOWN); - const contractName = getJoinNameByCollateralType(collateralType); - await executeTransaction(network, contractName, 'join', [walletAddress, depositRounded], { + const joinName = getJoinNameByCollateralType(collateralType); + if (!joinName) { + throw new Error(`Collateral "${collateralType}" can not deposit tokens into vat`); + } + await executeTransaction(network, joinName, 'join', [walletAddress, depositRounded], { notifier, confirmTransaction: true, }); From d28ceaea22f6af01f9c77567c10c30c784cb3b8c Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 14:09:31 +0200 Subject: [PATCH 15/28] add additional collateral property called tokenName to be able to display MKR instead of MCD_GOV --- core/src/constants/COLLATERALS.ts | 41 +++++++++++++++++++ core/src/fetch.ts | 4 +- core/src/types.ts | 2 + .../auction/collateral/CollateralAuction.vue | 23 +++++------ .../CollateralAuctionSwapTransactionTable.vue | 4 +- .../collateral/CollateralAuctionsTable.vue | 6 +-- .../collateral/MarketPriceSelection.vue | 4 +- .../components/dashboard/CollateralTable.vue | 6 +-- .../modals/ManageCollateralTable.vue | 2 +- .../panels/WithdrawCollateralPanel.vue | 2 +- frontend/helpers/generateFakeAuction.ts | 1 + 11 files changed, 69 insertions(+), 26 deletions(-) diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index 74fd32cd..a242deff 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -20,6 +20,7 @@ const COLLATERALS: Record = { title: 'AAVE', ilk: 'AAVE-A', symbol: 'AAVE', + tokenName: 'AAVE', decimals: 18, contracts: { token: 'AAVE', @@ -48,6 +49,7 @@ const COLLATERALS: Record = { title: 'Balancer', ilk: 'BAL-A', symbol: 'BAL', + tokenName: 'BAL', decimals: 18, contracts: { token: 'BAL', @@ -76,6 +78,7 @@ const COLLATERALS: Record = { title: 'Basic Attention Token', ilk: 'BAT-A', symbol: 'BAT', + tokenName: 'BAT', decimals: 18, contracts: { token: 'BAT', @@ -104,6 +107,7 @@ const COLLATERALS: Record = { title: 'Compound', ilk: 'COMP-A', symbol: 'COMP', + tokenName: 'COMP', decimals: 18, contracts: { token: 'COMP', @@ -132,6 +136,7 @@ const COLLATERALS: Record = { title: 'Gnosis Token', ilk: 'GNO-A', symbol: 'GNO', + tokenName: 'GNO', decimals: 18, contracts: { token: 'GNO', @@ -156,6 +161,7 @@ const COLLATERALS: Record = { title: 'Ether', ilk: 'ETH-A', symbol: 'ETH', + tokenName: 'ETH', decimals: 18, contracts: { token: 'ETH', @@ -184,6 +190,7 @@ const COLLATERALS: Record = { title: 'Ether', ilk: 'ETH-B', symbol: 'ETH', + tokenName: 'ETH', decimals: 18, contracts: { token: 'ETH', @@ -212,6 +219,7 @@ const COLLATERALS: Record = { title: 'Ether', ilk: 'ETH-C', symbol: 'ETH', + tokenName: 'ETH', decimals: 18, contracts: { token: 'ETH', @@ -240,6 +248,7 @@ const COLLATERALS: Record = { title: 'Gemini Dollar', ilk: 'GUSD-A', symbol: 'GUSD', + tokenName: 'GUSD', decimals: 2, contracts: { token: 'GUSD', @@ -268,6 +277,7 @@ const COLLATERALS: Record = { title: 'Kyber Network Crystal', ilk: 'KNC-A', symbol: 'KNC', + tokenName: 'KNC', decimals: 18, contracts: { token: 'KNC', @@ -296,6 +306,7 @@ const COLLATERALS: Record = { title: 'Chainlink', ilk: 'LINK-A', symbol: 'LINK', + tokenName: 'LINK', decimals: 18, contracts: { token: 'LINK', @@ -324,6 +335,7 @@ const COLLATERALS: Record = { title: 'Loopring', ilk: 'LRC-A', symbol: 'LRC', + tokenName: 'LRC', decimals: 18, contracts: { token: 'LRC', @@ -352,6 +364,7 @@ const COLLATERALS: Record = { title: 'Decentraland', ilk: 'MANA-A', symbol: 'MANA', + tokenName: 'MANA', decimals: 18, contracts: { token: 'MANA', @@ -380,6 +393,7 @@ const COLLATERALS: Record = { title: 'Paxos Standard', ilk: 'PAXUSD-A', symbol: 'PAXUSD', + tokenName: 'PAXUSD', decimals: 18, contracts: { token: 'PAXUSD', @@ -409,6 +423,7 @@ const COLLATERALS: Record = { title: 'renBTC', ilk: 'RENBTC-A', symbol: 'RENBTC', + tokenName: 'RENBTC', decimals: 8, contracts: { token: 'RENBTC', @@ -437,6 +452,7 @@ const COLLATERALS: Record = { title: 'True USD', ilk: 'TUSD-A', symbol: 'TUSD', + tokenName: 'TUSD', decimals: 18, contracts: { token: 'TUSD', @@ -465,6 +481,7 @@ const COLLATERALS: Record = { title: 'Uniswap', ilk: 'UNI-A', symbol: 'UNI', + tokenName: 'UNI', decimals: 18, contracts: { token: 'UNI', @@ -493,6 +510,7 @@ const COLLATERALS: Record = { title: 'USD Coin', ilk: 'USDC-A', symbol: 'USDC', + tokenName: 'USDC', decimals: 6, contracts: { token: 'USDC', @@ -521,6 +539,7 @@ const COLLATERALS: Record = { title: 'USD Coin', ilk: 'USDC-B', symbol: 'USDC', + tokenName: 'USDC', decimals: 6, contracts: { token: 'USDC', @@ -549,6 +568,7 @@ const COLLATERALS: Record = { title: 'Tether USD', ilk: 'USDT-A', symbol: 'USDT', + tokenName: 'USDT', decimals: 6, contracts: { token: 'USDT', @@ -577,6 +597,7 @@ const COLLATERALS: Record = { title: 'Wrapped Bitcoin', ilk: 'WBTC-A', symbol: 'WBTC', + tokenName: 'WBTC', decimals: 8, contracts: { token: 'WBTC', @@ -605,6 +626,7 @@ const COLLATERALS: Record = { title: 'Wrapped BTC', ilk: 'WBTC-B', symbol: 'WBTC', + tokenName: 'WBTC', decimals: 8, contracts: { token: 'WBTC', @@ -633,6 +655,7 @@ const COLLATERALS: Record = { title: 'Wrapped BTC', ilk: 'WBTC-C', symbol: 'WBTC', + tokenName: 'WBTC', decimals: 8, contracts: { token: 'WBTC', @@ -661,6 +684,7 @@ const COLLATERALS: Record = { title: 'yearn.finance', ilk: 'YFI-A', symbol: 'YFI', + tokenName: 'YFI', decimals: 18, contracts: { token: 'YFI', @@ -689,6 +713,7 @@ const COLLATERALS: Record = { title: '0x', ilk: 'ZRX-A', symbol: 'ZRX', + tokenName: 'ZRX', decimals: 18, contracts: { token: 'ZRX', @@ -717,6 +742,7 @@ const COLLATERALS: Record = { title: 'Matic', ilk: 'MATIC-A', symbol: 'MATIC', + tokenName: 'MATIC', decimals: 18, contracts: { token: 'MATIC', @@ -745,6 +771,7 @@ const COLLATERALS: Record = { title: 'Lido wstETH', ilk: 'WSTETH-A', symbol: 'WSTETH', + tokenName: 'WSTETH', decimals: 18, contracts: { token: 'WSTETH', @@ -765,6 +792,7 @@ const COLLATERALS: Record = { title: 'Lido wstETH', ilk: 'WSTETH-B', symbol: 'WSTETH', + tokenName: 'WSTETH', decimals: 18, contracts: { token: 'WSTETH', @@ -785,6 +813,7 @@ const COLLATERALS: Record = { title: 'Curve stETH', ilk: 'CRVV1ETHSTETH-A', symbol: 'CRVV1ETHSTETH', + tokenName: 'CRVV1ETHSTETH', decimals: 18, contracts: { token: 'CRVV1ETHSTETH', @@ -805,6 +834,7 @@ const COLLATERALS: Record = { title: 'UNIV2DAIETH LP', ilk: 'UNIV2DAIETH-A', symbol: 'UNIV2DAIETH', + tokenName: 'UNIV2DAIETH', decimals: 18, contracts: { token: 'UNIV2DAIETH', @@ -826,6 +856,7 @@ const COLLATERALS: Record = { title: 'UNIV2USDCETH LP', ilk: 'UNIV2USDCETH-A', symbol: 'UNIV2USDCETH', + tokenName: 'UNIV2USDCETH', decimals: 18, contracts: { token: 'UNIV2USDCETH', @@ -847,6 +878,7 @@ const COLLATERALS: Record = { title: 'UNIV2ETHUSDT LP', ilk: 'UNIV2ETHUSDT-A', symbol: 'UNIV2ETHUSDT', + tokenName: 'UNIV2ETHUSDT', decimals: 18, contracts: { token: 'UNIV2ETHUSDT', @@ -868,6 +900,7 @@ const COLLATERALS: Record = { title: 'UNIV2WBTCDAI LP', ilk: 'UNIV2WBTCDAI-A', symbol: 'UNIV2WBTCDAI', + tokenName: 'UNIV2WBTCDAI', decimals: 18, contracts: { token: 'UNIV2WBTCDAI', @@ -889,6 +922,7 @@ const COLLATERALS: Record = { title: 'UNIV2WBTCETH LP', ilk: 'UNIV2WBTCETH-A', symbol: 'UNIV2WBTCETH', + tokenName: 'UNIV2WBTCETH', decimals: 18, contracts: { token: 'UNIV2WBTCETH', @@ -910,6 +944,7 @@ const COLLATERALS: Record = { title: 'UNIV2LINKETH LP', ilk: 'UNIV2LINKETH-A', symbol: 'UNIV2LINKETH', + tokenName: 'UNIV2LINKETH', decimals: 18, contracts: { token: 'UNIV2LINKETH', @@ -931,6 +966,7 @@ const COLLATERALS: Record = { title: 'UNIV2UNIETH LP', ilk: 'UNIV2UNIETH-A', symbol: 'UNIV2UNIETH', + tokenName: 'UNIV2UNIETH', decimals: 18, contracts: { token: 'UNIV2UNIETH', @@ -952,6 +988,7 @@ const COLLATERALS: Record = { title: 'UNIV2AAVEETH LP', ilk: 'UNIV2AAVEETH-A', symbol: 'UNIV2AAVEETH', + tokenName: 'UNIV2AAVEETH', decimals: 18, contracts: { token: 'UNIV2AAVEETH', @@ -973,6 +1010,7 @@ const COLLATERALS: Record = { title: 'UNIV2DAIUSDT LP', ilk: 'UNIV2DAIUSDT-A', symbol: 'UNIV2DAIUSDT', + tokenName: 'UNIV2DAIUSDT', decimals: 18, contracts: { token: 'UNIV2DAIUSDT', @@ -994,6 +1032,7 @@ const COLLATERALS: Record = { title: 'UNIV2DAIUSDC LP', ilk: 'UNIV2DAIUSDC-A', symbol: 'UNIV2DAIUSDC', + tokenName: 'UNIV2DAIUSDC', decimals: 18, contracts: { token: 'UNIV2DAIUSDC', @@ -1015,6 +1054,7 @@ const COLLATERALS: Record = { title: 'Rocket Pool ETH', ilk: 'RETH-A', symbol: 'RETH', + tokenName: 'RETH', decimals: 18, contracts: { token: 'RETH', @@ -1035,6 +1075,7 @@ const COLLATERALS: Record = { title: 'Lockstake MKR', ilk: 'LOCKSTAKE', symbol: 'MCD_GOV', + tokenName: 'MKR', decimals: 18, contracts: { token: 'MCD_GOV', diff --git a/core/src/fetch.ts b/core/src/fetch.ts index 8d310022..20ebb5aa 100644 --- a/core/src/fetch.ts +++ b/core/src/fetch.ts @@ -64,6 +64,7 @@ export const fetchAuctionByCollateralTypeAndAuctionIndex = async function ( const contract = await getContract(network, getClipperNameByCollateralType(collateralType)); const auctionData = await contract.sales(auctionIndex); const startUnixTimestamp = new BigNumber(auctionData.tic._hex).toNumber(); + const collateralConfig = getCollateralConfigByType(collateralType); if (startUnixTimestamp === 0) { throw new Error('No active auction found with this id'); } @@ -72,7 +73,8 @@ export const fetchAuctionByCollateralTypeAndAuctionIndex = async function ( id: `${collateralType}:${auctionIndex}`, index: auctionIndex, collateralType, - collateralSymbol: getCollateralConfigByType(collateralType).symbol, + collateralSymbol: collateralConfig.symbol, + tokenName: collateralConfig.tokenName, collateralAmount: new BigNumber(auctionData.lot._hex).div(WAD), initialPrice: new BigNumber(auctionData.top._hex).div(RAY), vaultAddress: auctionData.usr, diff --git a/core/src/types.ts b/core/src/types.ts index 73e824d4..cfabb073 100644 --- a/core/src/types.ts +++ b/core/src/types.ts @@ -12,6 +12,7 @@ export declare interface AuctionInitialInfo { index: number; collateralType: string; collateralSymbol: string; + tokenName: string; collateralAmount: BigNumber; debtDAI: BigNumber; startDate: Date; @@ -166,6 +167,7 @@ export declare interface CollateralConfig { title: string; ilk: string; symbol: string; + tokenName: string; decimals: number; exchanges: Record; oracle: CollateralPriceSourceConfig; diff --git a/frontend/components/auction/collateral/CollateralAuction.vue b/frontend/components/auction/collateral/CollateralAuction.vue index a69f24c7..5392e2ca 100644 --- a/frontend/components/auction/collateral/CollateralAuction.vue +++ b/frontend/components/auction/collateral/CollateralAuction.vue @@ -27,10 +27,7 @@ Auction Amount - + @@ -39,7 +36,7 @@ Unknown @@ -50,7 +47,7 @@ Unknown @@ -119,7 +116,7 @@ @@ -170,14 +167,14 @@ @@ -379,7 +376,7 @@ export default Vue.extend({ typeof this.auction?.marketUnitPriceToUnitPriceRatio === 'undefined' ) { return `Swap transaction is not possible, - because we can't get value of ${this.auction?.collateralSymbol} on UniSwap`; + because we can't get value of ${this.auction?.tokenName} on UniSwap`; } return null; }, diff --git a/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue b/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue index 912d1ceb..66ce2f1f 100644 --- a/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue +++ b/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue @@ -9,7 +9,7 @@
@@ -18,7 +18,7 @@
per - {{ auctionTransaction.collateralSymbol }} + {{ auctionTransaction.tokenName }}
- - + +
Unknown
diff --git a/frontend/components/auction/collateral/MarketPriceSelection.vue b/frontend/components/auction/collateral/MarketPriceSelection.vue index 65a6a38d..ecaf897a 100644 --- a/frontend/components/auction/collateral/MarketPriceSelection.vue +++ b/frontend/components/auction/collateral/MarketPriceSelection.vue @@ -9,7 +9,7 @@
per - {{ auctionTransaction.collateralSymbol }} + {{ auctionTransaction.tokenName }}
@@ -32,7 +32,7 @@ per - {{ auctionTransaction.collateralSymbol }} + {{ auctionTransaction.tokenName }}
diff --git a/frontend/components/dashboard/CollateralTable.vue b/frontend/components/dashboard/CollateralTable.vue index 11940575..bb46300c 100644 --- a/frontend/components/dashboard/CollateralTable.vue +++ b/frontend/components/dashboard/CollateralTable.vue @@ -8,12 +8,12 @@ :pagination="{ pageSize: collateralAmount, hideOnSinglePage: true }" >
- +
{{ ilk }}
-
{{ symbol }}
+
{{ tokenName }}
@@ -144,7 +144,7 @@ export default Vue.extend({ }, { title: 'Currency', - dataIndex: 'symbol', + dataIndex: 'tokenName', scopedSlots: { customRender: 'symbol' }, }, { diff --git a/frontend/components/modals/ManageCollateralTable.vue b/frontend/components/modals/ManageCollateralTable.vue index 02fae22b..8d395dc3 100644 --- a/frontend/components/modals/ManageCollateralTable.vue +++ b/frontend/components/modals/ManageCollateralTable.vue @@ -15,7 +15,7 @@
- + {{ collateralStatus.type }}
diff --git a/frontend/components/panels/WithdrawCollateralPanel.vue b/frontend/components/panels/WithdrawCollateralPanel.vue index 88c81871..d265bfc0 100644 --- a/frontend/components/panels/WithdrawCollateralPanel.vue +++ b/frontend/components/panels/WithdrawCollateralPanel.vue @@ -87,7 +87,7 @@ export default Vue.extend({ collateralSymbol(): string { try { const collateral = getCollateralConfigByType(this.collateralType); - return collateral.symbol; + return collateral.tokenName; } catch { return ''; } diff --git a/frontend/helpers/generateFakeAuction.ts b/frontend/helpers/generateFakeAuction.ts index 06fb3ee3..ba785494 100644 --- a/frontend/helpers/generateFakeAuction.ts +++ b/frontend/helpers/generateFakeAuction.ts @@ -115,6 +115,7 @@ export const generateFakeAuction = function () { index, collateralType: collateralObject.ilk, collateralSymbol: collateralObject.symbol, + tokenName: collateralObject.tokenName, collateralAmount, totalPrice, debtDAI, From 540c2af9110c604a36909af95a862a450260c088 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 14:20:51 +0200 Subject: [PATCH 16/28] fix collaterals modal --- core/src/types.ts | 1 + frontend/store/collaterals.ts | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/core/src/types.ts b/core/src/types.ts index cfabb073..cbbf2d98 100644 --- a/core/src/types.ts +++ b/core/src/types.ts @@ -268,6 +268,7 @@ export declare interface WalletBalances { export declare interface CollateralStatus { type: string; symbol: string; + tokenName: string; isAuthorized: boolean; isAuthorizing: boolean; isDepositingOrWithdrawing: boolean; diff --git a/frontend/store/collaterals.ts b/frontend/store/collaterals.ts index c4ed17fd..fd3d345d 100644 --- a/frontend/store/collaterals.ts +++ b/frontend/store/collaterals.ts @@ -22,6 +22,7 @@ const getInitialState = (): State => ({ ({ ilk: collateral.ilk, symbol: collateral.symbol, + tokenName: collateral.tokenName, } as CollateralRow) ), collateralStatusesStorage: {}, @@ -131,6 +132,7 @@ export const actions = { commit('setCollateralStatus', { type: collateral.ilk, symbol: collateral.symbol, + tokenName: collateral.tokenName, }); }, async fetchCollateralStatus( @@ -152,12 +154,14 @@ export const actions = { commit('setCollateralStatus', { type: collateral.ilk, symbol: collateral.symbol, + tokenName: collateral.tokenName, address: tokenAddress, }); } catch { commit('setCollateralStatus', { type: collateral.ilk, symbol: collateral.symbol, + tokenName: collateral.tokenName, address: null, }); } From 92079705e3112c691167957a7e6244e502053f00 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 14:51:02 +0200 Subject: [PATCH 17/28] fix frontend types --- frontend/helpers/generateFakeCollateral.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/helpers/generateFakeCollateral.ts b/frontend/helpers/generateFakeCollateral.ts index 07fa6637..b46e8cf1 100644 --- a/frontend/helpers/generateFakeCollateral.ts +++ b/frontend/helpers/generateFakeCollateral.ts @@ -27,6 +27,7 @@ export const generateFakeCollateralStatuses = function () { collateralStatuses.push({ type: collateral.ilk, symbol: collateral.symbol, + tokenName: collateral.tokenName, address: faker.finance.ethereumAddress(), isAuthorized: faker.datatype.boolean(), isAuthorizing: false, From 960f8d28d8519c880c850ff894ffe6ee115f6ed5 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 16:13:02 +0200 Subject: [PATCH 18/28] update collateral name for the mainnet --- core/src/constants/COLLATERALS.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index a242deff..ee400823 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -1071,9 +1071,9 @@ const COLLATERALS: Record = { }, oracle: ORACLE_WITH_DELAY, }, - LOCKSTAKE: { + 'LSE-MKR-A': { title: 'Lockstake MKR', - ilk: 'LOCKSTAKE', + ilk: 'LSE-MKR-A', symbol: 'MCD_GOV', tokenName: 'MKR', decimals: 18, From 51d2ac1eb6bc149e5741ba0065dbfa14209e9821 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 17:20:26 +0200 Subject: [PATCH 19/28] use dynamic vaultIndex to open LSE vault --- core/simulations/helpers/createVaultWithCollateral.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/simulations/helpers/createVaultWithCollateral.ts b/core/simulations/helpers/createVaultWithCollateral.ts index e56c4ff9..a03b8ca3 100644 --- a/core/simulations/helpers/createVaultWithCollateral.ts +++ b/core/simulations/helpers/createVaultWithCollateral.ts @@ -204,11 +204,11 @@ const createDefaultVaultWithCollateral = async (collateralType: CollateralType, const createLockstakeVaultWithCollateral = async (collateralType: CollateralType, collateralOwned: BigNumber) => { const collateralConfig = getCollateralConfigByType(collateralType); const walletAddress = await (await getSigner(TEST_NETWORK)).getAddress(); - const vaultIndex = 1; const refId = 0; // Open engine vault const engine = await getContract(TEST_NETWORK, 'LOCKSTAKE_ENGINE', true); + const vaultIndex = parseInt(await engine.ownerUrnsCount(walletAddress)); await engine.open(vaultIndex); // Lock From 9326bac5ec668ad165b899b8d557271c237dbb96 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 17:36:53 +0200 Subject: [PATCH 20/28] set smaller starting price in the simulation --- core/simulations/configs/vaultLiquidation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/simulations/configs/vaultLiquidation.ts b/core/simulations/configs/vaultLiquidation.ts index a013896c..caa14d4f 100644 --- a/core/simulations/configs/vaultLiquidation.ts +++ b/core/simulations/configs/vaultLiquidation.ts @@ -83,7 +83,7 @@ const simulation: Simulation = { } catch {} try { // overwrite clip.buf (initial auction price multiplier) - await overwriteUintValue(collateralConfig.contracts.clip, '0x5', RAY.dividedBy(10)); + await overwriteUintValue(collateralConfig.contracts.clip, '0x5', RAY.dividedBy(50)); } catch {} // liquidate await liquidateVault(TEST_NETWORK, context.collateralType, context.vaultAddress); From 7af2e9c907d89c738df0c5f8089aec55928ccee1 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 19:06:14 +0200 Subject: [PATCH 21/28] display correct token inside Bid with DAI --- .../auction/collateral/CollateralAuctionBidBlock.vue | 2 +- .../collateral/CollateralAuctionBidTransactionTable.vue | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/components/auction/collateral/CollateralAuctionBidBlock.vue b/frontend/components/auction/collateral/CollateralAuctionBidBlock.vue index 4c18935e..83706071 100644 --- a/frontend/components/auction/collateral/CollateralAuctionBidBlock.vue +++ b/frontend/components/auction/collateral/CollateralAuctionBidBlock.vue @@ -20,7 +20,7 @@ Bid for diff --git a/frontend/components/auction/collateral/CollateralAuctionBidTransactionTable.vue b/frontend/components/auction/collateral/CollateralAuctionBidTransactionTable.vue index 2510247b..4006fa15 100644 --- a/frontend/components/auction/collateral/CollateralAuctionBidTransactionTable.vue +++ b/frontend/components/auction/collateral/CollateralAuctionBidTransactionTable.vue @@ -11,7 +11,7 @@
@@ -21,7 +21,7 @@ Unknown
@@ -94,11 +94,11 @@
Unknown - {{ auctionTransaction.collateralSymbol }} + {{ auctionTransaction.tokenName }}
From 195945e2cef9b3ea31d61fd75c3f5ff4fe32fdd1 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 23:30:13 +0200 Subject: [PATCH 22/28] improve logging --- bot/src/notify.ts | 2 +- core/simulations/helpers/createVaultWithCollateral.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/src/notify.ts b/bot/src/notify.ts index 0bd8ef02..86856206 100644 --- a/bot/src/notify.ts +++ b/bot/src/notify.ts @@ -6,7 +6,7 @@ const generateNotificationTextCollateral = function (auction: AuctionInitialInfo const url = `${process.env.FRONTEND_ORIGIN}/collateral/?network=${auction.network}&auction=${auction.id}`; const formattedString = formatToAutomaticDecimalPointsString(auction.collateralAmount); - return `Collateral auction with ${formattedString} ${auction.collateralSymbol} just started. Follow the link to participate: ${url}`; + return `Collateral auction with ${formattedString} ${auction.tokenName} just started. Follow the link to participate: ${url}`; }; const generateNotificationTextDebt = function (auction: DebtAuctionActive): string { diff --git a/core/simulations/helpers/createVaultWithCollateral.ts b/core/simulations/helpers/createVaultWithCollateral.ts index a03b8ca3..35df9bcd 100644 --- a/core/simulations/helpers/createVaultWithCollateral.ts +++ b/core/simulations/helpers/createVaultWithCollateral.ts @@ -99,7 +99,7 @@ const ensureWalletBalance = async (collateralConfig: CollateralConfig, collatera `Unexpected wallet balance. Expected ${collateralOwned.toFixed()}, Actual ${balance.toFixed()}` ); } - console.info(`Wallet has ${collateralOwned.toFixed()} ${collateralConfig.symbol}`); + console.info(`Wallet has ${collateralOwned.toFixed()} ${collateralConfig.tokenName}`); }; const putCollateralIntoVaultAndWithdrawDai = async (vaultId: number, collateralOwned: BigNumber) => { From 7f04c834e0fc2cb3903679e622067cf0d9a13b6f Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 23:31:10 +0200 Subject: [PATCH 23/28] show full exchange path --- .../components/auction/collateral/MarketPriceSelection.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/components/auction/collateral/MarketPriceSelection.vue b/frontend/components/auction/collateral/MarketPriceSelection.vue index ecaf897a..5c849d45 100644 --- a/frontend/components/auction/collateral/MarketPriceSelection.vue +++ b/frontend/components/auction/collateral/MarketPriceSelection.vue @@ -138,7 +138,9 @@ export default Vue.extend({ if (!pools || !pools?.length) { return ''; } - return pools.map(pool => pool.routes[0]).join(' → '); + const route = pools.map(pool => pool.routes[0]); + route.push(pools[pools.length - 1].routes[1]); + return route.join(' → '); }, getRouteFromMarketData(marketData: MarketData) { if (!marketData) { From beafc78947040a48866fe7d106e9fd47af21437e Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 23:31:55 +0200 Subject: [PATCH 24/28] use SKY/USDS market for LSE auctions --- core/src/calleeFunctions/UniswapV2LockstakeCallee.ts | 6 +++++- core/src/calleeFunctions/helpers/uniswapV2.ts | 2 +- core/src/constants/COLLATERALS.ts | 2 +- core/src/tokens.ts | 6 ++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/core/src/calleeFunctions/UniswapV2LockstakeCallee.ts b/core/src/calleeFunctions/UniswapV2LockstakeCallee.ts index 5dfabf97..2cedb0e9 100644 --- a/core/src/calleeFunctions/UniswapV2LockstakeCallee.ts +++ b/core/src/calleeFunctions/UniswapV2LockstakeCallee.ts @@ -33,8 +33,12 @@ const getMarketPrice = async function ( if (marketData.callee !== 'UniswapV2LockstakeCallee') { throw new Error(`Can not get market price for the "${collateral.ilk}"`); } + let price = await getRegularTokenExchangeRateBySymbol(network, collateral.symbol, marketId, amount); + if (marketData.route[0] === 'SKY') { + price = price.multipliedBy(24_000); + } return { - price: await getRegularTokenExchangeRateBySymbol(network, collateral.symbol, marketId, amount), + price, pools: await routeToPool(network, marketData.route, collateral.symbol), }; }; diff --git a/core/src/calleeFunctions/helpers/uniswapV2.ts b/core/src/calleeFunctions/helpers/uniswapV2.ts index 27637ab4..2ac9d6e9 100644 --- a/core/src/calleeFunctions/helpers/uniswapV2.ts +++ b/core/src/calleeFunctions/helpers/uniswapV2.ts @@ -124,7 +124,7 @@ export const getRegularTokenExchangeRateBySymbol = async function ( const completeExchangePath = getCompleteExchangePathBySymbol(symbol, marketId); const pairs = splitArrayIntoPairs(completeExchangePath); const uniswapPairs = await Promise.all(pairs.map(pair => getUniswapPairBySymbols(network, pair[0], pair[1]))); - const exchangeToken = await getUniswapTokenBySymbol(network, symbol); + const exchangeToken = await getUniswapTokenBySymbol(network, completeExchangePath[0]); const uniswapRoute = new Route(uniswapPairs, exchangeToken); const uniswapTrade = new Trade( uniswapRoute, diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index ee400823..8d5f4fc4 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -1086,7 +1086,7 @@ const COLLATERALS: Record = { exchanges: { 'Uniswap V2': { callee: 'UniswapV2LockstakeCallee', - route: ['MCD_GOV', 'DAI'], + route: ['SKY', 'USDS'], }, }, oracle: ORACLE_WITH_DELAY, diff --git a/core/src/tokens.ts b/core/src/tokens.ts index fa7d12aa..08dd0105 100644 --- a/core/src/tokens.ts +++ b/core/src/tokens.ts @@ -22,9 +22,15 @@ export const getTokenDecimalsBySymbol = function (symbol: string): number { if (tokenName === 'DAI') { return DAI_NUMBER_OF_DIGITS; } + if (tokenName === 'USDS') { + return DAI_NUMBER_OF_DIGITS; + } if (tokenName === 'MKR') { return MKR_NUMBER_OF_DIGITS; } + if (tokenName === 'SKY') { + return MKR_NUMBER_OF_DIGITS; + } const collateral = getCollateralConfigBySymbol(tokenName); return collateral && collateral.decimals; }; From 07029201abff19ea2762e779d903efc9099e37c3 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Mon, 21 Oct 2024 23:33:45 +0200 Subject: [PATCH 25/28] remove unsupported USDC-B collateral to fix tests --- core/src/constants/COLLATERALS.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index 8d5f4fc4..0f7b27c4 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -535,35 +535,6 @@ const COLLATERALS: Record = { }, oracle: ORACLE_WITHOUT_DELAY, }, - 'USDC-B': { - title: 'USD Coin', - ilk: 'USDC-B', - symbol: 'USDC', - tokenName: 'USDC', - decimals: 6, - contracts: { - token: 'USDC', - pip: 'PIP_USDC', - join: 'MCD_JOIN_USDC_A', - clip: 'MCD_CLIP_USDC_B', - calc: 'MCD_CLIP_CALC_USDC_B', - }, - exchanges: { - 'Uniswap V3 Autorouter': { - callee: 'UniswapV3Callee', - automaticRouter: true, - }, - 'Uniswap V3': { - callee: 'UniswapV3Callee', - route: ['USDC', 'ETH', 'DAI'], - }, - 'Uniswap V2': { - callee: 'UniswapV2CalleeDai', - route: ['USDC', 'ETH', 'DAI'], - }, - }, - oracle: ORACLE_WITHOUT_DELAY, - }, 'USDT-A': { title: 'Tether USD', ilk: 'USDT-A', From a625ebcdd9061fbd6c1e521881c7a8b143903d42 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 22 Oct 2024 11:31:15 +0200 Subject: [PATCH 26/28] update end-to-end tests to work with LSE collateral --- .../helpers/createVaultWithCollateral.ts | 4 + core/src/constants/COLLATERALS.ts | 29 +++ core/test/vault-test.ts | 216 ++++++++---------- 3 files changed, 132 insertions(+), 117 deletions(-) diff --git a/core/simulations/helpers/createVaultWithCollateral.ts b/core/simulations/helpers/createVaultWithCollateral.ts index 35df9bcd..2dcfaa7a 100644 --- a/core/simulations/helpers/createVaultWithCollateral.ts +++ b/core/simulations/helpers/createVaultWithCollateral.ts @@ -41,6 +41,10 @@ import getSigner from '../../src/signer'; const UNSUPPORTED_COLLATERAL_TYPES = [ 'GNO-A', + 'GUSD-A', + 'USDC-A', + 'USDC-B', + 'RENBTC-A', 'RETH-A', // [temporary] this collateral is not yet deployed, tested via different flow 'TUSD-A', // [proxy] this collateral has a proxy-token contract and fallback solution does not work since JOIN contract does not have sufficient funds ]; diff --git a/core/src/constants/COLLATERALS.ts b/core/src/constants/COLLATERALS.ts index 0f7b27c4..8d5f4fc4 100644 --- a/core/src/constants/COLLATERALS.ts +++ b/core/src/constants/COLLATERALS.ts @@ -535,6 +535,35 @@ const COLLATERALS: Record = { }, oracle: ORACLE_WITHOUT_DELAY, }, + 'USDC-B': { + title: 'USD Coin', + ilk: 'USDC-B', + symbol: 'USDC', + tokenName: 'USDC', + decimals: 6, + contracts: { + token: 'USDC', + pip: 'PIP_USDC', + join: 'MCD_JOIN_USDC_A', + clip: 'MCD_CLIP_USDC_B', + calc: 'MCD_CLIP_CALC_USDC_B', + }, + exchanges: { + 'Uniswap V3 Autorouter': { + callee: 'UniswapV3Callee', + automaticRouter: true, + }, + 'Uniswap V3': { + callee: 'UniswapV3Callee', + route: ['USDC', 'ETH', 'DAI'], + }, + 'Uniswap V2': { + callee: 'UniswapV2CalleeDai', + route: ['USDC', 'ETH', 'DAI'], + }, + }, + oracle: ORACLE_WITHOUT_DELAY, + }, 'USDT-A': { title: 'Tether USD', ilk: 'USDT-A', diff --git a/core/test/vault-test.ts b/core/test/vault-test.ts index 28354c23..4796644c 100644 --- a/core/test/vault-test.ts +++ b/core/test/vault-test.ts @@ -23,6 +23,7 @@ import createVaultWithCollateral, { getLiquidatableCollateralTypes, } from '../simulations/helpers/createVaultWithCollateral'; import { NULL_ADDRESS } from '../src/constants/UNITS'; +import { overwriteCurrentOraclePrice } from '../helpers/hardhat/overwrites'; chai.use(deepEqualInAnyOrder); const compareVaultTransactionsNotLiquidated = ( @@ -204,7 +205,7 @@ describe('Vaults', () => { describe('Sound values are extracted', () => { before(async () => { await setupRpcUrlAndGetNetworks(LOCAL_RPC_URL); - await resetNetwork(15533000); + await resetNetwork(21019453); }); const expectedReturn: Record< CollateralType, @@ -213,22 +214,22 @@ describe('Sound values are extracted', () => { 'AAVE-A': { nextUnitPrice: '150.79237464128204', currentUnitPrice: '150.79237464128204', - nextPriceChange: new Date('2022-01-23T22:00:00.000Z'), + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'BAL-A': { - currentUnitPrice: '11.80800329930906', + currentUnitPrice: '11.721140147069267', nextUnitPrice: '11.721140147069267', - nextPriceChange: new Date('2022-01-23T19:00:00.000Z'), + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'BAT-A': { nextUnitPrice: '0.73', - currentUnitPrice: '0.71910538308', - nextPriceChange: new Date('2022-01-23T19:00:00.000Z'), + currentUnitPrice: '0.73', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'COMP-A': { nextUnitPrice: '124.5640565401381', currentUnitPrice: '124.5640565401381', - nextPriceChange: new Date('2022-01-23T22:00:00.000Z'), + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'ETH-A': { nextUnitPrice: '1712.2106886', @@ -236,9 +237,9 @@ describe('Sound values are extracted', () => { nextPriceChange: new Date('2022-09-09T10:00:00.000Z'), }, 'ETH-B': { - nextUnitPrice: '1602.1803800999999', - currentUnitPrice: '1602.1803800999999', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '2643.19', + currentUnitPrice: '2643.19', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, 'ETH-C': { nextUnitPrice: '1208.0159951', @@ -251,24 +252,24 @@ describe('Sound values are extracted', () => { nextPriceChange: new Date(NaN), }, 'KNC-A': { - nextUnitPrice: '1.5108', - currentUnitPrice: '1.4869', - nextPriceChange: new Date('2021-10-28T05:00:00.000Z'), + nextUnitPrice: '1.8601360490999999', + currentUnitPrice: '1.8601360490999999', + nextPriceChange: new Date('2023-04-06T19:00:00.000Z'), }, 'LINK-A': { - nextUnitPrice: '7.2245', - currentUnitPrice: '7.159627035', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '14.56509', + currentUnitPrice: '7.2', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'LRC-A': { nextUnitPrice: '0.8117493344000001', - currentUnitPrice: '0.7270649846852948', - nextPriceChange: new Date('2022-01-23T19:00:00.000Z'), + currentUnitPrice: '0.8117493344000001', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'MANA-A': { - nextUnitPrice: '0.73075', - currentUnitPrice: '0.73075', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '0.36741132408456323', + currentUnitPrice: '0.36741132408456323', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'PAXUSD-A': { nextUnitPrice: 'NaN', @@ -276,9 +277,9 @@ describe('Sound values are extracted', () => { nextPriceChange: new Date(NaN), }, 'RENBTC-A': { - nextUnitPrice: '20388.465', - currentUnitPrice: '20388.465', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '66992.455', + currentUnitPrice: '66992.455', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, 'TUSD-A': { nextUnitPrice: 'NaN', @@ -286,9 +287,9 @@ describe('Sound values are extracted', () => { nextPriceChange: new Date(NaN), }, 'UNI-A': { - nextUnitPrice: '6.1622020819', - currentUnitPrice: '5.103855836', - nextPriceChange: new Date('2022-07-11T16:00:00.000Z'), + nextUnitPrice: '5.845563067104212', + currentUnitPrice: '5.845563067104212', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'USDC-A': { nextUnitPrice: 'NaN', @@ -301,104 +302,109 @@ describe('Sound values are extracted', () => { nextPriceChange: new Date(NaN), }, 'USDT-A': { - nextUnitPrice: '1.0007712772150232', - currentUnitPrice: '1.0007712772150232', - nextPriceChange: new Date('2021-10-28T05:00:00.000Z'), + nextUnitPrice: '1.000413775900346', + currentUnitPrice: '1.000413775900346', + nextPriceChange: new Date('2023-04-06T19:00:00.000Z'), }, 'WBTC-A': { - nextUnitPrice: '20388.465', - currentUnitPrice: '20388.465', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '66992.455', + currentUnitPrice: '66992.455', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, 'WBTC-B': { - nextUnitPrice: '20388.465', - currentUnitPrice: '20388.465', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '66992.455', + currentUnitPrice: '66992.455', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, 'WBTC-C': { - nextUnitPrice: '20388.465', - currentUnitPrice: '20388.465', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '66992.455', + currentUnitPrice: '66992.455', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, 'YFI-A': { - nextUnitPrice: '9150', - currentUnitPrice: '9185.8368', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '6274.912194791102', + currentUnitPrice: '6274.912194791102', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'ZRX-A': { nextUnitPrice: '0.54008', - currentUnitPrice: '0.50224', - nextPriceChange: new Date('2022-01-23T19:00:00.000Z'), + currentUnitPrice: '0.54008', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'MATIC-A': { - nextUnitPrice: '0.859281', - currentUnitPrice: '0.859281', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '0.6834569949358978', + currentUnitPrice: '0.6834569949358978', + nextPriceChange: new Date('2024-01-30T01:00:00.000Z'), }, 'WSTETH-A': { - nextUnitPrice: '1687.84305547955', - currentUnitPrice: '1687.84305547955', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '3095.153407214590908078', + currentUnitPrice: '3095.153407214590908078', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, 'WSTETH-B': { - nextUnitPrice: '1687.84305547955', - currentUnitPrice: '1687.84305547955', - nextPriceChange: new Date('2022-09-14T13:00:00.000Z'), + nextUnitPrice: '3095.153407214590908078', + currentUnitPrice: '3095.153407214590908078', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, 'CRVV1ETHSTETH-A': { - nextUnitPrice: '1633.547452878850724671', - currentUnitPrice: '1645.994835125363651071', - nextPriceChange: new Date('2022-09-14T12:01:47.000Z'), + nextUnitPrice: '2949.792480904069309162', + currentUnitPrice: '2898.680178316106908798', + nextPriceChange: new Date('2024-10-21T16:00:11.000Z'), }, 'UNIV2DAIETH-A': { - nextUnitPrice: '111.536694644490420563', - currentUnitPrice: '115.716445113160358543', - nextPriceChange: new Date('2022-07-13T17:00:03.000Z'), + nextUnitPrice: '180.027413016904332609', + currentUnitPrice: '156.864657339046759104', + nextPriceChange: new Date('2024-01-30T01:43:59.000Z'), }, 'UNIV2USDCETH-A': { - nextUnitPrice: '164916785.176105260363204747', - currentUnitPrice: '165534555.801045344024651968', - nextPriceChange: new Date('2022-09-14T12:01:47.000Z'), + nextUnitPrice: '217940294.382329574841183087', + currentUnitPrice: '188666866.181749331159918865', + nextPriceChange: new Date('2024-01-30T01:43:59.000Z'), }, 'UNIV2ETHUSDT-A': { - nextUnitPrice: '228116379.650719357480121186', - currentUnitPrice: '230190196.687438171219371005', - nextPriceChange: new Date('2021-10-28T04:01:15.000Z'), + nextUnitPrice: '197722335.963263628773031269', + currentUnitPrice: '228116379.650719357480121186', + nextPriceChange: new Date('2023-04-06T18:44:23.000Z'), }, 'UNIV2WBTCDAI-A': { - nextUnitPrice: '31892330.725591269457933196', - currentUnitPrice: '32196608.076982062517168305', - nextPriceChange: new Date('2022-07-11T16:09:40.000Z'), + nextUnitPrice: '47113092.314935817960683604', + currentUnitPrice: '37716763.676534507210426868', + nextPriceChange: new Date('2024-01-30T01:43:59.000Z'), }, 'UNIV2WBTCETH-A': { - nextUnitPrice: '1102874511.239936578199968093', - currentUnitPrice: '1175008223.21111667836061111', - nextPriceChange: new Date('2022-07-13T17:00:03.000Z'), + nextUnitPrice: '2517374355.748241170169672756', + currentUnitPrice: '1794044631.240253383841931772', + nextPriceChange: new Date('2024-01-30T01:43:59.000Z'), }, 'UNIV2LINKETH-A': { - nextUnitPrice: '567.672642511519510798', - currentUnitPrice: '566.984073123537837073', - nextPriceChange: new Date('2022-01-23T19:01:00.000Z'), + nextUnitPrice: '632.725670378659259608', + currentUnitPrice: '375.213195603332086751', + nextPriceChange: new Date('2024-01-30T01:43:59.000Z'), }, 'UNIV2UNIETH-A': { - nextUnitPrice: '368.441439820843276851', - currentUnitPrice: '327.117645258478197955', - nextPriceChange: new Date('2022-07-11T16:09:40.000Z'), + nextUnitPrice: '546.022046787969721817', + currentUnitPrice: '478.806858210117892322', + nextPriceChange: new Date('2024-01-30T01:43:59.000Z'), }, 'UNIV2AAVEETH-A': { - nextUnitPrice: '2503.767176345875098159', - currentUnitPrice: '2529.450702467409881126', - nextPriceChange: new Date('2021-11-22T23:04:46.000Z'), + nextUnitPrice: '1435.896796202841677092', + currentUnitPrice: '2503.767176345875098159', + nextPriceChange: new Date('2023-04-06T18:44:23.000Z'), }, 'UNIV2DAIUSDT-A': { - nextUnitPrice: '2274141.032812901837192665', - currentUnitPrice: '2274109.765292120125373109', - nextPriceChange: new Date('2021-10-28T04:01:15.000Z'), + nextUnitPrice: '2333803.165539906895807342', + currentUnitPrice: '2274141.032812901837192665', + nextPriceChange: new Date('2023-04-06T18:44:23.000Z'), }, 'UNIV2DAIUSDC-A': { - nextUnitPrice: '2252657.773463853818331742', - currentUnitPrice: '2252657.773463853818331742', - nextPriceChange: new Date('2022-09-14T12:01:47.000Z'), + nextUnitPrice: '2265919.675663883138436151', + currentUnitPrice: '2265919.675663883138436151', + nextPriceChange: new Date('2024-10-22T06:53:35.000Z'), + }, + 'LSE-MKR-A': { + nextUnitPrice: '1177.52796', + currentUnitPrice: '1177.52796', + nextPriceChange: new Date('2024-10-22T07:00:00.000Z'), }, }; for (const type of getLiquidatableCollateralTypes()) { @@ -420,42 +426,18 @@ describe('Sound values are extracted', () => { describe(`Collateral vault simulation liquidation `, () => { before(async () => { await createWalletForRpc(); - await resetNetwork(16066000); // TODO: remove hardcoded block number and investigate `Dog/not-unsafe` error + await resetNetwork(21019453); // TODO: remove hardcoded block number and investigate `Dog/not-unsafe` error }); for (const collateralType of getLiquidatableCollateralTypes()) { it(`runs the simulaton for ${collateralType}`, async () => { - let collateralOwned: BigNumber; + await overwriteCurrentOraclePrice(TEST_NETWORK, collateralType, new BigNumber(1000)); await adjustLimitsAndRates(collateralType); - try { - collateralOwned = await calculateMinCollateralAmountToOpenVault(collateralType); - } catch (e) { - if (e instanceof Error && e.message.endsWith('max debt set to zero')) { - return; - } - throw e; - } - let vaultId: number; - try { - vaultId = (await createVaultWithCollateral(collateralType, collateralOwned)).vaultIndex; - } catch (e) { - if (e instanceof Error && e.message === 'Could not borrow dai because debt ceiling is exceeded.') { - return; - } - throw e; - } - - const vault = await fetchVault(TEST_NETWORK, vaultId); - expect(vault.collateralAmount.toFixed(0)).to.eq(collateralOwned.toFixed(0)); - - const previousStabilityFee = vault.stabilityFeeRate; + const collateralOwned = (await calculateMinCollateralAmountToOpenVault(collateralType)).multipliedBy(10); + const vaultAddress = (await createVaultWithCollateral(collateralType, collateralOwned)).vaultAddress; await warpTime(60 * 24 * 30 * 12 * 2, 60); - await collectStabilityFees(TEST_NETWORK, vault.collateralType); - const currentStabilityFee = (await fetchVault(TEST_NETWORK, vaultId)).stabilityFeeRate; - if (!currentStabilityFee.gt(previousStabilityFee)) { - throw new Error('Successful vault creation, but stability fees did not change after time warp'); - } - - await liquidateVault(TEST_NETWORK, vault.collateralType, vault.address); + await overwriteCurrentOraclePrice(TEST_NETWORK, collateralType, new BigNumber(500)); + await collectStabilityFees(TEST_NETWORK, collateralType); + await liquidateVault(TEST_NETWORK, collateralType, vaultAddress); }); } }); From 4427d68311db1008f265d6b5a00e95cb2ab7dfe5 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 22 Oct 2024 15:07:19 +0200 Subject: [PATCH 27/28] display correct profit token --- .../CollateralAuctionSwapTransactionTable.vue | 15 +++++++++++---- .../auction/collateral/MarketPriceSelection.vue | 9 +++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue b/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue index 66ce2f1f..a00b704d 100644 --- a/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue +++ b/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue @@ -17,7 +17,7 @@
Auction Price
- per + per {{ auctionTransaction.tokenName }}
@@ -25,6 +25,7 @@ :auction-transaction="auctionTransaction" :market-id.sync="currentMarketId" :is-autorouting-enabled="isAutoroutingEnabled" + :profit-token="profitToken" @update:toggleAutoRouterLoad="toggleAutoRouterLoad" />
@@ -49,7 +50,7 @@ v-if="transactionGrossProfit" show-sign :value="transactionGrossProfit" - currency="DAI" + :currency="profitToken" /> Unknown
@@ -71,7 +72,7 @@ Unknown @@ -83,7 +84,7 @@ v-if="transactionNetProfit" show-sign :value="transactionNetProfit" - currency="DAI" + :currency="profitToken" class="font-extrabold" /> Unknown @@ -133,6 +134,12 @@ export default Vue.extend({ }; }, computed: { + profitToken(): string { + const marketId = this.currentMarketId || this.auctionTransaction.suggestedMarketId; + const route = this.auctionTransaction.marketDataRecords[marketId].route || []; + const profitToken = route[route.length - 1]; + return profitToken; + }, marketUnitPriceToUnitPriceRatio(): BigNumber | undefined { if (!this.currentMarketId || !this.auctionTransaction.marketDataRecords) { return this.auctionTransaction.marketUnitPriceToUnitPriceRatio; diff --git a/frontend/components/auction/collateral/MarketPriceSelection.vue b/frontend/components/auction/collateral/MarketPriceSelection.vue index 5c849d45..5e1530e6 100644 --- a/frontend/components/auction/collateral/MarketPriceSelection.vue +++ b/frontend/components/auction/collateral/MarketPriceSelection.vue @@ -8,7 +8,7 @@ ({{ suggestionOrSelection }})
- per + per {{ auctionTransaction.tokenName }}
@@ -31,7 +31,8 @@ Select - per + + per {{ auctionTransaction.tokenName }} @@ -87,6 +88,10 @@ export default Vue.extend({ type: Object as Vue.PropType, required: true, }, + profitToken: { + type: String, + required: true, + }, marketId: { type: String, default: '', From 6752ddd0b1082b07f27ee408dac4ff3f2ea8ee81 Mon Sep 17 00:00:00 2001 From: Valia Fetisov Date: Tue, 22 Oct 2024 15:19:05 +0200 Subject: [PATCH 28/28] fix frontend tests --- .../collateral/CollateralAuctionSwapTransactionTable.vue | 2 +- .../auction/collateral/MarketPriceSelection.stories.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue b/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue index a00b704d..73d67190 100644 --- a/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue +++ b/frontend/components/auction/collateral/CollateralAuctionSwapTransactionTable.vue @@ -138,7 +138,7 @@ export default Vue.extend({ const marketId = this.currentMarketId || this.auctionTransaction.suggestedMarketId; const route = this.auctionTransaction.marketDataRecords[marketId].route || []; const profitToken = route[route.length - 1]; - return profitToken; + return profitToken || 'DAI'; }, marketUnitPriceToUnitPriceRatio(): BigNumber | undefined { if (!this.currentMarketId || !this.auctionTransaction.marketDataRecords) { diff --git a/frontend/components/auction/collateral/MarketPriceSelection.stories.js b/frontend/components/auction/collateral/MarketPriceSelection.stories.js index c866663a..699d4e07 100644 --- a/frontend/components/auction/collateral/MarketPriceSelection.stories.js +++ b/frontend/components/auction/collateral/MarketPriceSelection.stories.js @@ -12,7 +12,7 @@ const common = { auctionTransaction: fakeAuctionTransaction, marketId: '', }), - template: ``, + template: ``, }; storiesOf('Auction/Collateral/MarketPriceSelection', module).add('Default', () => ({ ...common }));