From 0c374ee4cb1194f2278fc3a9b67a0ef0d3964ba3 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Sat, 28 Aug 2021 00:16:37 +0300 Subject: [PATCH 01/21] Add Reflexer --- assets/icons/reflexer.svg | 29 ++ .../protocols/reflexer/CardReflexer.vue | 66 ++++ .../protocols/reflexer/DropdownReflexer.vue | 96 ++++++ .../reflexer/SidebarReflexerBorrow.vue | 196 +++++++++++ .../reflexer/SidebarReflexerCollateral.vue | 83 +++++ .../reflexer/SidebarReflexerPayback.vue | 220 +++++++++++++ .../reflexer/SidebarReflexerSupply.vue | 204 ++++++++++++ .../reflexer/SidebarReflexerWithdraw.vue | 192 +++++++++++ composables/protocols/useReflexerPosition.ts | 311 ++++++++++++++++++ composables/useSidebar.ts | 13 + composables/useValidators.ts | 38 ++- constant/abi/read/reflexer.json | 271 +++++++++++++++ constant/abis.ts | 3 +- constant/addresses.ts | 15 +- constant/tokens/safes.ts | 10 + pages/index.vue | 10 +- pages/mainnet/reflexer.vue | 283 ++++++++++++++++ 17 files changed, 2029 insertions(+), 11 deletions(-) create mode 100644 assets/icons/reflexer.svg create mode 100644 components/protocols/reflexer/CardReflexer.vue create mode 100644 components/protocols/reflexer/DropdownReflexer.vue create mode 100644 components/sidebar/context/reflexer/SidebarReflexerBorrow.vue create mode 100644 components/sidebar/context/reflexer/SidebarReflexerCollateral.vue create mode 100644 components/sidebar/context/reflexer/SidebarReflexerPayback.vue create mode 100644 components/sidebar/context/reflexer/SidebarReflexerSupply.vue create mode 100644 components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue create mode 100644 composables/protocols/useReflexerPosition.ts create mode 100644 constant/abi/read/reflexer.json create mode 100644 constant/tokens/safes.ts create mode 100644 pages/mainnet/reflexer.vue diff --git a/assets/icons/reflexer.svg b/assets/icons/reflexer.svg new file mode 100644 index 0000000..426969f --- /dev/null +++ b/assets/icons/reflexer.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/components/protocols/reflexer/CardReflexer.vue b/components/protocols/reflexer/CardReflexer.vue new file mode 100644 index 0000000..394666c --- /dev/null +++ b/components/protocols/reflexer/CardReflexer.vue @@ -0,0 +1,66 @@ + + + \ No newline at end of file diff --git a/components/protocols/reflexer/DropdownReflexer.vue b/components/protocols/reflexer/DropdownReflexer.vue new file mode 100644 index 0000000..1353587 --- /dev/null +++ b/components/protocols/reflexer/DropdownReflexer.vue @@ -0,0 +1,96 @@ + + + diff --git a/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue b/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue new file mode 100644 index 0000000..89ad92b --- /dev/null +++ b/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue @@ -0,0 +1,196 @@ + + + diff --git a/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue b/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue new file mode 100644 index 0000000..54b69d0 --- /dev/null +++ b/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue @@ -0,0 +1,83 @@ + + + diff --git a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue new file mode 100644 index 0000000..3b56008 --- /dev/null +++ b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue @@ -0,0 +1,220 @@ + + + diff --git a/components/sidebar/context/reflexer/SidebarReflexerSupply.vue b/components/sidebar/context/reflexer/SidebarReflexerSupply.vue new file mode 100644 index 0000000..2190128 --- /dev/null +++ b/components/sidebar/context/reflexer/SidebarReflexerSupply.vue @@ -0,0 +1,204 @@ + + + diff --git a/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue b/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue new file mode 100644 index 0000000..8e38c7a --- /dev/null +++ b/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue @@ -0,0 +1,192 @@ + + + diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts new file mode 100644 index 0000000..6c26b72 --- /dev/null +++ b/composables/protocols/useReflexerPosition.ts @@ -0,0 +1,311 @@ +import { computed, Ref, ref, watch } from "@nuxtjs/composition-api"; +import BigNumber from "bignumber.js"; +BigNumber.config({ POW_PRECISION: 200 }); +import abis from "~/constant/abis"; +import addresses from "~/constant/addresses"; +import reflexerSafes from "~/constant/tokens/safes"; +import { useBigNumber } from "~/composables/useBigNumber"; +import { useDSA } from "~/composables/useDSA"; +import { useToken } from "~/composables/useToken"; +import { useWeb3 } from "~/composables/useWeb3"; +import { AbiItem } from "web3-utils"; + +const defaultSafe = { + id: null, + tokenKey: "eth", + token: "ETH", + collateralName: "ETH-A", + collateral: "0", + debt: "0", + liquidatedCollateral: "0", + status: "0", + rate: "0", + liquidation: "0", + price: "0", + netvalue: "0" +}; + +const safeId = ref(null); +const safes = ref([]); +const isNewSafe = ref(false); +const safeTypes = ref([]); +const safeType = ref(""); + +const safe = computed(() => { + const vlt = safes.value.find(v => v.id === safeId.value); + if (!isNewSafe.value && !!vlt) { + return vlt; + } + + const vt = safeTypes.value.find(vt => vt.type === safeType.value); + if (vt) { + return { ...defaultSafe, ...vt }; + } + + const defaultSafeType = safeTypes.value[0]; + if (defaultSafeType) { + return { ...defaultSafe, ...defaultSafeType }; + } + + return defaultSafe; +}); + +export function useReflexerPosition( + collateralAmountRef: Ref = null, + debtAmountRef: Ref = null +) { + const { web3, chainId, networkName } = useWeb3(); + const { activeAccount } = useDSA(); + const { isZero, ensureValue, times, div, max, gt } = useBigNumber(); + const { getTokenByKey } = useToken(); + + const safeTokenType = computed(() => safe.value.safeTokenType); + + const price = computed(() => ensureValue(safe.value.price).toFixed()); + + const collateralUsd = computed(() => + times(collateral.value, price.value).toFixed() + ); + const collateral = computed(() => + ensureValue(safe.value.collateral).toFixed() + ); + + const liquidation = computed(() => + ensureValue(safe.value.liquidation).toFixed() + ); + const tokenKey = computed(() => safe.value.tokenKey); + + const token = computed(() => getTokenByKey(tokenKey.value)); + const symbol = computed(() => token.value.symbol ?? "ETH"); + const rate = computed(() => ensureValue(safe.value.rate).toFixed()); + const netValue = computed(() => ensureValue(safe.value.netValue).toFixed()); + + const status = computed(() => { + if (!collateralAmountRef || !debtAmountRef) + return ensureValue(safe.value.status).toFixed(); + return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value) + ? "1.1" + : div( + debtAmountRef.value, + times(collateralAmountRef.value, price.value) + ).toFixed(); + }); + + const liquidationPrice = computed(() => { + if (!collateralAmountRef || !debtAmountRef) + return max( + div(div(debt.value, collateral.value), liquidation.value), + "0" + ).toFixed(); + return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value) + ? times(price.value, "1.1").toFixed() + : max( + div( + div(debtAmountRef.value, collateralAmountRef.value), + liquidation.value + ), + "0" + ).toFixed(); + }); + + const debt = computed(() => ensureValue(safe.value.debt).toFixed()); + const minDebt = computed( + () => safeTypes.value[0]?.totalFloor?.toString() || "5000" + ); + const debtCeilingReached = computed(() => + safeTypes.value?.some(v => + gt(v.overallTotalDebt, v.overallTotalDebtCeiling) + ) + ); + + const fetchPosition = async () => { + if (!web3.value) { + return; + } + + safeTypes.value = await getSafeTypes(web3.value); + + if (!activeAccount.value) { + return; + } + safes.value = await getSafes(activeAccount.value.address, web3.value); + if (safes.value.length > 0) { + safeId.value = safes.value[0].id; + } + }; + + watch( + web3, + async val => { + if (val) { + fetchPosition(); + } + }, + { immediate: true } + ); + + watch( + activeAccount, + async val => { + if (val) { + fetchPosition(); + } + }, + { immediate: true } + ); + + const selectSafe = vid => { + if (vid === safeId.value && !isNewSafe.value) return; + safeId.value = vid; + isNewSafe.value = false; + }; + + return { + fetchPosition, + safeId: computed(() => (isNewSafe.value ? "0" : safeId.value || "0")), + selectSafe, + safeTokenType, + safe, + safes, + safeType, + safeTypes, + isNewSafe, + collateralUsd, + collateral, + price, + liquidation, + tokenKey, + token, + symbol, + rate, + netValue, + status, + liquidationPrice, + liquidationMaxPrice: price, + debt, + minDebt, + debtCeilingReached + }; +} + +async function getSafeTypes(web3) { + const reflexerResolveABI = abis.resolver.reflexer; + const reflexerResolveAddr = addresses.mainnet.resolver.reflexer; + + const reflexerResolverInstance = new web3.eth.Contract( + reflexerResolveABI as AbiItem[], + reflexerResolveAddr + ); + + try { + const rawData: any[] = await reflexerResolverInstance.methods + .getColInfo(reflexerSafes.types) + .call(); + + return reflexerSafes.allSafes.map( + ({ type, token, key: tokenKey, disabled, safeTokenType }, i) => { + const [rate, price, ratioCbyD, debtCeiling, totalDebt] = rawData[i]; + + return { + type, + token, + tokenKey, + disabled, + safeTokenType, + rate: calRate(rate), + price: new BigNumber(price).dividedBy(1e27).toFixed(), + liquidation: new BigNumber(1) + .dividedBy(new BigNumber(ratioCbyD).dividedBy(1e27)) + .toFixed(), + debtCeiling: debtCeiling, + totalDebt: new BigNumber(totalDebt) + .dividedBy(1e18) + .multipliedBy(1.00002) + .toFixed() + }; + } + ); + } catch (error) { + console.error(error); + return []; + } +} +async function getSafes(user, web3) { + try { + const reflexerResolveABI = abis.resolver.reflexer; + const reflexerResolveAddr = addresses.mainnet.resolver.reflexer; + + const reflexerResolverInstance = new web3.eth.Contract( + reflexerResolveABI as AbiItem[], + reflexerResolveAddr + ); + + const rawData: any[] = await reflexerResolverInstance.methods + .getSafes(user) + .call(); + + return rawData.map( + ([ + id, + owner, + type, + collInWei, + , + debtInWei, + liquidatedColInWei, + ratePerBlock, + priceInWei, + liquidationRatioCbyD, + urn + ]) => { + const collateral = new BigNumber(collInWei).dividedBy(1e18); + const debt = new BigNumber(debtInWei).dividedBy(1e18); + const price = new BigNumber(priceInWei).dividedBy(1e27); + + const safe = reflexerSafes.getSafeByType(type); + + return { + id, + owner, + type, + tokenKey: safe.key, + token: safe.token, + safeTokenType: safe.safeTokenType, + collateral: collateral.toFixed(), + debt: debt.toFixed(), + liquidatedCollateral: new BigNumber(liquidatedColInWei) + .dividedBy(1e18) + .toFixed(), + rate: calRate(ratePerBlock), + price: price.toFixed(), + liquidation: new BigNumber(1) + .dividedBy(new BigNumber(liquidationRatioCbyD).dividedBy(1e27)) + .toFixed(), + urn, + netValue: collateral + .multipliedBy(price) + .minus(debt) + .toFixed(), + status: collateral.isZero() + ? "0" + : debt.dividedBy(collateral.multipliedBy(price)).toFixed() + }; + } + ); + } catch (error) { + console.error(error); + return []; + } +} + +function calRate(ilkRate) { + try { + return new BigNumber(ilkRate) + .dividedBy(1e27) + .pow(31545000) + .minus(1) + .toFixed(18); + } catch (error) { + console.log("error", error); + } +} diff --git a/composables/useSidebar.ts b/composables/useSidebar.ts index a8ee8c2..4e53041 100644 --- a/composables/useSidebar.ts +++ b/composables/useSidebar.ts @@ -35,6 +35,12 @@ import SidebarLiquityTroveWithdraw from '~/components/sidebar/context/liquity/Si import SidebarLiquityTroveBorrow from '~/components/sidebar/context/liquity/SidebarLiquityTroveBorrow.vue' import SidebarLiquityTrovePayback from '~/components/sidebar/context/liquity/SidebarLiquityTrovePayback.vue' +import SidebarReflexerCollateral from '~/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue' +import SidebarReflexerSupply from '~/components/sidebar/context/reflexer/SidebarReflexerSupply.vue' +import SidebarReflexerWithdraw from '~/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue' +import SidebarReflexerBorrow from '~/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue' +import SidebarReflexerPayback from '~/components/sidebar/context/reflexer/SidebarReflexerPayback.vue' + const sidebars = { "#overview" : {component: SidebarOverview, back : false, close : true }, @@ -64,6 +70,13 @@ const sidebars = { '/mainnet/liquity#trove-withdraw': { component: SidebarLiquityTroveWithdraw }, '/mainnet/liquity#trove-borrow': { component: SidebarLiquityTroveBorrow }, '/mainnet/liquity#trove-payback': { component: SidebarLiquityTrovePayback }, + + "/mainnet/reflexer": { component: null }, + '/mainnet/reflexer#collateral': { component: SidebarReflexerCollateral }, + "/mainnet/reflexer#supply": { component: SidebarReflexerSupply }, + "/mainnet/reflexer#withdraw": { component: SidebarReflexerWithdraw }, + "/mainnet/reflexer#borrow": { component: SidebarReflexerBorrow }, + "/mainnet/reflexer#payback": { component: SidebarReflexerPayback }, }; const sidebar = ref(null); diff --git a/composables/useValidators.ts b/composables/useValidators.ts index bd54ee2..7ef68d6 100644 --- a/composables/useValidators.ts +++ b/composables/useValidators.ts @@ -2,17 +2,19 @@ import { useBigNumber } from "./useBigNumber"; import { useFormatting } from "./useFormatting"; import { useMakerdaoPosition } from "~/composables/protocols/useMakerdaoPosition"; import { useLiquityPosition } from "./protocols/useLiquityPosition"; +import { useReflexerPosition } from "./protocols/useReflexerPosition"; export function useValidators() { const { formatNumber } = useFormatting(); const { isZero, minus, eq, gt, lt, gte, plus } = useBigNumber(); const { minDebt: makerMinDebt, vaultTypes } = useMakerdaoPosition(); + const { minDebt: reflexerMinDebt, safeTypes } = useReflexerPosition(); const { minDebt: liquityMinDebt, liquidationReserve: liquityLiquidationReserve, troveOpened: liquityTroveOpened } = useLiquityPosition(); - + function validateAmount(amountParsed, balance = null, options = null) { const mergedOptions = Object.assign( { msg: "Your amount exceeds your maximum limit." }, @@ -96,6 +98,36 @@ export function useValidators() { return null; } + function validateReflexerDebtCeiling(safeType, debtParsed = 0) { + const safe = safeTypes.value.find(v => v.type === safeType); + const { debtCeiling, totalDebt } = safe || {}; + + if (!isZero(debtCeiling) && !isZero(totalDebt)) { + const total = plus(totalDebt, debtParsed); + return gte(total, debtCeiling) + ? `${safeType} Collateral reached debt ceiling` + : null; + } + return null; + } + + function validateReflexerDebt( + debtParsed, + minDebt = reflexerMinDebt.value, + vaultId + ) { + if (lt(debtParsed, minDebt) && gt(debtParsed, "0")) { + const vaultText = vaultId + ? vaultId !== "0" + ? `on vault #${vaultId}` + : `on new vault` + : ""; + return `Minimum debt requirement is ${minDebt} DAI ${vaultText}`; + } + + return null; + } + function validateLiquityDebt( debtParsed, minDebt = liquityMinDebt.value, @@ -129,6 +161,8 @@ export function useValidators() { validateMakerDebt, validateMakerDebtCeiling, validateLiquityDebt, - validateLiquityTroveExists + validateLiquityTroveExists, + validateReflexerDebtCeiling, + validateReflexerDebt, }; } diff --git a/constant/abi/read/reflexer.json b/constant/abi/read/reflexer.json new file mode 100644 index 0000000..26891be --- /dev/null +++ b/constant/abi/read/reflexer.json @@ -0,0 +1,271 @@ +[ + { + "inputs": [ + { + "internalType": "string[]", + "name": "name", + "type": "string[]" + } + ], + "name": "getColInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debtCeiling", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debtFloor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDebt", + "type": "uint256" + } + ], + "internalType": "struct Helpers.ColInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRedemptionRate", + "outputs": [ + { + "internalType": "uint256", + "name": "redemptionRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReflexerAddresses", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + }, + { + "internalType": "address", + "name": "safeEngine", + "type": "address" + }, + { + "internalType": "address", + "name": "taxCollector", + "type": "address" + }, + { + "internalType": "address", + "name": "oracleRelayer", + "type": "address" + }, + { + "internalType": "address", + "name": "getSafes", + "type": "address" + } + ], + "internalType": "struct Helpers.ReflexerAddresses", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "getSafeById", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "string", + "name": "colType", + "type": "string" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "adjustedDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidatedCol", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "colPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationRatio", + "type": "uint256" + }, + { + "internalType": "address", + "name": "safeAddress", + "type": "address" + } + ], + "internalType": "struct Helpers.SafeData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "getSafes", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "string", + "name": "colType", + "type": "string" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "adjustedDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidatedCol", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "colPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationRatio", + "type": "uint256" + }, + { + "internalType": "address", + "name": "safeAddress", + "type": "address" + } + ], + "internalType": "struct Helpers.SafeData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/constant/abis.ts b/constant/abis.ts index f978da4..974c464 100644 --- a/constant/abis.ts +++ b/constant/abis.ts @@ -7,7 +7,7 @@ import makerABI from "./abi/read/maker.json"; import makerProxyRegistryABI from "./abi/makerProxyRegistry.json"; import unipoolABI from "./abi/read/unipool.json"; import liquityABI from "./abi/read/liquity.json"; - +import reflexerABI from './abi/read/reflexer.json' const abis = { makerProxyRegistry: makerProxyRegistryABI, resolver: { @@ -19,6 +19,7 @@ const abis = { maker: makerABI, unipool: unipoolABI, liquity: liquityABI, + reflexer: reflexerABI } }; diff --git a/constant/addresses.ts b/constant/addresses.ts index ffd8594..a1b4ac0 100644 --- a/constant/addresses.ts +++ b/constant/addresses.ts @@ -9,25 +9,26 @@ const addresses = { compound: "0xcCAa4b1b3931749b8b6EF19C6b0B2c496703321b", maker: "0x84addce4fac0b6ee4b0cd132120d6d4b700e35c0", unipool: "0x22bddA39D14eD0aafeee36B6e784602fdDE64723", - liquity: '0xDAf2A39503463B0F41f899EDD82213b3c96b6Cf8', - }, + liquity: "0xDAf2A39503463B0F41f899EDD82213b3c96b6Cf8", + reflexer: "0x016ca8d0993d1a7073b01802a2e22fd0df7e633a" + } }, polygon: { core: { instaIndex: "0xA9B99766E6C676Cf1975c0D3166F96C0848fF5ad", - instaConnectorsV2: "0x2A00684bFAb9717C21271E0751BCcb7d2D763c88", + instaConnectorsV2: "0x2A00684bFAb9717C21271E0751BCcb7d2D763c88" }, resolver: { aave_v2: "0xD6E0803d0eB34af8Ea135835512D7E77960b28F1", accounts: "0xdF19Da523DA64bBE82eE0E4DFf00d676A8386474", balance: "0x04F8a41be023f839E709eeEaA0725FD766139A4d", merkleResolver: { - aave_v2: "0x2a26228e607ffD2aB2bD3aA49cBae0eDC6469Bf8", + aave_v2: "0x2a26228e607ffD2aB2bD3aA49cBae0eDC6469Bf8" }, - weth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - }, - }, + weth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + } + } }; export default addresses; diff --git a/constant/tokens/safes.ts b/constant/tokens/safes.ts new file mode 100644 index 0000000..f69c115 --- /dev/null +++ b/constant/tokens/safes.ts @@ -0,0 +1,10 @@ +// prettier-ignore +const safes = [ + { type: 'ETH-A', token: 'ETH', key: 'eth', ratio: 0.6666666666666666, joinAddr: '0x2D3cD7b81c93f188F3CB8aD87c8Acc73d6226e3A', addr: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', stabiltyRate: 0, price: 0, typeBytes: '0x4554482d41000000000000000000000000000000000000000000000000000000', disabled: false, safeTokenType: 'token' }, + ] + +export default { + allSafes: safes, + types: safes.map(safe => safe.type), + getSafeByType: type => safes.find(safe => safe.type === type) +}; diff --git a/pages/index.vue b/pages/index.vue index a9d0b0f..517caf6 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -37,6 +37,7 @@ import CompoundIcon from "~/assets/icons/compound.svg?inline"; import MakerIcon from "~/assets/icons/makerdao.svg?inline"; import OneInchIcon from "~/assets/icons/1inch.svg?inline"; import LiquityIcon from "~/assets/icons/liquity.svg?inline"; +import ReflexerIcon from "~/assets/icons/reflexer.svg?inline"; const appsPerNetwork = { mainnet: [ @@ -68,12 +69,19 @@ const appsPerNetwork = { url: "/1inch", description: "DEX Aggregator" }, - { + { id: "liquity", icon: LiquityIcon, name: "Liquity", url: "/mainnet/liquity", description: "Collateralized Debt" + }, + { + id: "reflexer", + icon: ReflexerIcon, + name: "Reflexer Finance", + url: "/mainnet/reflexer", + description: "Collateralized Debt" } ], polygon: [ diff --git a/pages/mainnet/reflexer.vue b/pages/mainnet/reflexer.vue new file mode 100644 index 0000000..a6abfbc --- /dev/null +++ b/pages/mainnet/reflexer.vue @@ -0,0 +1,283 @@ + + + From c6c82ec0dc4f26c32223749703eb166e6140ad2a Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Sat, 28 Aug 2021 00:27:11 +0300 Subject: [PATCH 02/21] fixes --- assets/icons/currencies/rai.svg | 4 ++-- assets/img/icons/currencies/rai.svg | 4 ++-- .../context/reflexer/SidebarReflexerBorrow.vue | 12 ++++++------ .../context/reflexer/SidebarReflexerCollateral.vue | 4 ++-- .../context/reflexer/SidebarReflexerPayback.vue | 12 ++++++------ pages/mainnet/reflexer.vue | 6 +++--- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/assets/icons/currencies/rai.svg b/assets/icons/currencies/rai.svg index 16e95ce..d399f42 100644 --- a/assets/icons/currencies/rai.svg +++ b/assets/icons/currencies/rai.svg @@ -1,5 +1,5 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/assets/img/icons/currencies/rai.svg b/assets/img/icons/currencies/rai.svg index 16e95ce..d399f42 100644 --- a/assets/img/icons/currencies/rai.svg +++ b/assets/img/icons/currencies/rai.svg @@ -1,5 +1,5 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue b/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue index 89ad92b..1b727f5 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue @@ -4,7 +4,7 @@ @@ -109,10 +109,10 @@ export default defineComponent({ const changedDebt = computed(() => plus(debt.value, amountParsed.value).toFixed()) const { liquidationPrice, status } = useReflexerPosition(collateral, changedDebt) - const daiTokenKey = ref('dai') - const daiToken = computed(() => getTokenByKey(daiTokenKey.value)) - const symbol = computed(() => daiToken.value?.symbol) - const decimals = computed(() => daiToken.value?.decimals) + const raiTokenKey = ref('rai') + const raiToken = computed(() => getTokenByKey(raiTokenKey.value)) + const symbol = computed(() => raiToken.value?.symbol) + const decimals = computed(() => raiToken.value?.decimals) const { validateAmount, @@ -173,7 +173,7 @@ export default defineComponent({ } return { - daiTokenKey, + raiTokenKey, symbol, debt, amount, diff --git a/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue b/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue index 54b69d0..62e05b7 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerCollateral.vue @@ -54,11 +54,11 @@ export default defineComponent({ const { store, app, route } = useContext() const { formatPercent } = useFormatting() const { back } = useSidebar() - const { safeTypes: makerSafeTypes, safeType, isNewSafe } = useReflexerPosition() + const { safeTypes: reflexerSafeTypes, safeType, isNewSafe } = useReflexerPosition() const safeTypes = computed(() => { const shouldFilter = !!props.safeType && (props.safeType === 'token' || props.safeType === 'uniLPT') - const filtered = makerSafeTypes.value.filter((safe) => !safe.disabled) + const filtered = reflexerSafeTypes.value.filter((safe) => !safe.disabled) const final = shouldFilter ? filtered.filter((safe) => safe.safeTokenType === props.safeType) : filtered if (route.value.hash.startsWith('#collateral')) return final return filtered.filter((safe) => safe.safeTokenType === 'token') diff --git a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue index 3b56008..4a22cd6 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue @@ -5,14 +5,14 @@
@@ -121,7 +121,7 @@ export default defineComponent({ const amount = ref('') const amountParsed = computed(() => parseSafeFloat(amount.value)) - const daiTokenKey = ref('dai') + const raiTokenKey = ref('rai') const tokenKey = computed(() => props.tokenKey) const token = computed(() => getTokenByKey(tokenKey.value)) const symbol = computed(() => token.value?.symbol) @@ -136,7 +136,7 @@ export default defineComponent({ const maxBalance = computed(() => min(balance.value, debt.value).toFixed()) const { toggle, isMaxAmount } = useMaxAmountActive(amount, maxBalance) - const { validateAmount, validateLiquidation, validateIsLoggedIn, validateMakerDebt } = useValidators() + const { validateAmount, validateLiquidation, validateIsLoggedIn, validateReflexerDebt } = useValidators() const errors = computed(() => { const hasAmountValue = !isZero(amount.value) @@ -145,7 +145,7 @@ export default defineComponent({ amount: { message: validateAmount(amountParsed.value, maxBalance.value), show: hasAmountValue }, liquidation: { message: validateLiquidation(status.value, liquidation.value), show: hasAmountValue }, auth: { message: validateIsLoggedIn(!!account.value), show: true }, - minDebt: { message: validateMakerDebt(changedDebt.value), show: hasAmountValue }, + minDebt: { message: validateReflexerDebt(changedDebt.value), show: hasAmountValue }, } }) const { errorMessages, isValid } = useValidation(errors) @@ -193,7 +193,7 @@ export default defineComponent({ } return { - daiTokenKey, + raiTokenKey, symbol, debt, balance, diff --git a/pages/mainnet/reflexer.vue b/pages/mainnet/reflexer.vue index a6abfbc..c292723 100644 --- a/pages/mainnet/reflexer.vue +++ b/pages/mainnet/reflexer.vue @@ -137,7 +137,7 @@ :amount="debt" :amount-usd="debt" position-type="borrow" - token-key="dai" + token-key="rai" :safe-token-type="safeTokenType" :supply-or-borrow="showBorrow" :withdraw-or-payback="showPayback" @@ -239,7 +239,7 @@ export default defineComponent({ if (isZero(collateral.value)) { showWarning("ReflexerDAO", "No collateral supplied!!"); } else { - router.push({ hash: "payback?tokenKey=dai" }); + router.push({ hash: "payback?tokenKey=rai" }); } } @@ -247,7 +247,7 @@ export default defineComponent({ if (isZero(collateral.value)) { showWarning("ReflexerDAO", "Deposit collateral before borrowing!!"); } else { - router.push({ hash: "borrow?tokenKey=dai" }); + router.push({ hash: "borrow?tokenKey=rai" }); } } From 29666d70dc9d0e377db1af594ecfcda50bdf6afd Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Sat, 28 Aug 2021 00:42:39 +0300 Subject: [PATCH 03/21] Update SidebarReflexerPayback.vue --- components/sidebar/context/reflexer/SidebarReflexerPayback.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue index 4a22cd6..b8b168c 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue @@ -156,7 +156,7 @@ export default defineComponent({ pending.value = true const amount = isMaxAmount.value - ? gte(balance.value, balance.value) + ? gte(balance.value, debt.value) ? dsa.value.maxValue : balanceRaw.value : valInt(amountParsed.value, decimals.value) From 887c7b61db2a35abf62088ba8c27adfaa9645aad Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Sat, 28 Aug 2021 00:49:11 +0300 Subject: [PATCH 04/21] fix --- composables/protocols/useReflexerPosition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index 6c26b72..d564e21 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -129,7 +129,7 @@ export function useReflexerPosition( return; } safes.value = await getSafes(activeAccount.value.address, web3.value); - if (safes.value.length > 0) { + if (safes.value.length > 0 && !safeId.value) { safeId.value = safes.value[0].id; } }; From c5b19fe4f6374c468fb8d5d93a60f78a1a795117 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Sun, 29 Aug 2021 23:46:12 +0300 Subject: [PATCH 05/21] fix min debt message --- composables/useValidators.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composables/useValidators.ts b/composables/useValidators.ts index 7ef68d6..2de9cf5 100644 --- a/composables/useValidators.ts +++ b/composables/useValidators.ts @@ -122,7 +122,7 @@ export function useValidators() { ? `on vault #${vaultId}` : `on new vault` : ""; - return `Minimum debt requirement is ${minDebt} DAI ${vaultText}`; + return `Minimum debt requirement is ${minDebt} RAI ${vaultText}`; } return null; From 4f2ea1cb685f95a67689e978c2db0fc6039d61e4 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Mon, 30 Aug 2021 00:03:34 +0300 Subject: [PATCH 06/21] fixes --- components/sidebar/context/makerdao/SidebarMakerdaoSupply.vue | 4 +++- components/sidebar/context/reflexer/SidebarReflexerSupply.vue | 4 ++-- composables/protocols/useReflexerPosition.ts | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/components/sidebar/context/makerdao/SidebarMakerdaoSupply.vue b/components/sidebar/context/makerdao/SidebarMakerdaoSupply.vue index 277eda0..8b2076c 100644 --- a/components/sidebar/context/makerdao/SidebarMakerdaoSupply.vue +++ b/components/sidebar/context/makerdao/SidebarMakerdaoSupply.vue @@ -104,7 +104,7 @@ export default defineComponent({ const amount = ref('') const amountParsed = computed(() => parseSafeFloat(amount.value)) - const { tokenKey, token, debt, collateral, liquidation, liquidationMaxPrice, isNewVault, vaultId, vaultType, fetchPosition} = useMakerdaoPosition() + const { tokenKey, token, debt, collateral, liquidation, liquidationMaxPrice, isNewVault, vaultId, vaultType, fetchPosition } = useMakerdaoPosition() const symbol = computed(() => token.value?.symbol) const decimals = computed(() => token.value?.decimals) @@ -163,6 +163,8 @@ export default defineComponent({ from: account.value, onReceipt: async receipt => { showConfirmedTransaction(receipt.transactionHash); + + isNewVault.value = false; await fetchBalances(true); await fetchPosition(); diff --git a/components/sidebar/context/reflexer/SidebarReflexerSupply.vue b/components/sidebar/context/reflexer/SidebarReflexerSupply.vue index 2190128..ac61ee3 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerSupply.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerSupply.vue @@ -104,7 +104,7 @@ export default defineComponent({ const amount = ref('') const amountParsed = computed(() => parseSafeFloat(amount.value)) - const { tokenKey, token, debt, collateral, liquidation, liquidationMaxPrice, isNewSafe, safeId, safeType, fetchPosition} = useReflexerPosition() + const { tokenKey, token, debt, collateral, liquidation, liquidationMaxPrice, isNewSafe, safeId, safeType, fetchPosition } = useReflexerPosition() const symbol = computed(() => token.value?.symbol) const decimals = computed(() => token.value?.decimals) @@ -163,7 +163,7 @@ export default defineComponent({ from: account.value, onReceipt: async receipt => { showConfirmedTransaction(receipt.transactionHash); - + isNewSafe.value = false await fetchBalances(true); await fetchPosition(); } diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index d564e21..61479e5 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -110,7 +110,7 @@ export function useReflexerPosition( const debt = computed(() => ensureValue(safe.value.debt).toFixed()); const minDebt = computed( - () => safeTypes.value[0]?.totalFloor?.toString() || "5000" + () => safeTypes.value[0]?.totalFloor?.toString() || "699" ); const debtCeilingReached = computed(() => safeTypes.value?.some(v => From c35ef575614e30128f46a51ae15b79211f95dc5f Mon Sep 17 00:00:00 2001 From: mstfash Date: Tue, 31 Aug 2021 17:23:00 +0200 Subject: [PATCH 07/21] fix liquidation price --- composables/protocols/useReflexerPosition.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index 61479e5..59e2c10 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -25,6 +25,8 @@ const defaultSafe = { netvalue: "0" }; +const oracleRelayerAddress = "0x4ed9C0dCa0479bC64d8f4EB3007126D5791f7851"; + const safeId = ref(null); const safes = ref([]); const isNewSafe = ref(false); @@ -202,6 +204,10 @@ async function getSafeTypes(web3) { .getColInfo(reflexerSafes.types) .call(); + const rawRedemptionPrice = await web3.eth.getStorageAt( + oracleRelayerAddress, + 4 + ); return reflexerSafes.allSafes.map( ({ type, token, key: tokenKey, disabled, safeTokenType }, i) => { const [rate, price, ratioCbyD, debtCeiling, totalDebt] = rawData[i]; @@ -213,7 +219,13 @@ async function getSafeTypes(web3) { disabled, safeTokenType, rate: calRate(rate), - price: new BigNumber(price).dividedBy(1e27).toFixed(), + redemptionPrice: new BigNumber(rawRedemptionPrice) + .dividedBy(1e27) + .toFixed(), + price: new BigNumber(price) + .times(rawRedemptionPrice) + .dividedBy(1e54) + .toFixed(), liquidation: new BigNumber(1) .dividedBy(new BigNumber(ratioCbyD).dividedBy(1e27)) .toFixed(), From 7801ec17512d6ea7a186e73d2e0a964ee0786a3e Mon Sep 17 00:00:00 2001 From: mstfash Date: Tue, 31 Aug 2021 19:25:22 +0200 Subject: [PATCH 08/21] adding a fix for safe liquidation price --- composables/protocols/useReflexerPosition.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index 59e2c10..37e824c 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -256,6 +256,10 @@ async function getSafes(user, web3) { .getSafes(user) .call(); + const rawRedemptionPrice = await web3.eth.getStorageAt( + oracleRelayerAddress, + 4 + ); return rawData.map( ([ id, @@ -272,7 +276,9 @@ async function getSafes(user, web3) { ]) => { const collateral = new BigNumber(collInWei).dividedBy(1e18); const debt = new BigNumber(debtInWei).dividedBy(1e18); - const price = new BigNumber(priceInWei).dividedBy(1e27); + const price = new BigNumber(priceInWei) + .times(rawRedemptionPrice) + .dividedBy(1e54); const safe = reflexerSafes.getSafeByType(type); From 85ee2a0d480efefcb42f5993bea899b3b1a364b2 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Tue, 31 Aug 2021 22:33:24 +0300 Subject: [PATCH 09/21] make minDebt dynamic --- composables/protocols/useReflexerPosition.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index 37e824c..d2fa373 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -112,7 +112,7 @@ export function useReflexerPosition( const debt = computed(() => ensureValue(safe.value.debt).toFixed()); const minDebt = computed( - () => safeTypes.value[0]?.totalFloor?.toString() || "699" + () => safeTypes.value[0]?.totalDebt?.toString() || "699" ); const debtCeilingReached = computed(() => safeTypes.value?.some(v => @@ -231,7 +231,6 @@ async function getSafeTypes(web3) { .toFixed(), debtCeiling: debtCeiling, totalDebt: new BigNumber(totalDebt) - .dividedBy(1e18) .multipliedBy(1.00002) .toFixed() }; From 061f86c0f05b9c1ce2a1e1b73b581f73d42308db Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Wed, 1 Sep 2021 00:43:47 +0300 Subject: [PATCH 10/21] calculate status using spotPrice and fix liquidation price --- composables/protocols/useReflexerPosition.ts | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index d2fa373..44b46e1 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -58,13 +58,15 @@ export function useReflexerPosition( ) { const { web3, chainId, networkName } = useWeb3(); const { activeAccount } = useDSA(); - const { isZero, ensureValue, times, div, max, gt } = useBigNumber(); + const { isZero, ensureValue, times, div, max, gt, toBN } = useBigNumber(); const { getTokenByKey } = useToken(); const safeTokenType = computed(() => safe.value.safeTokenType); const price = computed(() => ensureValue(safe.value.price).toFixed()); + const spotPrice = computed(() => ensureValue(safe.value.spotPrice).toFixed()); + const collateralUsd = computed(() => times(collateral.value, price.value).toFixed() ); @@ -89,7 +91,7 @@ export function useReflexerPosition( ? "1.1" : div( debtAmountRef.value, - times(collateralAmountRef.value, price.value) + times(collateralAmountRef.value, spotPrice.value) ).toFixed(); }); @@ -99,12 +101,13 @@ export function useReflexerPosition( div(div(debt.value, collateral.value), liquidation.value), "0" ).toFixed(); + return isZero(collateralAmountRef.value) && !isZero(debtAmountRef.value) ? times(price.value, "1.1").toFixed() : max( div( div(debtAmountRef.value, collateralAmountRef.value), - liquidation.value + toBN(liquidation.value ).multipliedBy(spotPrice.value).dividedBy(price.value) ), "0" ).toFixed(); @@ -222,17 +225,13 @@ async function getSafeTypes(web3) { redemptionPrice: new BigNumber(rawRedemptionPrice) .dividedBy(1e27) .toFixed(), - price: new BigNumber(price) - .times(rawRedemptionPrice) - .dividedBy(1e54) - .toFixed(), + spotPrice: new BigNumber(price).dividedBy(1e27).toFixed(), + price: new BigNumber(price).times(rawRedemptionPrice).dividedBy(1e54).toFixed(), liquidation: new BigNumber(1) .dividedBy(new BigNumber(ratioCbyD).dividedBy(1e27)) .toFixed(), debtCeiling: debtCeiling, - totalDebt: new BigNumber(totalDebt) - .multipliedBy(1.00002) - .toFixed() + totalDebt: new BigNumber(totalDebt).multipliedBy(1.00002).toFixed() }; } ); @@ -275,6 +274,7 @@ async function getSafes(user, web3) { ]) => { const collateral = new BigNumber(collInWei).dividedBy(1e18); const debt = new BigNumber(debtInWei).dividedBy(1e18); + const spotPrice = new BigNumber(priceInWei).dividedBy(1e27); const price = new BigNumber(priceInWei) .times(rawRedemptionPrice) .dividedBy(1e54); @@ -295,6 +295,7 @@ async function getSafes(user, web3) { .toFixed(), rate: calRate(ratePerBlock), price: price.toFixed(), + spotPrice, liquidation: new BigNumber(1) .dividedBy(new BigNumber(liquidationRatioCbyD).dividedBy(1e27)) .toFixed(), @@ -305,7 +306,7 @@ async function getSafes(user, web3) { .toFixed(), status: collateral.isZero() ? "0" - : debt.dividedBy(collateral.multipliedBy(price)).toFixed() + : debt.dividedBy(collateral.multipliedBy(spotPrice)).toFixed() }; } ); From baf65d6fda96a2d00a5cdd7e11f6c5169f8b2656 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Wed, 1 Sep 2021 00:58:50 +0300 Subject: [PATCH 11/21] add rai price --- composables/protocols/useReflexerPosition.ts | 18 +++++++++++++++--- pages/mainnet/reflexer.vue | 8 +++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index 44b46e1..fce5e2d 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -9,6 +9,7 @@ import { useDSA } from "~/composables/useDSA"; import { useToken } from "~/composables/useToken"; import { useWeb3 } from "~/composables/useWeb3"; import { AbiItem } from "web3-utils"; +import { useBalances } from "../useBalances"; const defaultSafe = { id: null, @@ -60,13 +61,18 @@ export function useReflexerPosition( const { activeAccount } = useDSA(); const { isZero, ensureValue, times, div, max, gt, toBN } = useBigNumber(); const { getTokenByKey } = useToken(); + const { prices } = useBalances(); + + const raiToken = computed(() => getTokenByKey("rai")); + const raiInUsd = computed(() => + raiToken.value ? prices.mainnet[raiToken.value.address] || "0" : "0" + ); const safeTokenType = computed(() => safe.value.safeTokenType); const price = computed(() => ensureValue(safe.value.price).toFixed()); const spotPrice = computed(() => ensureValue(safe.value.spotPrice).toFixed()); - const collateralUsd = computed(() => times(collateral.value, price.value).toFixed() ); @@ -107,7 +113,9 @@ export function useReflexerPosition( : max( div( div(debtAmountRef.value, collateralAmountRef.value), - toBN(liquidation.value ).multipliedBy(spotPrice.value).dividedBy(price.value) + toBN(liquidation.value) + .multipliedBy(spotPrice.value) + .dividedBy(price.value) ), "0" ).toFixed(); @@ -178,6 +186,7 @@ export function useReflexerPosition( collateralUsd, collateral, price, + raiInUsd, liquidation, tokenKey, token, @@ -226,7 +235,10 @@ async function getSafeTypes(web3) { .dividedBy(1e27) .toFixed(), spotPrice: new BigNumber(price).dividedBy(1e27).toFixed(), - price: new BigNumber(price).times(rawRedemptionPrice).dividedBy(1e54).toFixed(), + price: new BigNumber(price) + .times(rawRedemptionPrice) + .dividedBy(1e54) + .toFixed(), liquidation: new BigNumber(1) .dividedBy(new BigNumber(ratioCbyD).dividedBy(1e27)) .toFixed(), diff --git a/pages/mainnet/reflexer.vue b/pages/mainnet/reflexer.vue index c292723..eb3d18f 100644 --- a/pages/mainnet/reflexer.vue +++ b/pages/mainnet/reflexer.vue @@ -141,7 +141,7 @@ :safe-token-type="safeTokenType" :supply-or-borrow="showBorrow" :withdraw-or-payback="showPayback" - price-in-usd="1" + :price-in-usd="raiInUsd" />
@@ -207,7 +207,8 @@ export default defineComponent({ liquidationMaxPrice, debt, minDebt, - debtCeilingReached + debtCeilingReached, + raiInUsd, } = useReflexerPosition(); const statusLiquidationRatio = computed(() => @@ -276,7 +277,8 @@ export default defineComponent({ showSupply, debt, minDebt, - debtCeilingReached + debtCeilingReached, + raiInUsd, }; } }); From 41803ddffe33e2c4d9c19502439f5d767313aad8 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Mon, 6 Sep 2021 19:59:42 +0300 Subject: [PATCH 12/21] fixes --- components/sidebar/context/reflexer/SidebarReflexerBorrow.vue | 4 ++-- .../sidebar/context/reflexer/SidebarReflexerPayback.vue | 4 ++-- components/sidebar/context/reflexer/SidebarReflexerSupply.vue | 2 +- .../sidebar/context/reflexer/SidebarReflexerWithdraw.vue | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue b/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue index 1b727f5..9cf4ca2 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerBorrow.vue @@ -69,7 +69,7 @@ import { useValidation } from '~/composables/useValidation' import { useToken } from '~/composables/useToken' import { useParsing } from '~/composables/useParsing' import { useMaxAmountActive } from '~/composables/useMaxAmountActive' -import { useWeb3 } from '~/composables/useWeb3' +import { useWeb3 } from '@instadapp/vue-web3' import ToggleButton from '~/components/common/input/ToggleButton.vue' import { useDSA } from '~/composables/useDSA' import ButtonCTA from '~/components/common/input/ButtonCTA.vue' @@ -87,7 +87,7 @@ export default defineComponent({ }, setup(props) { const { close } = useSidebar() - const { networkName, account } = useWeb3() + const { account } = useWeb3() const { dsa } = useDSA() const { getTokenByKey, valInt } = useToken() const { fetchBalances } = useBalances() diff --git a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue index b8b168c..6387d99 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue @@ -91,7 +91,7 @@ import { useValidation } from '~/composables/useValidation' import { useToken } from '~/composables/useToken' import { useParsing } from '~/composables/useParsing' import { useMaxAmountActive } from '~/composables/useMaxAmountActive' -import { useWeb3 } from '~/composables/useWeb3' +import { useWeb3 } from '@instadapp/vue-web3' import ToggleButton from '~/components/common/input/ToggleButton.vue' import { useDSA } from '~/composables/useDSA' import ButtonCTA from '~/components/common/input/ButtonCTA.vue' @@ -107,7 +107,7 @@ export default defineComponent({ }, setup(props) { const { close } = useSidebar() - const { networkName, account } = useWeb3() + const { account } = useWeb3() const { dsa } = useDSA() const { getTokenByKey, valInt } = useToken() const { getBalanceByKey, getBalanceRawByKey, fetchBalances } = useBalances() diff --git a/components/sidebar/context/reflexer/SidebarReflexerSupply.vue b/components/sidebar/context/reflexer/SidebarReflexerSupply.vue index ac61ee3..cacffe8 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerSupply.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerSupply.vue @@ -79,7 +79,7 @@ import { useValidation } from '~/composables/useValidation' import { useToken } from '~/composables/useToken' import { useParsing } from '~/composables/useParsing' import { useMaxAmountActive } from '~/composables/useMaxAmountActive' -import { useWeb3 } from '~/composables/useWeb3' +import { useWeb3 } from '@instadapp/vue-web3' import ToggleButton from '~/components/common/input/ToggleButton.vue' import { useDSA } from '~/composables/useDSA' import ButtonCTA from '~/components/common/input/ButtonCTA.vue' diff --git a/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue b/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue index 8e38c7a..9bc827a 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerWithdraw.vue @@ -77,7 +77,7 @@ import { useValidation } from '~/composables/useValidation' import { useToken } from '~/composables/useToken' import { useParsing } from '~/composables/useParsing' import { useMaxAmountActive } from '~/composables/useMaxAmountActive' -import { useWeb3 } from '~/composables/useWeb3' +import { useWeb3 } from '@instadapp/vue-web3' import ToggleButton from '~/components/common/input/ToggleButton.vue' import { useDSA } from '~/composables/useDSA' import ButtonCTA from '~/components/common/input/ButtonCTA.vue' From 4430b40dbdfccddc4ea9c8d4a9d04360676ace14 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Mon, 6 Sep 2021 20:04:21 +0300 Subject: [PATCH 13/21] fixes --- composables/protocols/useReflexerPosition.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index fce5e2d..11007b9 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -7,7 +7,7 @@ import reflexerSafes from "~/constant/tokens/safes"; import { useBigNumber } from "~/composables/useBigNumber"; import { useDSA } from "~/composables/useDSA"; import { useToken } from "~/composables/useToken"; -import { useWeb3 } from "~/composables/useWeb3"; +import { useWeb3 } from "@instadapp/vue-web3"; import { AbiItem } from "web3-utils"; import { useBalances } from "../useBalances"; @@ -57,7 +57,7 @@ export function useReflexerPosition( collateralAmountRef: Ref = null, debtAmountRef: Ref = null ) { - const { web3, chainId, networkName } = useWeb3(); + const { library } = useWeb3(); const { activeAccount } = useDSA(); const { isZero, ensureValue, times, div, max, gt, toBN } = useBigNumber(); const { getTokenByKey } = useToken(); @@ -132,23 +132,23 @@ export function useReflexerPosition( ); const fetchPosition = async () => { - if (!web3.value) { + if (!library.value) { return; } - safeTypes.value = await getSafeTypes(web3.value); + safeTypes.value = await getSafeTypes(library.value); if (!activeAccount.value) { return; } - safes.value = await getSafes(activeAccount.value.address, web3.value); + safes.value = await getSafes(activeAccount.value.address, library.value); if (safes.value.length > 0 && !safeId.value) { safeId.value = safes.value[0].id; } }; watch( - web3, + library, async val => { if (val) { fetchPosition(); From cfd957648fab5e54964ada2336e769fa684d146f Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Tue, 7 Sep 2021 21:35:52 +0300 Subject: [PATCH 14/21] fix debt price in usd --- composables/protocols/useReflexerPosition.ts | 5 +++++ pages/mainnet/reflexer.vue | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/composables/protocols/useReflexerPosition.ts b/composables/protocols/useReflexerPosition.ts index 11007b9..d4124c0 100644 --- a/composables/protocols/useReflexerPosition.ts +++ b/composables/protocols/useReflexerPosition.ts @@ -122,6 +122,10 @@ export function useReflexerPosition( }); const debt = computed(() => ensureValue(safe.value.debt).toFixed()); + const debtUsd = computed(() => + times(debt.value, raiInUsd.value).toFixed() + ); + const minDebt = computed( () => safeTypes.value[0]?.totalDebt?.toString() || "699" ); @@ -197,6 +201,7 @@ export function useReflexerPosition( liquidationPrice, liquidationMaxPrice: price, debt, + debtUsd, minDebt, debtCeilingReached }; diff --git a/pages/mainnet/reflexer.vue b/pages/mainnet/reflexer.vue index eb3d18f..b19b0c7 100644 --- a/pages/mainnet/reflexer.vue +++ b/pages/mainnet/reflexer.vue @@ -135,7 +135,7 @@ Date: Tue, 7 Sep 2021 22:17:15 +0300 Subject: [PATCH 15/21] add message for min debt on payback --- .../reflexer/SidebarReflexerPayback.vue | 4 +-- composables/useValidators.ts | 26 +++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue index 6387d99..804b0b3 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue @@ -136,7 +136,7 @@ export default defineComponent({ const maxBalance = computed(() => min(balance.value, debt.value).toFixed()) const { toggle, isMaxAmount } = useMaxAmountActive(amount, maxBalance) - const { validateAmount, validateLiquidation, validateIsLoggedIn, validateReflexerDebt } = useValidators() + const { validateAmount, validateLiquidation, validateIsLoggedIn, validateReflexerPaybackDebt } = useValidators() const errors = computed(() => { const hasAmountValue = !isZero(amount.value) @@ -145,7 +145,7 @@ export default defineComponent({ amount: { message: validateAmount(amountParsed.value, maxBalance.value), show: hasAmountValue }, liquidation: { message: validateLiquidation(status.value, liquidation.value), show: hasAmountValue }, auth: { message: validateIsLoggedIn(!!account.value), show: true }, - minDebt: { message: validateReflexerDebt(changedDebt.value), show: hasAmountValue }, + minDebt: { message: validateReflexerPaybackDebt(changedDebt.value), show: hasAmountValue }, } }) const { errorMessages, isValid } = useValidation(errors) diff --git a/composables/useValidators.ts b/composables/useValidators.ts index 2de9cf5..e44e334 100644 --- a/composables/useValidators.ts +++ b/composables/useValidators.ts @@ -114,7 +114,7 @@ export function useValidators() { function validateReflexerDebt( debtParsed, minDebt = reflexerMinDebt.value, - vaultId + vaultId, ) { if (lt(debtParsed, minDebt) && gt(debtParsed, "0")) { const vaultText = vaultId @@ -122,7 +122,28 @@ export function useValidators() { ? `on vault #${vaultId}` : `on new vault` : ""; - return `Minimum debt requirement is ${minDebt} RAI ${vaultText}`; + + return `Minimum debt requirement is ${minDebt} RAI ${vaultText}` ; + } + + return null; + } + + function validateReflexerPaybackDebt( + debtParsed, + minDebt = reflexerMinDebt.value, + vaultId, + ) { + console.log(debtParsed, minDebt); + + if (lt(debtParsed, minDebt) && gt(debtParsed, "0")) { + const vaultText = vaultId + ? vaultId !== "0" + ? `on vault #${vaultId}` + : `on new vault` + : ""; + + return `Minimum debt requirement is ${minDebt} RAI ${vaultText} + accumulated interest, supply additional ${debtParsed} RAI` ; } return null; @@ -164,5 +185,6 @@ export function useValidators() { validateLiquityTroveExists, validateReflexerDebtCeiling, validateReflexerDebt, + validateReflexerPaybackDebt, }; } From 5804173cd6843c0a36bcc81c57fad4c91f5a2e12 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Tue, 7 Sep 2021 22:18:58 +0300 Subject: [PATCH 16/21] Update useValidators.ts --- composables/useValidators.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/composables/useValidators.ts b/composables/useValidators.ts index e44e334..a74d34d 100644 --- a/composables/useValidators.ts +++ b/composables/useValidators.ts @@ -134,7 +134,6 @@ export function useValidators() { minDebt = reflexerMinDebt.value, vaultId, ) { - console.log(debtParsed, minDebt); if (lt(debtParsed, minDebt) && gt(debtParsed, "0")) { const vaultText = vaultId From aa8a188d128b096c1a5cdf90f8c12af836d4bdae Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Mon, 13 Sep 2021 22:25:19 +0300 Subject: [PATCH 17/21] update payback msg --- composables/useValidators.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/composables/useValidators.ts b/composables/useValidators.ts index a74d34d..f1dcd6a 100644 --- a/composables/useValidators.ts +++ b/composables/useValidators.ts @@ -136,13 +136,7 @@ export function useValidators() { ) { if (lt(debtParsed, minDebt) && gt(debtParsed, "0")) { - const vaultText = vaultId - ? vaultId !== "0" - ? `on vault #${vaultId}` - : `on new vault` - : ""; - - return `Minimum debt requirement is ${minDebt} RAI ${vaultText} + accumulated interest, supply additional ${debtParsed} RAI` ; + return `Min debt requirement is ${minDebt} RAI. Payback additional ${debtParsed} RAI`; } return null; From 185052379a5da474b05df04989aed30efd7ce660 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Tue, 14 Sep 2021 00:59:09 +0530 Subject: [PATCH 18/21] Update useValidators.ts --- composables/useValidators.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composables/useValidators.ts b/composables/useValidators.ts index f1dcd6a..77ad963 100644 --- a/composables/useValidators.ts +++ b/composables/useValidators.ts @@ -136,7 +136,7 @@ export function useValidators() { ) { if (lt(debtParsed, minDebt) && gt(debtParsed, "0")) { - return `Min debt requirement is ${minDebt} RAI. Payback additional ${debtParsed} RAI`; + return `Minimum debt requirement is ${minDebt} RAI. Payback additional ${debtParsed} RAI`; } return null; From db880cd8b30d7b0f82b9edce93305a16d9cf88b6 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Thu, 16 Sep 2021 11:47:24 +0300 Subject: [PATCH 19/21] Update SidebarReflexerPayback.vue --- components/sidebar/context/reflexer/SidebarReflexerPayback.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue index 804b0b3..eaa6d63 100644 --- a/components/sidebar/context/reflexer/SidebarReflexerPayback.vue +++ b/components/sidebar/context/reflexer/SidebarReflexerPayback.vue @@ -133,7 +133,7 @@ export default defineComponent({ const changedDebt = computed(() => max(minus(debt.value, amountParsed.value), '0').toFixed()) const { liquidationPrice, status } = useReflexerPosition(collateral, changedDebt) - const maxBalance = computed(() => min(balance.value, debt.value).toFixed()) + const maxBalance = computed(() => min(balance.value, debt.value).toFixed(6)) const { toggle, isMaxAmount } = useMaxAmountActive(amount, maxBalance) const { validateAmount, validateLiquidation, validateIsLoggedIn, validateReflexerPaybackDebt } = useValidators() From 62333c5f51cd5ff2903536a47ca86ec34242e12b Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Thu, 16 Sep 2021 19:35:22 +0300 Subject: [PATCH 20/21] use first safe type when safe types has only 1 value --- pages/mainnet/reflexer.vue | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/pages/mainnet/reflexer.vue b/pages/mainnet/reflexer.vue index b19b0c7..e7cbb4d 100644 --- a/pages/mainnet/reflexer.vue +++ b/pages/mainnet/reflexer.vue @@ -175,7 +175,7 @@ export default defineComponent({ SVGArrowRight, SVGPercent, DropdownReflexer, - ReflexerIcon, + ReflexerIcon }, setup() { const router = useRouter(); @@ -210,6 +210,9 @@ export default defineComponent({ minDebt, debtCeilingReached, raiInUsd, + isNewSafe, + safeType, + safeTypes } = useReflexerPosition(); const statusLiquidationRatio = computed(() => @@ -222,7 +225,14 @@ export default defineComponent({ if (gt(debt.value, "0") && lt(debt.value, minDebt.value)) { // select("depositAndBorrow"); } else if (safes.value.length === 0) { - router.push({ hash: "collateral" }); + if (safeTypes.value.length === 0) { + } else if (safeTypes.value.length === 1) { + safeType.value = safeTypes.value[0].type; + isNewSafe.value = true; + router.push({ hash: "supply" }); + } else { + router.push({ hash: "collateral" }); + } } else { router.push({ hash: "supply" }); } @@ -280,7 +290,7 @@ export default defineComponent({ debtUsd, minDebt, debtCeilingReached, - raiInUsd, + raiInUsd }; } }); From 067071535108eefee37e58775b9f62d30be4cf89 Mon Sep 17 00:00:00 2001 From: Georges KABBOUCHI Date: Thu, 16 Sep 2021 21:10:11 +0300 Subject: [PATCH 21/21] Update DropdownReflexer.vue --- .../protocols/reflexer/DropdownReflexer.vue | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/components/protocols/reflexer/DropdownReflexer.vue b/components/protocols/reflexer/DropdownReflexer.vue index 1353587..5eebec0 100644 --- a/components/protocols/reflexer/DropdownReflexer.vue +++ b/components/protocols/reflexer/DropdownReflexer.vue @@ -23,7 +23,9 @@